JDBC常见面试题集锦(二)
JDBC的保存点(Savepoint)是什么,如何使用?
有时候事务包含了一组语句,而我们希望回滚到这个事务的某个特定的点。JDBC的保存点可以用来生成事务的一个检查点,使得事务可以回滚到这个检查点。
一旦事务提交或者回滚了,它生成的任何保存点都会自动释放并失效。回滚事务到某个特定的保存点后,这个保存点后所有其它的保存点会自动释放并且失效。可以读下这个了解更多关于JDBC Savepoint的信息。
JDBC的DataSource是什么,有什么好处?
DataSource即数据源,它是定义在javax.sql中的一个接口,跟DriverManager相比,它的功能要更强大。我们可以用它来创建数据库连接,当然驱动的实现类会实际去完成这个工作。除了能创建连接外,它还提供了如下的特性:
- 缓存PreparedStatement以便更快的执行
 - 可以设置连接超时时间
 - 提供日志记录的功能
 - ResultSet大小的最大阈值设置
 - 通过JNDI的支持,可以为servlet容器提供连接池的功能
 
关于JDBC数据源的示例请看下这里。
如何通过JDBC的DataSource和Apache Tomcat的JNDI来创建连接池?
对部署在servlet容器中的WEB程序而言,创建数据库连接池非常简单,仅需要以下几步。
- 在容器的配置文件中创建JDBC的JNDI资源,通常在server.xml或者context.xml里面。像这样:
<Resource name="jdbc/MyDB"
      global="jdbc/MyDB"
      auth="Container"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/UserDB"
      username="pankaj"
      password="pankaj123"
      maxActive="100"
      maxIdle="20"
      minIdle="5"
      maxWait="10000"/>
<ResourceLink name="jdbc/MyLocalDB"
                global="jdbc/MyDB"
                auth="Container"
                type="javax.sql.DataSource" />
 - 在WEB应用程序中,先用InitialContext来查找JNDI资源,然后获取连接。
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");
完整的示例请看这里。
 
Apache的DBCP是什么?
如果用DataSource来获取连接的话,通常获取连接的代码和驱动特定的DataSource是紧耦合的。另外,除了选择DataSource的实现类,剩下的代码基本都是一样的。
Apache的DBCP就是用来解决这些问题的,它提供的DataSource实现成为了应用程序和不同JDBC驱动间的一个抽象层。Apache的DBCP库依赖commons-pool库,所以要确保它们都在部署路径下。
完整的使用示例请看这里。
什么是数据库的隔离级别?
当我们为了数据的一致性使用事务时,数据库系统用锁来防止别人访问事务中用到的数据。数据库通过锁来防止脏读,不可重复读(Non-Repeatable Reads)及幻读(Phantom-Read)的问题。
数据库使用JDBC设置的隔离级别来决定它使用何种锁机制,我们可以通过Connection的getTransactionIsolation和setTransactionIsolation方法来获取和设置数据库的隔离级别。
| 隔离级别 | 
事务 | 
脏读 | 
不可重复读 | 
幻读 | 
| TRANSACTION_NONE | 
不支持 | 
不可用 | 
不可用 | 
不可用 | 
| TRANSACTION_READ_COMMITTED | 
支持 | 
阻止 | 
允许 | 
允许 | 
| TRANSACTION_READ_UNCOMMITTED | 
支持 | 
允许 | 
允许 | 
允许 | 
| TRANSACTION_REPEATABLE_READ | 
支持 | 
阻止 | 
阻止 | 
允许 | 
| TRANSACTION_SERIALIZABLE | 
支持 | 
阻止 | 
阻止 | 
阻止 | 
JDBC的RowSet是什么,有哪些不同的RowSet?
RowSet用于存储查询的数据结果,和ResultSet相比,它更具灵活性。RowSet继承自ResultSet,因此ResultSet能干的,它们也能,而ResultSet做不到的,它们还是可以。RowSet接口定义在javax.sql包里。
RowSet提供的额外的特性有:
- 提供了Java Bean的功能,可以通过settter和getter方法来设置和获取属性。RowSet使用了JavaBean的事件驱动模型,它可以给注册的组件发送事件通知,比如游标的移动,行的增删改,以及RowSet内容的修改等。
 - RowSet对象默认是可滚动,可更新的,因此如果数据库系统不支持ResultSet实现类似的功能,可以使用RowSet来实现。
 
RowSet分为两大类:
A. 连接型RowSet——这类对象与数据库进行连接,和ResultSet很类似。JDBC接口只提供了一种连接型RowSet,javax.sql.rowset.JdbcRowSet,它的标准实现是com.sun.rowset.JdbcRowSetImpl。<