一、PreparedStatement

PreparedStatement原理

  • Statement主要用于执行静态SQL语句,即内容固定不变的SQL语句
  • Statement每执行一次都要对传入的SQL语句编译一次,效率较差
  • 某些情况下,SQL语句只是其中的参数有所不同,其余子句完全相同,适用于PreparedStatement
  • 预防SQL注入攻击 PreparedStatement 接口继承自Statement,execute、executeQuery、executeUpdate方法已重写,不再需要参数。PreparedStatement实例包含已事先编译的SQL语句,SQL语句的IN参数使用『?』占位。
1
2
3
4
PreparedStatement stmt = conn.prepareStatement("UPDATE amp SET job = ? WHERE empno = ?");
stmt.setLong(1,"Manger");
stmt.setInt(2,1001);
stmt.executeUpdate();

由于数据库具有缓存功能,可以对statement的执行计划进行缓存,以免重复解析。但是如果每次执行SQL,条件都不同,则DB每次都会创建新计划,缓存并没有起到作用,但是PrepareStatement每次执行内容都用占位符占位,所以PrepareStatement可以利用缓存,提升性能。

SQL Injection只对Statement有效,对PreparedStatement无效,因为PreparedStatement不允许在插入参数时改变SQL语句的逻辑结构

二、ResultSetMetaData

ResultSetMetaData 数据结果集的元数据,对结果集进行描述的数据,只有返回ResulSet时才有这个元数据

1
2
3
4
5
6
ResultSetMetaData rsm = rs.getMetaData();
int columnCount = rsm.getColumnCount();
String columnName = null;
for (int i = 1;i <= columnCount;i++) {
columnName = rsm.getColumnName(i);
}

三、可滚动的结果集

创建可滚动的结果集

1
Statement stmt = conn.createStatement(type,concurrency);


1
PreparedStatement stmt = conn.prepareStatement(sql,type,concurrency);

type取值

  • TYPE_FORARD_ONLY 只能向前移动,默认参数
  • TYPE_SCROLL_INSENSITIVE 可滚动,不感知数据变化
  • TYPE_SCROLL_SENSITIVE 可滚动,感知数据变化

concurrency取值

  • CONCUR_READ_ONLY 只读
  • CONCUR_UPDATABLE 可更新

可滚动集的常用方法

  • first
  • last
  • beforeFirst
  • afterLast
  • isFirst
  • isLast
  • isBeforeFirst
  • isAfterLast
  • relative
  • next
  • previous
  • absolute