`
dbjoy
  • 浏览: 9373 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

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[6];
        DriverPropertyInfo driverpropertyinfo = new DriverPropertyInfo("user", null);
        driverpropertyinfo.value = properties.getProperty("user");
        driverpropertyinfo.required = true;
        adriverpropertyinfo[0] = driverpropertyinfo;
        driverpropertyinfo = new DriverPropertyInfo("password", null);
        driverpropertyinfo.value = properties.getProperty("password");
        driverpropertyinfo.required = true;
        adriverpropertyinfo[1] = driverpropertyinfo;
        driverpropertyinfo = new DriverPropertyInfo("get_column_name", null);
        driverpropertyinfo.value = properties.getProperty("get_column_name", "true");
        driverpropertyinfo.required = false;
        driverpropertyinfo.choices = as;
        adriverpropertyinfo[2] = driverpropertyinfo;
        driverpropertyinfo = new DriverPropertyInfo("ifexists", null);
        driverpropertyinfo.value = properties.getProperty("ifexists");
        driverpropertyinfo.required = false;
        driverpropertyinfo.choices = as;
        adriverpropertyinfo[3] = driverpropertyinfo;
        driverpropertyinfo = new DriverPropertyInfo("default_schema", null);
        driverpropertyinfo.value = properties.getProperty("default_schema");
        driverpropertyinfo.required = false;
        driverpropertyinfo.choices = as;
        adriverpropertyinfo[4] = driverpropertyinfo;
        driverpropertyinfo = new DriverPropertyInfo("shutdown", null);
        driverpropertyinfo.value = properties.getProperty("shutdown");
        driverpropertyinfo.required = false;
        driverpropertyinfo.choices = as;
        adriverpropertyinfo[5] = 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
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics