最近在深入学习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