JDBC驱动的加载和注册及statement、preparedStatement
一、JDBC驱动加载和注册Class.forName("org.hsqldb.jdbcDriver");
这行代码是用于加载一个JDBC驱动并注册这个已经加载的驱动,可是我们并没有看到加载和注册的代码片段,这行代码的背后隐藏着些什么呢?先来看看org.hsqldb.jdbcDriver这个类的java源代码:
public class jdbcDriver implements Driver{ public jdbcDriver() { } public Connection connect(String s, Properties properties) throws SQLException { return getConnection(s, properties); } public static Connection getConnection(String s, Properties properties) throws SQLException { HsqlProperties hsqlproperties = DatabaseURL.parseURL(s, true); if (hsqlproperties == null) throw new SQLException(Trace.getMessage(62)); if (hsqlproperties.isEmpty()) { return null; } else { hsqlproperties.addProperties(properties); return new jdbcConnection(hsqlproperties); } } public boolean acceptsURL(String s) { return s != null && s.regionMatches(true, 0, "jdbc:hsqldb:", 0, "jdbc:hsqldb:".length()); } public DriverPropertyInfo[] getPropertyInfo(String s, Properties properties) { String as[] = { "true", "false" }; DriverPropertyInfo adriverpropertyinfo[] = new DriverPropertyInfo; DriverPropertyInfo driverpropertyinfo = new DriverPropertyInfo("user", null); driverpropertyinfo.value = properties.getProperty("user"); driverpropertyinfo.required = true; adriverpropertyinfo = driverpropertyinfo; driverpropertyinfo = new DriverPropertyInfo("password", null); driverpropertyinfo.value = properties.getProperty("password"); driverpropertyinfo.required = true; adriverpropertyinfo = driverpropertyinfo; driverpropertyinfo = new DriverPropertyInfo("get_column_name", null); driverpropertyinfo.value = properties.getProperty("get_column_name", "true"); driverpropertyinfo.required = false; driverpropertyinfo.choices = as; adriverpropertyinfo = driverpropertyinfo; driverpropertyinfo = new DriverPropertyInfo("ifexists", null); driverpropertyinfo.value = properties.getProperty("ifexists"); driverpropertyinfo.required = false; driverpropertyinfo.choices = as; adriverpropertyinfo = driverpropertyinfo; driverpropertyinfo = new DriverPropertyInfo("default_schema", null); driverpropertyinfo.value = properties.getProperty("default_schema"); driverpropertyinfo.required = false; driverpropertyinfo.choices = as; adriverpropertyinfo = driverpropertyinfo; driverpropertyinfo = new DriverPropertyInfo("shutdown", null); driverpropertyinfo.value = properties.getProperty("shutdown"); driverpropertyinfo.required = false; driverpropertyinfo.choices = as; adriverpropertyinfo = driverpropertyinfo; return adriverpropertyinfo; } public int getMajorVersion() { return 1; } public int getMinorVersion() { return 8; } public boolean jdbcCompliant() { return false; } static { try { DriverManager.registerDriver(new jdbcDriver()); } catch (Exception exception) { } }}
注意到最后的代码片段是一个被static包含的静态语句块:
static { try { DriverManager.registerDriver(new jdbcDriver()); } catch (Exception exception) { } }
java的运行机制,静态语句块是在类的class文件首次被装载到JVM中时马上就要执行并且只执行一次的代码,所以当我们使用Class.forName("org.hsqldb.jdbcDriver");把的class文件装载到JVM时,这行代码背后就通过上面的静态语句块已经完成了JDBC驱动的加载实例化并使用DriverManager类注册这个驱动的操作了
二、statement、preparedStatement
Statement是用于向数据库发送SQL语句、执行SQL语句并返回结果。
当你需要多次使用一个Statement对象时,使用PreparedStatement对象更有效率。PreparedStatement对象和Statement对象不同的是,PreparedStatement对象在实例化创建时就被设置了一个SQL语句,使用PreparedStatement对象执行的SQL语句在首次发送到数据库时,SQL语句会被编译,所以PreparedStatement对象是一个包含了已经预编译SQL语句的对象,这样当多次执行同一个SQL语句时,就不用每次都去编译SQL语句,而是直接执行已经编译过的SQL语句。
经过代码测试:
Connection conn = JdbcUtil.getDefaultConnection(); Statement stmt = JdbcUtil.getDefaultConnection().createStatement(); int executeTime = 1000000; long start = System.currentTimeMillis(); for (int i = 0; i < executeTime; i++) { stmt.executeQuery("select * from coffees"); } long end = System.currentTimeMillis(); System.out.println(end - start); PreparedStatement preStmt = conn .prepareStatement("select * from coffees"); long preStart = System.currentTimeMillis(); for (int i = 0; i < executeTime; i++) { preStmt.executeQuery(); } long preEnd = System.currentTimeMillis(); System.out.println(preEnd - preStart); assertTrue((end - start) > (preEnd - preStart)); // 关闭jdbc相关对象 stmt.close(); preStmt.close(); conn.close();
使用Statement对象和PreparedStatement对象执行同一个SQL语句1000000次所消耗的时间分别为:
Statement:112406
PreparedStatement:85953
可以看出PrepareStatment执行SQL语句的效率确实会提高。所以在日常开发中,我们是优先使用preparedstatement的
页:
[1]