加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PreparedStatement 批量更新,插入数据到Oracle mysql

发布时间:2020-12-12 14:38:54 所属栏目:百科 来源:网络整理
导读:/** *更新数据库已有的customer信息 *@paramListCustomerBean *@return */ public int updateExistsInfo(ListCustomerBeanupdateList){ //查询的SQL语句 Stringsql= "updatet_customersetLICENSE_KEY=?,CORPORATE_NAME=?,INTEGRATED_CLASSIFICATION=?,BOSSHE
  1. /**
  2. *更新数据库已有的customer信息
  3. *@paramList<CustomerBean>
  4. *@return
  5. */
  6. publicintupdateExistsInfo(List<CustomerBean>updateList){
  7. //查询的SQL语句
  8. Stringsql="updatet_customersetLICENSE_KEY=?,CORPORATE_NAME=?,INTEGRATED_CLASSIFICATION=?,BOSSHEAD=?,"+
  9. "CONTACT_PHONE=?,ORDER_FREQUENCY=?,CONTACT_ADDRESS=?,USER_ID=?whereCUSTOMER_ID=?";
  10. //插入需要的数据库对象
  11. Connectionconn=null;
  12. PreparedStatementpstmt=null;
  13. try{
  14. conn=newDBSource().getConnection();
  15. //设置事务属性
  16. conn.setAutoCommit(false);
  17. pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
  18. for(CustomerBeancbean:updateList){
  19. pstmt.setString(1,cbean.getLicense_key());
  20. pstmt.setString(2,cbean.getCorporate_name());
  21. 3,cbean.getIntegrated_classification());
  22. 4,cbean.getBosshead());
  23. 5,cbean.getContact_phone());
  24. 6,cbean.getOrder_frequency());
  25. 7,cbean.getContact_address());
  26. pstmt.setInt(8,cbean.getUser_id());
  27. pstmt.setInt(9,cbean.getCustomer_id());
  28. pstmt.addBatch();
  29. }
  30. int[]tt=pstmt.executeBatch();
  31. System.out.println("update:"+tt.length);
  32. //提交,设置事务初始值
  33. conn.commit();
  34. conn.setAutoCommit(true);
  35. //插入成功,返回
  36. returntt.length;
  37. }catch(SQLExceptionex){
  38. //提交失败,执行回滚操作
  39. conn.rollback();
  40. }catch(SQLExceptione){
  41. e.printStackTrace();
  42. System.err.println("updateExistsInfo回滚执行失败!!!");
  43. }
  44. ex.printStackTrace();
  45. System.err.println("updateExistsInfo执行失败");
  46. //插入失败返回标志0
  47. return0;
  48. finally{
  49. //关闭资源
  50. if(pstmt!=null)pstmt.close();
  51. if(conn!=null)conn.close();
  52. catch(SQLExceptione){
  53. e.printStackTrace();
  54. System.err.println("资源关闭失败!!!");
  55. /**
  56. *插入数据中没有的customer信息
  57. *@paramList<CustomerBean>
  58. *@return
  59. */
  60. intinsertNewInfo(List<CustomerBean>insertList){
  61. Stringsql="insertintot_customer(CUSTOMER_ID,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> "LICENSE_KEY,CORPORATE_NAME,INTEGRATED_CLASSIFICATION,BOSSHEAD,CONTACT_PHONE,"+
  62. "ORDER_FREQUENCY,CONTACT_ADDRESS,USER_ID,CUSTOMER_NUM,CUSTOMER_CODING,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> "INVESTIGATION_TIME,SMS_REC_FLAG,WAP_FLAG,PRICE_GATHERING_FLAG,SOCIETY_STOCK_FLAG,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> "REGION_TYPE)"+
  63. "VALUES(CUSTOMER.NEXTVAL,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> "?,?,108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> "?,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> "TO_DATE(?,'YYYY-MM-DD'),108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> "?)";
  64. //插入需要的数据库对象
  65. Connectionconn= PreparedStatementpstmt=try{
  66. conn=newDBSource().getConnection();
  67. pstmt=conn.prepareStatement(sql,ResultSet.CONCUR_READ_ONLY);
  68. for(CustomerBeancbean:insertList){
  69. "gyyc00000");//
  70. 10,"95000000");//
  71. 11,getToday());
  72. 12,cbean.getSms_rec_flag());
  73. 13,cbean.getRegion_type());
  74. pstmt.addBatch();
  75. int[]tt=pstmt.executeBatch();
  76. System.out.println("insert:"+tt.length);
  77. //提交,设置事务初始值
  78. conn.commit();
  79. true);
  80. //插入成功,返回
  81. returntt.length;
  82. catch(SQLExceptionex){
  83. //提交失败,执行回滚操作
  84. conn.rollback();
  85. System.err.println("insertNewInfo回滚执行失败!!!");
  86. ex.printStackTrace();
  87. System.err.println("insertNewInfo执行失败");
  88. //插入失败返回标志0
  89. 0;
  90. finally{
  91. //关闭资源
  92. null)pstmt.close();
  93. null)conn.close();
  94. System.err.println("资源关闭失败!!!");
  95. }
