执行SQL语句并处理结果
向数据库发出执行SQL的请求时,需要使用Statement或PreparedStatement,使用Statement或PrepareStatement实例发出查询,服务端执行完成后将返回一个ResultSet实例,该实例包括查询的结果。
执行查询
使用Statement执行查询
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE columnfoo= 500");
while (rs.next())
{
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
使用PreparedStatement执行查询
int foovalue = 500;
PreparedStatement st = conn.prepareStatement("SELECT * FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
ResultSet rs = st.executeQuery();
while (rs.next())
{
System.out.print("Column 1 returned ");
System.out.println(rs.getString(1));
}
rs.close();
st.close();
使用游标获取结果
默认情况下,驱动程序将一次性获取查询的所有结果,当某个查询的结果集很庞大时,一次获取所有结果很不合理,因此JDBC驱动程序提供了一种基于数据库游标的ResultSet方法,只获取少量的行缓存在客户端。通过重新定位游标来获取下一批数据。
基于游标的ResultSet不能在所有情况下使用。有许多限制会使驱动程序一次性获取整个结果集:
连接不能使用自动提交模式,因为后端会在事务结束时关闭游标,因此在自动提交模式下,事务结束后,在从游标获取数据之前,游标已经被关闭。
Statement必须使用ResultSet.TYPE_FORWARD_ONLY类型创建,这意味着不能在结果集中进行跳转或向后滚动。这也是默认值,因此不需要在代码中额外指定。
给定的查询语句必须是单条语句,不能是用分号连接在一起的多个语句。
必须设置fetch size,且fetch size不能为0。
示例:
// make sure autocommit is off
conn.setAutoCommit(false);
Statement st = conn.createStatement();
// Turn use of the cursor on.
st.setFetchSize(50);
ResultSet rs = st.executeQuery("SELECT * FROM mytable");
while (rs.next())
{
System.out.print("a row was returned.");
}
rs.close();
// Turn the cursor off.
st.setFetchSize(0);
rs = st.executeQuery("SELECT * FROM mytable");
while (rs.next())
{
System.out.print("many rows were returned.");
}
rs.close();
// Close the statement.
st.close();
使用Statement和 PreparedStatement接口
在使用Statement和PreparedStatement时,需要注意以下问题:
可以多次使用一个Statement实例,可以在打开连接时创建Statement然后在连接的整个生命周期内使用它。但是必须注意在给定时间内每个Statement或PreparedStatement只能存在一个ResultSet.
如果在处理ResultSet时需要执行查询,可以创建另一个Statement来执行。
如果使用多线程,并且有多个线程正在使用数据库,则每个线程必须使用单独的Statement.
使用完Statement或PreparedStatement应该及时关闭。
在JDBC中,问号(?)是PreparedStatement的占位符,但是有一些操作符包含一个问号,为避免SQL语句中的问号被当成占位符,可以使用两个问号(??)进行转义。也可以在Statement中使用上述转义,但是不是必须的,因为在Statement中单个问号也可以用作操作符。
使用ResultSet接口
使用ResultSet接口时必须考虑下面的问题:
在读取任何数值的时候,必须调用next(),如果还有结果则返回真(true)。
在 JDBC 规范里,对一个字段应该只访问一次。遵循这个规则是最安全的,不过目前 Vastbase G100 JDBC驱动允许对一个字段访问任意次。
在结束对一个 ResultSet 的处理后,必须调用 close()来关闭它。
使用那个创建ResultSet的 Statement做另一个查询请求, 当前打开的ResultSet 实例将自动关闭。
执行更新
要更改数据(执行一个insert,update或者delete),可以使用 executeUpdate()方法. executeUpdate() 方法类似于发出 select语句的executeQuery()方法,不过,它不返回ResultSet,它返回的是insert,update或者delete语句影响的行数。
删除
int foovalue = 500;
PreparedStatement st = conn.prepareStatement("DELETE FROM mytable WHERE columnfoo = ?");
st.setInt(1, foovalue);
int rowsDeleted = st.executeUpdate();
System.out.println(rowsDeleted + " rows deleted");
st.close();
更新
int foovalue = 500;
PreparedStatement st = conn.prepareStatement("UPDATE mytable SET columninfo='updated' WHERE columnfoo = ?");
st.setInt(1, foovalue);
int rowsUpdated = st.executeUpdate();
System.out.println(rowsDeleted + " rows updated");
st.close();
插入
插入单行:
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable(col_1,col_2) values(?,?)"); st.setInt(1, 0); st.setString(2, "row1"); int rowsInserted = st.executeUpdate(); System.out.println(rowsDeleted + " rows inserted"); st.close();
插入多行:
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable(col_1,col_2) values(?,?)"); st.setInt(1, 0); st.setString(2, "row1"); st.addBatch(); st.setInt(1,1); st.setString(2, "row2"); st.addBatch(); st.executeBatch(); st.close();
创建或修改数据库对象
要创建、更改或者删除一个类似表或者视图这样的数据库对象, 可以使用execute() 方法, execute()方法类于发出 select语句的 executeQuery()方法,不过它不返回结果。
例如DROP表:
Statement st = conn.createStatement();
st.execute("DROP TABLE mytable");
st.close();