今天看sql批处理的时候看到别人用的Connection.preparecall然后上网查了一下发现用法挺多的,是preparedstment的plus版本么
preparedstatement和preparecall是java中用于执行参数化 sql 语句的接口。两者的区别在于主要应用场景不同。
1.preparedstatement接口
主要应用于执行静态 sql 语句,并预编译 sql 语句,当需要多次执行相似语句时,可以提高效率。
可以使用占位符 ? 代替具体数值或参数,通过 setxxx() 方法设置参数值,提高可读性和灵活性。
常用于查询、**、更新等操作,只需要传入不同的参数即可执行不同的 sql 语句。
2.callablestatement接口
继承了preparedstatement接口,也能够执行静态 sql 语句并支持预编译。
主要用于存储过程的调用,在 sql server 数据库中被称为extended stored procedures。
相比于 preparedstatement,callablestatement还提供了更好的存储过程支持,包括输入/输出参数和游标操作等。
加强版本吧
prepareCall 返回CallableStatement,CallableStatement继承自PreparedStatement,PreparedStatement只能执行sql,prepareCall 一般用来执行存过,也可以执行sql
PreparedStatement和PrepareCall都是预编译SQL语句的接口,但是用途不同。PreparedStatement适用于静态的SQL查询,执行效率高,参数的传递也很方便;而PrepareCall适用于调用存储过程,也就是带有参数输入/输出的SQL查询。
下面介绍一下PreparedStatement的解决方案:
String sql = "SELECT * FROM user_info WHERE user_name = ? AND password = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "张三"); ps.setString(2, "123456");
其中,1和2表示占位符的位置,从1开始计数,setString表示设置String类型的参数,最后一个参数是具体的参数值。
ResultSet rs = ps.executeQuery();
如果是更新操作,例如:
int affectedRows = ps.executeUpdate();
可以用executeBatch()方法来执行批量更新操作。
ps.close(); conn.close();
另外,为了防止SQL注入等安全问题,可以使用ESAPI等安全框架提供的工具方法对参数值进行处理,例如:
String safeUserName = ESAPI.encoder().encodeForSQL(new MySQLCodec(MySQLCodec.Mode.STANDARD), userName);
最后,可以使用Batch批处理机制来优化数据库操作性能,具体做法是把多个SQL语句打包成一次提交,以此减少I/O,降低吞吐时间。例如:
PreparedStatement ps = conn.prepareStatement("INSERT INTO user_info (user_name, password) VALUES (?, ?)");
for (int i = 0; i < users.size(); i++) { User user = users.get(i); ps.setString(1, user.getName()); ps.setString(2, user.getPassword()); ps.addBatch(); if (i % 1000 == 0) { ps.executeBatch(); } }
ps.executeBatch(); ps.close();