标签:jdbc
先记录一下几个测试结果
测试环境
MySQL:mysql-connector-java-5.1.29.jar
Java:1.7.0_67
测试A
代码:
PreparedStatement pstmt = conn
.prepareStatement("select id from world.city limit 3");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1));
}
System.out.println();
PreparedStatement pstmt2 = conn
.prepareStatement("select countrycode from world.city limit 3");
ResultSet rs2 = pstmt2.executeQuery();
while (rs2.next()) {
System.out.println(rs2.getString(1));
}
System.out.println(pstmt.isClosed());
System.out.println(rs.isClosed());
System.out.println(pstmt2.isClosed());
System.out.println(rs2.isClosed());
System.out.println(conn.isClosed());
System.out.println();
conn.close();
System.out.println(pstmt.isClosed());
System.out.println(rs.isClosed());
System.out.println(pstmt2.isClosed());
System.out.println(rs2.isClosed());
System.out.println(conn.isClosed());
System.out.println();结果:
false false false false false true true true true true
结论:
connection关闭时会关闭关联的ResultSet和PreparedStatement。
测试B
代码:
PreparedStatement pstmt = null;
ResultSet rs1 = null;
ResultSet rs2 = null;
Statement st = null;
ResultSet rs3 = null;
ResultSet rs4 = null;
try {
pstmt = conn.prepareStatement(
"select name from world.city where name like ? limit 3");
pstmt.setString(1, "a%");
rs1 = pstmt.executeQuery();
rs2 = null;
while (rs1.next()) {
System.out.println(rs1.getString(1));
pstmt.setString(1, "b%");
rs2 = pstmt.executeQuery();
while (rs2.next()) {
System.out.println(rs2.getString(1));
}
}
}
catch (Exception e) {
e.printStackTrace();
}
try {
st = conn.createStatement();
rs3 = st.executeQuery(
"select name from world.city where name like ‘a%‘ limit 3");
rs4 = null;
while (rs3.next()) {
System.out.println(rs3.getString(1));
rs4 = st.executeQuery(
"select name from world.city where name like ‘b%‘ limit 3");
while (rs4.next()) {
System.out.println(rs4.getString(1));
}
}
}
catch (Exception e) {
e.printStackTrace();
}
System.out.println(pstmt.isClosed());
System.out.println(rs1.isClosed());
System.out.println(rs2.isClosed());
System.out.println(st.isClosed());
System.out.println(rs3.isClosed());
System.out.println(rs4.isClosed());
System.out.println(conn.isClosed());
System.out.println();结果:
java.sql.SQLException: Operation not allowed after ResultSet closed java.sql.SQLException: Operation not allowed after ResultSet closed false true false false true false false
结论:
同一个Statement或PreparedStatement对象只能关联一个激活的ResultSet。
测试C
代码:
PreparedStatement pstmt = conn
.prepareStatement("select id from world.city limit 3");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1));
}
System.out.println();
PreparedStatement pstmt_old = pstmt;
pstmt = conn.prepareStatement("select name from world.city where name like ? limit 3");
pstmt.setString(1, "a%");
ResultSet rs2 = pstmt.executeQuery();
while (rs2.next()) {
System.out.println(rs2.getString(1));
}
System.out.println(pstmt.isClosed());
System.out.println(rs.isClosed());
System.out.println(pstmt_old.isClosed());
System.out.println(rs2.isClosed());
System.out.println(conn.isClosed());
System.out.println();
pstmt.close();
System.out.println(pstmt.isClosed());
System.out.println(rs.isClosed());
System.out.println(pstmt_old.isClosed());
System.out.println(rs2.isClosed());
System.out.println(conn.isClosed());
System.out.println();
conn.close();
System.out.println(pstmt.isClosed());
System.out.println(rs.isClosed());
System.out.println(pstmt_old.isClosed());
System.out.println(rs2.isClosed());
System.out.println(conn.isClosed());
System.out.println();结果:
false false false false false true false false true false true true true true true
结论:
如果PreparedStatement对象没有关闭就关联了其他PreparedStatement,则旧的PreparedStatement和ResultSet不会关闭,直到Connection关闭。在使用连接池的情况下,可能造成内存泄露。
比较好的做法:
使用PreparedStatement代替Statement,一方面,多次提高了多次执行语句的效率,另一方面,防止拼接SQL可能造成的注入攻击
一定要注意关闭PreparedStatement,在使用连接池的情况下尤其要注意。Java7以上建议使用try-with-resource语句,简洁。Java7以下注意关闭时也要try-catch,并尽量按照ResultSet、PreparedStatement、Connection的顺序关闭。
不要传递ResultSet,使用RowSet。
本文出自 “不积跬步,无以至千里” 博客,请务必保留此出处http://wangzhichao.blog.51cto.com/2643325/1720656
Connection、Statement、PreparedStatement 、Resultset注意点备忘
标签:jdbc
原文地址:http://wangzhichao.blog.51cto.com/2643325/1720656