最近在深入学习hibernate,在进行批量操作时,发现hibernate批量操作性能非常低。于是就想找一个性能较高的方法,在对jdbc、jdbcTemplate、hibernate进行测试后,发现jdbc的执行效率是最高的,jdbcTemplate也很相近,hibernate就不考虑了,惨不忍睹啊。下面把代码写出来,希望大家批评指正。
首先domain对象。在这里使用的注解的方式,都是比较新的版本。 User.java 1 package com.bao.sample.s3h4.domain; 2 3 import javax.persistence.Column; 4 import javax.persistence.Entity; 5 import javax.persistence.GeneratedValue; 6 import javax.persistence.GenerationType; 7 import javax.persistence.Id; 8 import javax.persistence.Table; 9 10 import com.bao.sample.base.domain.BaseDomain;11 12 @Entity13 @Table(name = “t_user”)14 public class User extends BaseDomain {15 16 private static final long serialVersionUID = 1L;17 private int id;18 private String username;19 private String password;20 21 /**22 * @Description 注解最好标记在get方法上。注意:采用一致的标记方式,注解是以Id的标记方式为准的,如果标记在get方法上,则忽略property上的注解。23 * @return24 */25 @Id26 @GeneratedValue(strategy = GenerationType.IDENTITY)27 public int getId() {28 return id;29 }30 31 public void setId(int id) {32 this.id = id;33 }34 35 @Column(nullable = false)36 public String getUsername() {37 return username;38 }39 40 public void setUsername(String username) {41 this.username = username;42 }43 44 @Column(nullable = false)45 public String getPassword() {46 return password;47 }48 49 public void setPassword(String password) {50 this.password = password;51 }52 53 public User() {54 super();55 }56 57 public User(int id, String username, String password) {58 super();59 this.id = id;60 this.username = username;61 this.password = password;62 }63 64 } 接下来是Dao接口,继承一个BaseDao接口。 UserBatchDao 1 package com.bao.sample.s3h4.dao; 2 3 import java.util.List; 4 5 import com.bao.sample.base.dao.BaseDao; 6 import com.bao.sample.s3h4.domain.User; 7 8 public interface UserBatchDao extends BaseDao<User> { 9 10 /**11 * @Description 批量增加操作12 * @return -1:操作失败;0:执行正常;>0:执行成功的数目13 */14 public int batchAddUsingJdbc(List<User> users);15 16 public int batchAddUsingHibernate(List<User> users);17 18 public int batchAddUsingJdbcTemplate(List<User> users);19 20 } UserBatchDao的实现: UserBatchDaoImpl 1 package com.bao.sample.s3h4.dao; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.SQLException; 6 import java.util.List; 7 8 import javax.annotation.Resource; 9 10 import org.hibernate.Session; 11 import org.springframework.jdbc.core.BatchPreparedStatementSetter; 12 import org.springframework.jdbc.core.JdbcTemplate; 13 import org.springframework.orm.hibernate4.SessionFactoryUtils; 14 import org.springframework.stereotype.Repository; 15 import org.springframework.transaction.annotation.Transactional; 16 17 import com.bao.sample.base.dao.BaseDaoImpl; 18 import com.bao.sample.s3h4.domain.User; 19 20 /** 21 * 22 * @Description 三种批量增加方法,执行效率依次是jdbc、jdbcTemplate、hibernate.<br />jdbc和jdbcTemplate执行效率相近,不过jdbcTemplate可以使用事务注解控制,所以优先选择。 23 * @author Bob 24 * @date 2012-8-13 25 */ 26 @Repository(“userBatchDao”) 27 public class UserBatchDaoImpl extends BaseDaoImpl<User> implements UserBatchDao { 28 29 @Resource 30 protected JdbcTemplate jdbcTemplate; 31 32 /** 33 * 执行10W条记录,大致耗时15188ms 34 */ 35 @Override 36 public int batchAddUsingJdbc(List<User> users) { 37 38 int result = 0; 39 40 Connection conn = null; 41 PreparedStatement pstmt = null; 42 String sql = “insert into t_user (username,password) values (?,?)”; 43 44 try { 45 conn = SessionFactoryUtils.getDataSource(sessionFactory)。getConnection(); 46 conn.setAutoCommit(false); 47 pstmt = conn.prepareStatement(sql); 48 49 for (int i = 0; i < users.size(); i++) { 50 51 int j = 1; 52 pstmt.setString(j++, users.get(i)。getUsername()); 53 pstmt.setString(j++, users.get(i)。getPassword()); 54 pstmt.addBatch(); 55 56 } 57 pstmt.executeBatch(); 58 conn.commit(); 59 conn.setAutoCommit(true); 60 61 } catch (SQLException e) { 62 if (conn != null) { 63 try { 64 conn.rollback(); 65 } catch (SQLException e1) { 66 e1.printStackTrace(); 67 } 68 } 69 } finally { 70 if (pstmt != null) { 71 try { 72 pstmt.close(); 73 } catch (SQLException e) { 74 e.printStackTrace(); 75 } 76 } 77 78 if (conn != null) { 79 try { 80 conn.close(); 81 } catch (SQLException e) { 82 e.printStackTrace(); 83 } 84 } 85 } 86 87 return result; 88 } 89 90 /** 91 * 执行10W条记录,大致耗时131203ms,大致是jdbc或jdbcTemplate的10倍。 92 */ 93 @Override 94 // @Transactional(noRollbackFor = RuntimeException.class) 95 @Transactional 96 pub