PreparStament
-
简介
通过上面的例子发现,statement存在以下问题
- sql注入的问题
- 动态sql拼接太过麻烦
为了解决上述问题,那么我们可以采用一个新的执行SQL语句工具类对象
PreparStament
,有以下好处:- 提供了预编译功能,避免了SQL注入问题
- 能够使用动态sql,不需要用户手动拼接动态sql
-
创建PreparStatement,并执行DML语句
@Test public void preInsertData() throws Exception { Connection connection = ConnectionUtil.getConnection(); // 创建sql语句,如果不确定sql中具体的值,可以用 ?代替 // 简单的说 :?就是一个占位符 String sql = "insert into jdbc_test values(?,?,?,?)"; // 创建对象时需要传入sql语句 PreparedStatement prepareStatement = connection.prepareStatement(sql); /* * 给sql语句注入值,说白了就是替换? 给替换?时需要根据数据类型不同而调用不同的方法 */ // id数据为int类型,第一个参数为?的索引,从1开始,第二个参数为具体的值 prepareStatement.setInt(1,2); prepareStatement.setString(2, "套马的汉子"); prepareStatement.setDouble(3, 1000); prepareStatement.setDate(4, new Date(System.currentTimeMillis())); // 返回影响条数,执行时不需要传入SQL int result = prepareStatement.executeUpdate(); System.out.println(result); connection.commit(); prepareStatement.close(); connection.close(); }
-
执行查询
@Test public void selectData() throws Exception { // 获取连接 Connection connection = ConnectionUtil.getConnection(); String sql = "select * from jdbc_test where id = ?"; // 创建对象 PreparedStatement preparedStatement = connection.prepareStatement(sql); // 用户手动输入数据 Scanner scanner = new Scanner(System.in); String id = scanner.next(); preparedStatement.setInt(1, Integer.parseInt(id)); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { int ids = resultSet.getInt(1); String name = resultSet.getString("name"); double salary = resultSet.getDouble("salary"); System.out.println(ids + ":" + name + ":" + salary); } preparedStatement.close(); connection.close(); }
-
PreparStatement与Statement对比
Statement:
-
创建时不需要传递sql语句,但是执行时需要传递sql语句。
-
如果涉及到动态参数的传递,必须使用字符串拼接-
PreparedStatement:
-
创建时就需要传递sql语句,执行的时候不需要传递sql语句-
-
如果涉及到动态参数的传递,可以使用字符串拼接,也可以使用?占-
位的形式要求在执行sql语句之前,给?号传值。 -
提供预编译的功能,某种程度上可以避免sql注入的问题
-