(九) 事务
可以将一组语句构建成一个事务(transaction),当所有语句顺利执行之后,事务可以被提交(commit),否则事务将被回滚(rollback);
使用事务的原因:保持数据库完整性(database integrity)
默认情况下数据库连接处于自动提交模式(autocommit mode),每个SQL命令一旦被执行便提交给数据库,一旦提交就无法回滚,在使用事务时,需要关闭这个默认值。
关闭自动提交模式 : conn.setAutoCommit(false);
提交事务 : conn.commit();
回滚 : conn.rollback();
1.保存点(Save Point)
在使用某些驱动程序时,使用保存点(Save Point)可以更好地控制回滚操作,创建一个保持点意味着稍后只需返回到这个点,而非事务开头。
e.g.? 保持点的使用,建立、返回和释放
Statement stmt = conn.createStatement(); //开始事务,rollback()将回到该点 stmt.executeUpdate(command1); Savepoint savepoint = conn.setSavepoint();//设置保存点,rollback(savepoint)将回到该点 stmt.executeUpdate(command2); if(...){ conn.rollback(savepoint); //回到保持点,相当于不执行command2 } conn.commit(); conn.releaseSavepoint(savepoint) //当不再需要保存点时,必须释放它
注意:保存点只能保存DML语言,即UPDATE更新、INSERT插入、DELETE删除。?
?
2.批量更新(batch update)
假设有一个程序需要执行许多insert语句,以便将数据填入数据库表中,可以使用批量更新的方法来提高程序性能。
在使用批量更新(batch update)时,一个命令序列作为一批操作将同时被收集和提交。
注意:
(1)使用DatabaseMetaData类中的supportsBatchUpdate方法可以获知数据库是否支持这种特性。
(2)处于同一批中的容器可以是INSERT、UPDATE和DELETE等操作,也可以是数据库定义命令,如CREATE TABLE和DROP TABLE。但是批量处理中添加SELECT命令会抛出异常。(从概念上讲,批量处理中的SELECT语句没有意义,因为它会返回结果集,而不是更新数据库)
(3)应该调用addBatch(sql)方法,而非executeUpdate方法。
(4)为了在批量模式下正确的处理错误,必须将批量执行的操作视为事务,如果批量更新在执行过程中失败,那么必须将它回滚到批量操作开始之前的状态。
e.g.通过批量更新建表及添加数据
boolean autoCommitState = conn.getAutoCommit(); conn.setAutoCommit(false); Statement stmt = conn.createStatement(); String command = "CREATE TABLE ..."; stmt.addBatch(command); while(...){ command = "INSERT INTO ... VALUES(...)"; stat.addBatch(command); } int[] counts = stmt.executeBatch();//包含批中每个命令的一个元素的更新计数所组成的数组。 conn.setAutoCommit(autoCommitState)
?
3.高级SQL类型
? ? SQL数据类型及其对应的Java类型
?
SQL数据类型 Java数据类型INTEGER或INT intSMALLINT shortNUMERIC(m,n),DECIMAL(m,n),DEC(m,n) java.math.BigDecimalFLOAT(n) doubleREAL floatDOUBLE doubleCHARACTER(n)或CHAR(n) StringVARCHAR(n),LONGVARCHAR StringBOOLEAN booleanDATE java.sql.DateTIME java.sql.TimeTIMESTAMP java.sql.TimestampBLOB java.sql.BlobCLOB java.sql.ClobARRAY java.sql.ArrayROWID java.sql.RowIdNCHAR(n),NVARCHAR(n),LONG NVARCHAR(n) StringNCLOB java.sql.NClob
?
?
?
(1)SQL ARRAY(SQL数组)是值的序列,在Oracle中为关键字
(2)从数据库中获取一个BLOB或数组并不等于获取了它的实际内容,只有在访问具体的值时,它们才会从数据库中读取出来,目的是改善性能,因为通常这些数据的数据量都非常大。
(3)某些数据库支持ROWID值,JDBC 4引入了java.sql.RowId接口,并提供了用于在查询时中提供行ID,以及从结果中获取该值的方法。Oracle中为关键字。
(4)NCHAR及其变体为国家属性字符串,按照本地字符编码机制存储字符串,并使用本地排序惯例对这些字符串进行排序。JDBC 4提供了方法,用于在查询和结果中进行Java的String对象和国家属性字符串之间的双向转换。
(5)有些数据库可以存储用户自定义的结构化类型,JDBC 3提供了一种机制用于将SQL结构化类型自动映射成Java对象。
(6)有些数据库提供用于XML数据的本地存储。JDBC 4引入了SQLXML接口,它可以在内部XML表示和DOM的Source/Result接口或二进制流之间起到中介作用。