使用Java JDBC基本的API批量插入数据到数据库中
  1. importjava.sql.Connection;
  2. importjava.sql.Statement;
  3. //...
  4. Connectionconnection=newgetConnection();
  5. Statementstatemenet=connection.createStatement();
  6. for(Employeeemployee:employees){
  7. Stringquery="insertintoemployee(name,city)values('"
  8. +employee.getName()+"','"+employee.getCity+"')";
  9. statemenet.addBatch(query);
  10. }
  11. statemenet.executeBatch();
  12. statemenet.close();
  13. connection.close();
  14. 请注意我们是如何从Employee对象中的数据动态创建查询并在批处理中添加,插入一气呵成。完美!是不是?
    等等......你必须思考什么关于SQL注入?这样动态创建的查询SQL注入是很容易的。并且每个插入查询每次都被编译。
    为什么不使用PreparedStatement而不是简单的声明。是的,这是个解决方案。下面是SQL注入安全批处理。
    SQL Injection Safe Batch - SQL注入安全批处理
    思考一下下面代码:
    [java] view plain copy
    1. importjava.sql.Connection;
    2. importjava.sql.PreparedStatement;
    3. //...
    4. Stringsql="insertintoemployee(name,city,phone)values(?,?)";
    5. Connectionconnection=newgetConnection();
    6. PreparedStatementps=connection.prepareStatement(sql);
    7. for(Employeeemployee:employees){
    8. ps.setString( ps.setString(
    9. ps.addBatch();
    10. }
    11. ps.executeBatch();
    12. ps.close();
    13. connection.close();
    看看上面的代码。漂亮。我们使用的java.sql.PreparedStatement和在批处理中添加INSERT查询。这是你必须实现批量插入逻辑的解决方案,而不是上述Statement那个。
    这一解决方案仍然存在一个问题。考虑这样一个场景,在您想要插入到数据库使用批处理上万条记录。嗯,可能产生的OutOfMemoryError:
    java.lang.OutOfMemoryError: Java heap space
    com.mysql.jdbc.ServerPreparedStatement$BatchedBindValues.<init>(ServerPreparedStatement.java:72)
    com.mysql.jdbc.ServerPreparedStatement.addBatch(ServerPreparedStatement.java:330)
    org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:171)

    这是因为你试图在一个批次添加所有语句,并一次插入。最好的办法是将执行分批次。看看下面的解决方案
    Smart Insert: Batch within Batch - 智能插入:将整批分批
    这是一个简单的解决方案。考虑批量大小为1000,每1000个查询语句为一批插入提交。
    copy
      Stringsql="insertintoemployee(name,?)";
    1. newgetConnection();
    2. PreparedStatementps=connection.prepareStatement(sql);
    3. finalintbatchSize=1000;
    4. intcount=0;
    5. for(Employeeemployee:employees){
    6. ps.addBatch();
    7. if(++count%batchSize==0){
    8. ps.executeBatch();
    9. }
    10. ps.executeBatch();//insertremainingrecords
    11. connection.close();
    这才是理想的解决方案,它避免了SQL注入和内存不足的问题。看看我们如何递增计数器计数,一旦BATCHSIZE 达到 1000,我们调用executeBatch()提交。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读