jdbc 1.0 - 4.0

1.0

jdk1.1,java.sql包

  • 类 DriverManager、SQLException

  • 接口

Driver、Connection、Statement、ResultSet

2.0

拆成 java.sql(核心API)、javax.sql(扩展API)

  • java.sql

结果集滚动、batch updates、(BLOB/CLOB)

  • javax.sql

连接池技术,都需要实现 javax.sql.DataSource 接口

Connection pooling、Distrubute transaction、RowSet、SavePoints

Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("jdbc/InventoryDB"):
Connection conn = ds.getConnection("password","username");

3.0

jdk1.4

JDBC 2 时,SQL99规范未定

MetaData API

Database/Parameter MetaData

PreparedStatement 中的medaData

CallableStatements 命名参数

3.0前只支持索引值

获取自增值

Statement stmt = conn.createStatement();
stmt.executeUpdate("INSERT INTO authors values (′George′, ′Orwell′)",Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
    int key = rs.getInt("");
}  

离线ResultSet

事务commit后cursor/resultset不自动关闭   createStatement/prepareStatement/prepareCall 时用

  • HOLD_CURSORS_OVER_COMMIT ResultSet 对象(游标)没有被关闭 它们在提交操作得到显式的或隐式的执行以后仍保持打开的状态

  • CLOSE_CURSORS_AT_COMMIT
    ResultSet 对象(游标)在提交操作得到显式的或隐式的执行后被关闭

总的来说,在事务提交之后关闭游标操作会带来更好的性能。除非在事务结束后还需要该游标,否则您最好在执行提交操作后将其关闭

返回多重结果

允许 Statement 接口支持多重打开的 ResultSets execute() 仍会关闭任何以前 execute() 中打开的 ResultSet 重载的 getMoreResults() 会做一个整数标记,在 getResultSet() 方法被调用时指定前一次打开的 ResultSet 的行为

  • CLOSE_ALL_RESULTS
    所有以前打开的 ResultSet 对象都将被关闭
  • CLOSE_CURRENT_RESULT
    当前的 ResultSet 对象将被关闭
  • KEEP_CURRENT_RESULT
    当前的 ResultSet 对象将不会被关闭
String procCall;
// Set the value of procCall to call a stored procedure.
CallableStatement cstmt = connection.prepareCall(procCall);
int retval = cstmt.execute();
if (retval == false) {
    // The statement returned an update count, so handle it.
    // ...
} else { // ResultSet
    ResultSet rs1 = cstmt.getResultSet();
    // ...
    retval = cstmt.getMoreResults(Statement.KEEP_CURRENT_RESULT);
    if (retval == true) {
        ResultSet rs2 = cstmt.getResultSet();
        // Both ResultSets are open and ready for use.
        rs2.next();
        rs1.next();
        // ...
    }
}

连接池

标准连接池属性

属性名称描述
maxStatements连接池可以保持打开的语句数目
initialPoolSize当池初始化时可以建立的物理连接的数目
minPoolSize池可以包含的物理连接的最小数目
maxPoolSize池可以包含的物理连接的最大数目
零指没有最大值
maxIdleTime持续时间,以秒计,指一个闲置的物理连接在被关闭前可以在池中停留的时间
零指没有限制
propertyCycle间隔时间,以秒计,指连接池在执行其属性策略前可以等待的时间

预编译语句池

缓冲预编译语句

String INSERT_BOOK_QUERY = "INSERT INTO BOOKLIST " +
        '(AUTHOR, TITLE) " +
     "VALUES (?, ?) ";
Connection conn = aPooledConnection.getConnection();
PreparedStatement ps = conn.prepareStatement(INSERT_BOOK_QUERY);
ps.setString(1, "Orwell, George");
ps.setString(2, "1984");
ps.executeUpdate();
ps.close();
conn.close();
// ...
conn = aPooledConnection.getConnection();
// Since the connection is from a PooledConnection, the data layer has
// the option to retrieve this statement from its statement pool,
// saving the VM from re-compiling the statement again.
PreparedStatement cachedStatement = conn.prepareStatemet(INSERT_BOOK_QUERY);
// ...

Savepoint

将事务分割为各个逻辑断点,以控制有多少事务需要回滚

或许不是经常需要使用 Savepoint 然而,在一种普遍的情况下 Savepoint 会发挥作用 需要作一系列的改变,但是在知道所有的结果之前不能确定应该保留这些改变的哪一部分

conn.setAutoCommit(false);
//Set a conservative transaction isolation level
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate( "INSERT INTO authors "
 + '(first_name, last_name) VALUES " 
+'('Lewis', 'Carroll')");
//Set a named savepoint.
Savepoint svpt = conn.setSavepoint("NewAuthor");

rows = stmt.executeUpdate( "UPDATE authors set type = 'fiction' " +
"WHERE last_name = 'Carroll'");
conn.rollback(svpt);

// The author has been added, but not updated.
conn.commit();

4.0

JSR-221

驱动及连接管理

不必再显式地加载 Class.forName

异常处理

for (Throwable e : ex) {
    System.err.println("Error encountered: " + e);
}

数据类型

SQLXML ROWID 大对象类型支持的增强 National Character Set

API 变化

Array Connection 提供一系列创建大对象的方法如 createClob,createBlob 等及验证当前连接正确性的方法

PooledConnection 提供 addStatementEventListener 和 removeStatementEventListener

DatabaseMetaData增强

con = ds.getConnection();
DatabaseMetaData dmd = con.getMetaData();
rs=dmd.getSchemas("TABLE_CAT", "SYS%");
//iterate over the rs and print to console

CAT库以 SYS 开头的数据库和表结构

Scalar 函数支持

Statement,PreparedStatement,和 CallableStatement提供 isClosed ,setPoolable 是否可以被池化,isPoolable 来检测当前的池化状态 PreparedStatement 及 CallableStatement 接口现在提供了更多插入大对象的方法,通过使用 InputStream 及 Reader 等 .

Wrapper

4.1(JDK7)

Closeable 接口

Connection、ResultSet 、Statement 实现 Closeable 接口

try (Statement stmt = con.createStatement()){    
        …    
}    

4.2(JDK1.8)

REF Cursor 修改返回值大小范围(update count) java.sql.DriverAction接口 java.sql.SQLType接口 java.sql.JDBCtype枚举 java.time包时间类型的支持