今天复习了下jdbc操作数据库,其实通过复习,感觉对类的熟悉和方法的运用都是小事,毕竟有API都可以查得到。
关键是一些设计,
1、 比如:
Class.forName("");这个是用来加载驱动,获取driver实例,并在加载的过程中注册到了DriverManager中,由后者去管理。
所以:在DriverManager.getConnection()时,发生的操作有:Drivermanager查找已经注册的列表,然后根据url去对应,最后通过driver获取数据库连接,假如有注册的重复的驱动,默认最先匹配的那个驱动为正确结果。在DriverManager中提供了关于一些driver的管理机制,包括重复的一些处理。
2、 PreparedStatement,Statement
两者的区别:前者相当于sql预编译,在程序执行的时候已经把sql编译好,尽管它可以动态传参,这也提高了执行效率。
前者还可以防止sql注入
如果基本数据库和驱动程序在语句提交之后仍保持这些语句的打开状态,则同一个 PreparedStatement 可执行多次。如果这一点不成立,那么试图通过使用 PreparedStatement对象代替 Statement 对象来提高性能是没有意义的。
示例:
1 pstmt.setString(1, "Hi"); 2 for (int i = 0; i < 10; i++) { 3 pstmt.setInt(2, i); 4 int rowCount = pstmt.executeUpdate(); 5 }
3、ResultSet提供了很好的结果集管理机制,主要实现了java.sql.ResultSet接口,
比如查看结果集有几行几列,查看结果集的列名,查看结果集最后一行是否为空等等。
4、关于一些长字段的输入和输出问题,见代码。
for(;;); mt = con.createStatement(); ResultSet r = stmt.executeQuery("SELECT x FROM Table2"); // 现在以 4K 块大小获取列 1 结果: byte buff = new byte[4096]; while (r.next()) { Java.io.InputStream fin = r.getAsciiStream(1); for (;;) { int size = fin.read(buff); if (size == -1) { // 到达流末尾 break; } // 将新填充的缓冲区发送到 ASCII 输出流: output.write(buff, 0, size); } }
java.io.File file = new java.io.File("/tmp/data"); int fileLength = file.length(); java.io.InputStream fin = new java.io.FileInputStream(file); java.sql.PreparedStatement pstmt = con.prepareStatement( "UPDATE Table5 SET stuff = ? WHERE index = 4"); pstmt.setBinaryStream (1, fin, fileLength); pstmt.executeUpdate();
数据库针对长字段提供了三种流机制:
getBinaryStream
getAsciiStream
getUnicodeStream
其中for(;;)是无限循环的意思..
关于为什么preparedStatement比statement,同一个sql假如执行N遍,preparedStatement只进行一次编译,而statement需要编译N次