预处理语句
Java提供了更高效率的数据库操作机制,就是PreparedStatement对象,该对象被习惯地称做预处理语句对象。
预处理语句优点
对于JDBC,如果使用Connection和某个数据库建立了连接对象con,那么con就可以调用prepareStatement(String sql)方法对参数sql指定的SQL语句进行预编译处理,生成该数据库底层的内部命令,并将该命令封装在PreparedStatement对象中,那么该对象调用下列方法都可以使得该底层内部命令被数据库执行。
ResultSet executeQuery()
boolean execute()
int executeUpdate()
只要编译好了PreparedStatement对象,那么该对象可以随时执行上述方法,显然提高了访问数据库的速度。
public void inputQueryResult() {
Connection con;
PreparedStatement sql;
ResultSet rs ;
try {
con = DBUtil.getConnection();
DatabaseMetaData metadata = con.getMetaData();
ResultSet rs1 = metadata.getColumns(null,null,"stu",null);
int count = 0;
while(rs1.next()) {
count ++ ;
}
sql = con.prepareStatement(SQL); //调用prepareStatement(String sql)方法对指定的SQL语句进行预编译处理。EE
rs = sql.executeQuery(); //调用executeQuery()方法使得底层内部命令被数据库执行。
while(rs.next()) {
for(int k=1; k<=count; k++) {
System.out.println(rs.getString(k));
}
System.out.println(" ");
}
con.close();
}catch(Exception e) {
e.printStackTrace();
}
}
通配符
在对SQL进行预处理时,可以使用通配符“?”来代替字段的值,只要在预处理语句执行之前再设置通配符所表示的具体值即可。例如:
sql = con.prepareStatement("SELECT * FROM goods WHERE salary < ?");
再sql对象执行之前,必须调用相应的方法设置通配符“?"代表的具体指,比如:
sql.setFloat(1,76,98);
指定上述预处理SQL语句中通配符”?“代表的值是76.839。通配符按着它们在预处理SQL语句中从左到右依次出现的顺序分别被称为第一个、第二个、.....、第m个通配符。
void setFloat(int parameterIndex, float x)用来设置通配符的值,其中参数paramIndex用来表示SQL语句从左到右的第paramerterIndex个通配符号,x是该通配符所代表的具体指。
使用通配符可以使得应用程序更容易动态地改变SQL语句中关于字段值的条件。
事务
事务能够控制何时更改提交并应用于数据库,它将单个SQL语句或一组SQL视为一个逻辑单元,如果语句失败,整个事务将失败。
要启动手动事务支持,而不是使用JDBC驱动程序默认使用的自动提交模式,调用Connection对象的setAutoCommit()方法,如果将false传递给setAutoCommit(),则关闭自动提交,也可以传递true来重新打开它。
提交和回滚
完成更改后,若要提交更改,那么可在连接对象上调用commit()方法,
conn.commit();
否则,要使用连接名为conn的数据库回滚更新,使用以下代码:
conn.rollback();
保存点
新的JDBC 3.0新添加了Savepoint接口提供了额外的事务控制能力。大多数现代DBMS支持其环境中的保存点,如Oracle的PL/SQL。
设置保存点时,可在事务中定义逻辑回滚点,如果通过保存点发生错误时,则可以使用回滚方法来撤销所有更改或仅保存保存点之后所做的更改。
Connection对象有两种新的方法可用来管理保存点:
- setSavepoint(String savepointName) 定义新的保存点,它还返回一个Savepoint对象。
- releaseSavepoint(Savepoint savepointName) 删除保存点,它还需要一个Savepoint对象作为参数。该对象通常是由setSavepoint()方法生成的保存点。
有一个rollback (String savepointName)方法,它将使用事务回滚到指定的保存点。
JDBC批处理
批处理允许相关的SQL语句分组到批处理中,并通过对数据库的一次调用来提交它们,一次执行完成与数据库之间的交互。
- DatabaseMetaData.supportsBatchUpdates()方法来确定目标数据库是否支持批量更新处理,如果JDBC驱动程序支持此功能,则返回true。
- Statement,PrepareStatement和CallableStatement的addBatch()方法用于将单个语句添加到批处理。executeBatch()用于执行组成批量的所有语句。
- executeBatch()返回一个整数数组,数组的每个元素表示相应更新语句的更新计数。
- 使用clearBatch()方法可用删除它们,此方法将删除所有使用addBatch()方法添加的语句。但是,无法指定选择某个要删除的语句。
使用Statement对象进行批处理:
以下是使用Statement 对象的批处理的典型步骤序列。
- 使用createStatement()方法创建Statement对象。
- 使用setAutoCommit()将自动提交设置为false。
- 使用addBatch()方法创建的Statement对象上添加到批处理中。
- 在创建的Statement对象上使用executeBatch()方法执行所有SQL语句。
- 最后使用commit()方法提交所有更改。
使用PrepareStatement对象进行批处理。
以下是使用PrepareStatement对象进行批处理的典型步骤顺序。
- 使用占位符创建SQL语句。
- 使用prepareStatement()方法创建PrepareStatement对象。
- 使用setAutoCommit()将自动提交设置为false。
- 使用addBatch()方法在创建的Statement对象上添加SQL语句到批处理中。
- 在创建的Statement对象上使用executeBatch()方法执行所有SQL语句。
- 最后,使用commit()方法提交所有更改。
Connection con = null;
ResultSet rs ;
try {
con = DBUtil.getConnection();
String SQL = "INSERT INTO stu(name,phone) VALUES(\"抗压\",\"1231313123\")";
PreparedStatement p = con.prepareStatement(SQL);
con.setAutoCommit(false);
p.addBatch(SQL);
String SQL1 = "INSERT INTO stu(name,phone) VALUES(\"你好\",\"123123132\")";
p.addBatch(SQL1);
p.executeBatch();
con.commit();
}catch(Exception se) {
se.printStackTrace();
}
CachedRowSetImpl类
JDBC使用ResultSet对象处理SQL语句从数据库表中查询的记录,需要特别注意的是,ResultSet对象和数据库连接对象(Connection 对象)实现了紧密的绑定,一旦连接对象被关闭,ResultSet对象中的数据立刻消失。这就意味着,应用程序在使用ResultSet对象中的数据时,就必须始终保持和数据库的连接,直到应用程序将ResultSet对象中的数据产看完毕。
每种数据库在同一时刻都有允许的最大连接数目,因此当多个应用程序同时连接访问数据库时,应当避免长时间占用数据库的连接资源。
com.sun.rowset包提供了CachedRowSetImpl类,该类实现了CachedRowSet接口。CachedRowSetImpl对象可以保存ResultSet对象中的数据,而且CachedRowSetImpl对象不依赖Connection对象,这意味着一旦把ResultSet对象中的数据保存到CachedRowSetImpl对象中后,就可以关闭和数据库的连接。CachedRowSetImpl继承了ResultSet的所有方法,因此可以操作ResultSet对象一样来