Hibernate中,数据批量插入

本文对比了两种Hibernate数据批量插入方法:一种是通过Hibernate API,另一种是直接使用JDBC进行操作。在大数据量的情况下,直接使用JDBC的方法表现更优。

今天试了两种Hibernate数据批量插入:

 

一、通过JDBC的API来进行插入

final List<存入的类别>  list= ....;

 

hibernateTemplate.execute(new HibernateCallback(){

   public Object doInHibernate(Session session)
     throws HibernateException, SQLException {
    int count = 0;
    Transaction ts = session.beginTransaction();

    int count = 0;

   for(Iterator it = list.iterator();it.hasNext();){

        session.save(it.next());

       count ++;

       if(count%50 == 0){

             session.flush();

             session.clear();

       }

   }

ts.commit();

session.close();

return null;

}

});

 

二、路过Hibernate直接通过JDBC来插入

final List<Student> studentList = ...;

 

hibernateTemplate.execute(new HibernateCallback(){

   public Object doInHibernate(Session session)
     throws HibernateException, SQLException {

     Connection conn = session.connection();

     PreparedStatement pst = null;
    String sql = "insert into inf_student (id,name,sex,code) values(?,?,?,?)";

    pst=conn.prepareStatement(sql);
    UUIDHexGenerator uuidGenerator = null;
    int num = studentList.size();
    
    while(num>count){
     for(int i=num;i>(num-count);i--){
      Student student = (Student)studentList.get(i-1);
      uuidGenerator = new UUIDHexGenerator();
      pst.setString(1, uuidGenerator.generate(null, null).toString());
      pst.setString(2, student.getName());
      pst.setString(3, student.getSex());
      pst.setString(4, student.getCode());
      pst.addBatch();
     }
     pst.executeBatch();
     session.flush();
     num -= count;
    }
    if(num>0){
     for(int i=0;i<num;i++){
      InfStudent student = (InfStudent)studentList.get(i);
      uuidGenerator = new UUIDHexGenerator();
      pst.setString(1, uuidGenerator.generate(null, null).toString());
      pst.setString(2, student.getName());
      pst.setString(3, student.getSex());
      pst.setString(4, student.getCode());
      pst.addBatch();
     }
    }
    pst.executeBatch();
    session.flush();
    session.clear();
    return null;
   }

});

 

在数据量较大时,第二种方法比第一种要有较明显的优势,但是第二种写起来要复杂一些,尤其是要插入字段较多时inser 语句sql 和pst Set写起来很麻烦

在使用 Hibernate 进行批量插入数据时,为了提升性能,需要避免 Hibernate 默认的逐条插入行为,转而采用更高效的批量处理机制。以下是一些最佳实践和示例代码。 ### 配置优化 首先,确保在 `hibernate.cfg.xml` 或 `persistence.xml` 中启用批量操作支持。可以配置以下参数: - `hibernate.jdbc.batch_size`:设置批量插入的大小。 - `hibernate.order_inserts` 和 `hibernate.order_updates`:启用批量插入和更新的排序,减少数据库的切换开销。 ```xml <property name="hibernate.jdbc.batch_size" value="50"/> <property name="hibernate.order_inserts" value="true"/> <property name="hibernate.order_updates" value="true"/> ``` ### 使用 Hibernate批量插入示例 在代码中,可以通过 `Session` 接口进行批量插入,并结合事务管理以确保数据一致性。以下是一个简单的批量插入示例: ```java Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); for (int i = 0; i < 1000; i++) { MyEntity entity = new MyEntity("value" + i); session.save(entity); // 每插入一定数量的数据后刷新一次 if (i % 50 == 0 && i != 0) { session.flush(); session.clear(); } } transaction.commit(); session.close(); ``` ### 使用原生 SQL 批量插入 如果需要更高的性能,可以直接使用 JDBC 的 `PreparedStatement` 来执行批量插入操作。这种方式绕过了 Hibernate 的对象状态管理,减少了内存消耗和性能开销。 ```java Session session = sessionFactory.openSession(); Connection connection = session.connection(); connection.setAutoCommit(false); String sql = "INSERT INTO my_table (column1) VALUES (?)"; try (PreparedStatement ps = connection.prepareStatement(sql)) { for (int i = 0; i < 1000; i++) { ps.setString(1, "value" + i); ps.addBatch(); if (i % 50 == 0) { ps.executeBatch(); } } ps.executeBatch(); // 提交剩余的数据 connection.commit(); } catch (SQLException e) { connection.rollback(); } ``` ### 使用多线程提升性能 对于非常大的数据集,可以考虑使用线程池来并行处理数据插入。以下是一个使用 `CompletableFuture` 和线程池的示例: ```java ExecutorService executor = Executors.newFixedThreadPool(4); List<CompletableFuture<Void>> futures = new ArrayList<>(); List<List<MyEntity>> batches = splitDataIntoBatches(allData, 1000); // 数据分片 for (List<MyEntity> batch : batches) { futures.add(CompletableFuture.runAsync(() -> { try (Session session = sessionFactory.openSession()) { Transaction tx = session.beginTransaction(); for (MyEntity entity : batch) { session.save(entity); } tx.commit(); } catch (Exception e) { // 异常处理 } }, executor)); } CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); executor.shutdown(); ``` ### 相关问题 1. Hibernate 中如何配置批量更新的最佳实践? 2. 如何在 Hibernate 中使用缓存机制提升性能? 3. 如何通过 Hibernate 进行高效的批量删除操作? 4. 在 Hibernate 中,如何结合事务管理进行批量操作? 5. 如何使用 Hibernate 的原生 SQL 查询来优化批量操作?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值