JDBC预编译
原始的JDBC操作,因为SQL语句可以通过字符串进行拼接,因此会出现SQL注入问题,这样是不安全的。
所以我们使用占位符 “?” 来直接修改SQL语句
示例:
insert into emp(eno,ename,phone) values(?,?,?);
select e.eno,e.ename,e.phone from emp e where e.eno=?;
- 关键词 PreparedStatement 是Statement的子接口
PreparedStatement 表示预编译的SQL语句的对象。
SQL语句已预编译并存储在PreparedStatement
对象中。 然后可以使用该对象多次有效地执行此语句。
主要方法:
execute()
执行此PreparedStatement
对象中的SQL语句,这可能是任何类型的SQL语句。
executeQuery()
执行此PreparedStatement
对象中的SQL查询,并返回查询PreparedStatement
的ResultSet
对象。
executeUpdate()
执行在该SQL语句PreparedStatement
对象,它必须是一个SQL数据操纵语言(DML)语句
setInt(int parameterIndex, int x)
将指定的参数设置为给定的Javaint
值。
setObject(int parameterIndex, Object x)
使用给定对象设置指定参数的值。
- 常规的预编译查询
/**
* 常规的预编译查询功能
*/
public static void query() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 获取连接对象
conn = DBUtil.newInstance();
// 定义SQL
String sql = "select * from emp where ename=? and dno=?";
// 预编译SQL
ps = conn.prepareStatement(sql);
// 动态的给占位符设置参数,参数一代表占位符的位置(从1开始) 参数二代表要设置的值
ps.setString(1, "柱子");
ps.setInt(2, 3);
// 执行SQL获取结果集
rs = ps.executeQuery();
Emp emp = null;
// 遍历结果集
while (rs.next()) {
emp = new Emp();
emp.setEno(rs.getInt("eno"));
emp.setEname(rs.getString("ename"));
emp.setSex(rs.getString("sex"));
emp.setBirthday(rs.getDate("birthday"));
emp.setPhone(rs.getString("phone"));
emp.setDno(rs.getInt("dno"));
}
System.out.println(emp);
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn, ps, rs);
}
}
- 预编译的普通写法
public static void delete() {
Connection conn = null;
PreparedStatement ps = null;
try {
//通过工具类创建连接(工具类参见上篇博客)
conn=DBUtil.newInstance();
//定义SQL
String sql = "delete from depart where dno =?";
//预编译SQL
ps=conn.prepareStatement(sql);
ps.setInt(1, 66);//where dno=66
//执行SQL
int result = ps.executeUpdate();
System.out.println(result);
} catch (SQLException e) {
e.printStackTrace();
} finally {//使用工具类关闭连接
DBUtil.close(conn, ps, rs);
}
}
- 增删改预编译的工具类
/**
* 预编译增删改通用对象
* @param sql
* @param objects
* ...代表是可变数组
* 可以当成是一个单独的对象或变量,例如:1,"str"
* 还可以当成是一个数组,数组的大小是固定的,因此在传值的时候,是需要先定义数组的
* @return
*/
public static int precurdMethod(String sql,Object...objects) {
PreparedStatement ps = null;
try {
newInstance();
ps=conn.prepareStatement(sql);
//设置参数,根据下标
if(objects !=null) {
for(int i =0;i<objects.length;i++) {
//i+1 占位符的下标是从1开始的,正好和数组的下标相差1,注意一定不能影响循环本身的i的值(不能使用i++)
ps.setObject(i+1, objects[i]);
}
}
int result = ps.executeUpdate();
return result;
} catch (SQLException e) {
System.out.println("预编译异常");
e.printStackTrace();
}
finally {
close(conn,ps,null);
}
return 0;
}
- 当工具类完成之后我们可以使用更简单的方法进行操作,以添加为例
/**
* 用工具类实现添加功能呢
*/
public static void insert2() {
String sql = "insert into depart values(?,?,?)";
Object[] objects = {20, "test", "test loc" };
DBUtil.precurdMethod(sql, objects);
}