Batch insert using Native SQL in Hibernate

前端 未结 3 1491
盖世英雄少女心
盖世英雄少女心 2020-12-24 08:51

I want to insert records in database using Hibernate Native SQL.The code is like below

 Session session = sessionFactory.openSession();
 Transaction tx = ses         


        
相关标签:
3条回答
  • 2020-12-24 09:27

    Hibernate have a Batch functionality.But in above case I am using Native SQL,as per my observation hibernate batch is not much effective in case of Native SQL.Yes,surely it avoids the out of memory error but does not improves much performance. Hence I retreated to implemented JDBC Batch in Hibernate.Hibernate provides method doWork() to get Connection from Hibernate Session.

    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    //get Connction from Session
    session.doWork(new Work() {
           @Override
           public void execute(Connection conn) throws SQLException {
              PreparedStatement pstmt = null;
              try{
               String sqlInsert = "insert into sampletbl (name) values (?) ";
               pstmt = conn.prepareStatement(sqlInsert );
               int i=0;
               for(String name : list){
                   pstmt .setString(1, name);
                   pstmt .addBatch();
    
                   //20 : JDBC batch size
                 if ( i % 20 == 0 ) { 
                    pstmt .executeBatch();
                  }
                  i++;
               }
               pstmt .executeBatch();
             }
             finally{
               pstmt .close();
             }                                
         }
    });
    tx.commit();
    session.close();
    
    0 讨论(0)
  • 2020-12-24 09:35

    Here is the same example for Java 8, Hibernate-JPA 2.1:

    @Repository
    public class SampleNativeQueryRepository {
        private final Logger log = LoggerFactory.getLogger(SampleNativeQueryRepository.class);
        @PersistenceContext
        private EntityManager em;
    
        public void bulkInsertName(List<String> list){
            Session hibernateSession = em.unwrap(Session.class);
            String sql = "insert into sampletbl (name) values (:name) ";
            hibernateSession.doWork(connection -> {
                try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
                    int i = 1;
                    for(String name : list) {
                        preparedStatement.setString(1, name);
                        preparedStatement.addBatch();
                        //Batch size: 20
                        if (i % 20 == 0) {
                            preparedStatement.executeBatch();
                        }
                        i++;
                    }
                    preparedStatement.executeBatch();
                } catch (SQLException e) {
                    log.error("An exception occurred in SampleNativeQueryRepository.bulkInsertName: {}", e);
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-12-24 09:51

    If you don't need to worry about SQL injection. i.e you are not getting data from user side then you can do this.

    StringBuilder sqlInsert = new StringBuilder("insert into sampletbl (name) values ");
    for(String name : list){   
        sqlInsert.append("("+name++"),");
    }
    sqlInsert.setLength(sqlInsert.length() - 1);
    session.createSQLQuery( sqlInsert.toString()).executeUpdate();
    

    It will create a query like this.

    insert into sampletbl (name) values ("name1"), ("name2")....
    

    This way your query will run only once and not for each and every item in the list.

    0 讨论(0)
提交回复
热议问题