这两个对象的区别: 1.Statement它更适合执行不同sql的批处理,它没有提供预处理功能,性能比较低。 2.PreparedStatement它适合执行相同的批处理,它提供了预处理功能,属性比较高。 /** * @param args * @throws SQLException * @throws ClassNotFoundException */ public static void main(String[] args) throws ClassNotFoundException, SQLException { // 定义sql 语句 String sql1 = "create table person(id int,name varchar(20))"; String sql2 = "insert into person values(1,‘tom‘)"; String sql3 = "insert into person values(2,‘fox‘)"; String sql4 = "insert into person values(3,‘tony‘)"; String sql5 = "update person set name=‘张三‘ where id=1"; String sql6 = "delete from person where id=3"; Connection conn = jdbcUtils. getConnection(); Statement st = conn.createStatement(); // 添加批处理sql st.addBatch(sql1); st.addBatch(sql2); st.addBatch(sql3); st.addBatch(sql4); st.addBatch(sql5); st.addBatch(sql6); // 执行批处理sql st.executeBatch(); st.clearBatch(); st.close(); conn.close(); } 使用版本高一点的 jdbc的jar包时加入参数可开启缓存在url中加参数: ?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true /** * @param args * @throws SQLException * @throws ClassNotFoundException */ public static void main(String[] args) throws ClassNotFoundException, SQLException { String sqlString = "insert into person values(?,?)"; Connection conn = jdbcUtils. getConnection(); PreparedStatement pst = conn.prepareStatement(sqlString); long l = System. currentTimeMillis(); for ( int i = 0; i < 10000; i ) { pst.setInt(1, i); pst.setString(2, "name" i); pst.addBatch(); if (i % 1000 == 0) { pst.executeBatch(); pst.clearBatch(); // 清空缓存 } } pst.executeBatch(); pst.close(); conn.close(); System. out.println(System. currentTimeMillis() - l); }
方法:
- public static Connection getConnection(){
- try {
- Class.forName( "com.mysql.jdbc.Driver");
- ct = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/test","squirrel","xiaoyang");
- } catch (Exception e) {
- e.printStackTrace();
- }
- return ct;
- }
- /**释放数据库链接资源:注意数据库资源关闭的顺序*/
- public static void closeConnection(){
- try { //注意关闭数据库资源的先后顺序
- if(rs!=null){
- rs.close();
- } if(ps!=null){
- ps.close();
- } if(ct!=null){
- ct.close();
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
测试方法:
- /**
- * PreparedStatement批量执行sql
- */
- public static void excuteBatchInsertDatabase(){
- ct=getConnection();
- try {
- ct.setAutoCommit( false);
- ps=ct.prepareStatement( "insert into user(name,passwd,age,gender) values(?,?,?,?)");
- ps.setString( 1, "BBBB");
- ps.setString( 2, "BBBB");
- ps.setInt( 3, 20);
- ps.setString( 4, "F");
- ps.addBatch();
- ps.setString( 1, "BBBB");
- ps.setString( 2, "BBBB");
- ps.setInt( 3, 20);
- ps.setString( 4, "F");
- ps.addBatch();
- /**
- * 等价于sql语句:
- * insert into user(name,passwd,age,gender) values
- * ("BBBB","BBBB",20,‘F‘),
- * ("BBBB","BBBB",20,‘F‘);
- */
- ps.executeBatch(); //批量执行sql,避免因此单次的insert操作建立多个Connection浪费资源
- ct.commit();
- } catch (Exception e) {
- e.printStackTrace();
- try {
- ct.rollback();
- } catch (SQLException e1) {
- e1.printStackTrace();
- }
- } finally{
- closeConnection();
- }
- }
执行excuteBatchInsertDatabase()方法数据库记录:
数据库数据记录表明:sql语句批量执行成功
注意:
批量查询最好交由一个事务组控制,如果出现操作异常可以进行事务回滚,不至于造成部分数据更新部分数据更新失败的尴尬局面,避免你脏数据污染数据库
- 由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象。因此,多次执行的 SQL 语句经常创建为 PreparedStatement 对象,以提高效率
- Statement用于执行静态的sql语句
-
由于PreparedStatement创建对象消耗资源比较高,所以只执行 一次的sql语句,不使用PreparedStatement
- 主要目的减少执行计划次数,防止sql注入
- jdbc 元数据 meta ,ResultSet.xxx
- Mysql jdbc 关闭自动提交事务 可提升性能 conn.setAutoCommit(false) ,
- 归还conn时 须提前设置为.setAutoCommit(true)
- rollback()回滚
- 批量处理:一次向数据库发送多个SQL语句时,可以减少通信开销,从而提高性能。