日期:2014-05-16  浏览次数:20385 次

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。<