之前项目中的数据需要大量写数据库,每次写的条数很多,所以想到了用批量执行的方式来节省时间。但这一块是同时做的,我直接调用API,一直没仔细看。后来想了解一下PreparedStatement的原理是怎样的,结果发现似乎想要批量执行并不是那么简单。
发现了这篇文章https://blog.csdn.net/intelrain/article/details/80451120。除了排版很差劲,其他的写的都很好。
后来需要自己动手连数据库,尝试了一下PreparedStatement进行批量处理,顺便实验了一下上面文章中的理论,结果发现是正确的。
额外准备
1、mysql日志默认是不会打开的,因为每条操作都记录,日志会非常大
set global general_log=on;
连上数据库,用上面命令打开日志,至于日志文件的位置可以通过下面的命令看到。general_log_file就是用来指定日志文件路径的
show variables like '%log%';
结论
1、PreparedStatement包含两个功能,防止sql注入+预编译。防止sql注入应该是通过sql语句检查实现的吧。
2、只有在url中加上了 useServerPrepStmts=true 才能真正打开预编译。而且在程序执行 connection.prepareStatement(sql) 的时候,会发现日志中出现了 “prepare sql……” 这种命令,说明预编译真正的在mysql端执行了。
3、cachePrepStmts=true 可以使得相同的sql语句不必重新编译。这个我尝试了,关闭prepareStatement,再重新create的时候确实没有新产生“prepare sql”操作。
4、程序重新执行的时候,所有的预编译必须重新执行。也就是说跨程序的预编译估计是不可行的(或者,根本上来说,跨connection的预编译都是不可复用的),没有实验,这个结论对我来说已经够用了。
5、网上看到说prepareStatement必须要关闭,不然会占用一些资源。但没有说为什么的,以及占用了什么资源。另外,如果connection关闭,prepareStatement是否会随之关闭;就像prepareStatement关闭了,resultSet也就关闭不可用了。