彻底搞懂JDBC的运行过程( 二 )


这是Java核心库里反射机制的最佳实践之一,它使得应用程序和驱动程序之间进行了隔离,让迁移数据库的工作变得更简单 。
Statement和PreparedStatement区别

  • 关系:PreparedStatement继承自Statement,两者都是接口
  • 区别:PreparedStatement可以使用占位符,而且是预编译的,批处理比Statement效率高
预编译
创建时的区别:
Statement statement = conn.createStatement();PreparedStatement preStatement = conn.prepareStatement(sql);执行时的区别:
ResultSet rSet = statement.executeQuery(sql);ResultSet pSet = preStatement.executeQuery();由上可以看出,PreparedStatement有预编译的过程,已经绑定sql,之后无论执行多少次,都不会再去进行编译,而Statement 不同,如果执行多次,则相应的就要编译多少次sql,所以从这点看,PreparedStatement的效率会比Statement要高一些 。PreparedStatement是预编译的,所以可以有效的防止SQL注入等问题
占位符
PrepareStatement可以替换变量在SQL语句中可以包含?,可以用?替换成变量 。
ps = conn.prepareStatement("select * from Employees where id=?");int sid = 1001;ps.setInt(1, sid);rs = ps.executeQuery();而Statement只能用字符串拼接 。
int sid = 1001;Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("select * from Employees where id=" + sid);JDBC的ResultSet
在查询数据库后会返回一个ResultSet,它就像是查询结果集的一张数据表 。
ResultSet对象维护了一个游标,指向当前的数据行 。开始的时候这个游标指向的是第一行 。如果调用了ResultSet的next()方法游标会下移一行,如果没有更多的数据了,next()方法会返回false 。可以在for循环中用它来遍历数据集 。
默认的ResultSet是不能更新的,游标也只能往下移 。也就是说你只能从第一行到最后一行遍历一遍 。不过也可以创建可以回滚或者可更新的ResultSet,像下面这样 。
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);当生成ResultSet的Statement对象要关闭或者重新执行或是获取下一个ResultSet的时候,ResultSet对象也会自动关闭 。
可以通过ResultSet的getter方法,传入列名或者从1开始的序号来获取列数据 。
ResultSet的不同类型
根据创建Statement时输入参数的不同,会对应不同类型的ResultSet 。如果你看下Connection的方法,你会发现createStatement和prepareStatement方法重载了,以支持不同的ResultSet和并发类型 。
ResultSet对象有三种类型 。
  1. ResultSet.TYPE_FORWARD_ONLY:这是默认的类型,它的游标只能往下移 。
  2. ResultSet.TYPE_SCROLL_INSENSITIVE:游标可以上下移动,一旦它创建后,数据库里的数据再发生修改,对它来说是透明的 。
  3. ResultSet.TYPE_SCROLL_SENSITIVE:游标可以上下移动,如果生成后数据库还发生了修改操作,它是能够感知到的 。
ResultSet有两种并发类型 。
  1. ResultSet.CONCUR_READ_ONLY:ResultSet是只读的,这是默认类型 。
  2. ResultSet.CONCUR_UPDATABLE:我们可以使用ResultSet的更新方法来更新里面的数据 。
更多内容,欢迎关注微信公众号:全菜工程师小辉~

【彻底搞懂JDBC的运行过程】


推荐阅读