`

hibernate 批量插入的测试

阅读更多

Hibernate 批量插入的测试:
最近在项目中做了一个充值卡的模块,用到了批量插入:我一开始用hibernate插入五十万条数据:选说一下我的记算机配置:
内存:1G,CPU:Pentium(R) 4 CPU 3.20GHz. 配置应该算是过时的了,
我的数据库是:oracle10G,数据库服务器在外地,我测试插入到十万条的时候用了二十五分钟,后来我把程序放到外网服务器:配置:酷睿2代 2.0,4G内存,
插入十万条是五分钟,速试是大大的提升,但是我还是感觉有点慢,后来我用JDBC的批处理:还是在我本地插入:10万条用时:不到1分钟,如果放到外网服务器就更快。
下面贴一下我的代码:hibernate批量导入代码:(只是部分代码,不能运行。)
 public boolean addCardList( final SysCardImport sysCardImport,final Date date){
  boolean bool =(Boolean) hibernateTemplate.execute(new HibernateCallback() {
   public Object doInHibernate(Session session) throws HibernateException, SQLException {
   boolean flag=true;
   try {  
    int i=0;
    
    String temp=sysCardImport.getCardSymbol();  //卡代号
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    //取得充值卡类型值和面额值
    SysPublictype cardType = (SysPublictype)session.get(SysPublictype.class, sysCardImport.getCardType());
    SysPublictype cardMoney = (SysPublictype)session.get(SysPublictype.class, sysCardImport.getCardMoney());
    temp+=cardType.getVchvalue();
    temp+=cardMoney.getVchvalue();
    
    String templeng[]=sysCardImport.getPasswordChar();
    for(int len=0;len<templeng.length;len++){   //循环遍历充值卡加密字符串
     String temparray[]=templeng[len].split(":");     
     String temps=temp+temparray[0]; //加密字符串代码
     long cardnum=0;
     List list= session.createQuery(" from SysCard t where t.vchcode like ? order by t.vchcode desc")
        .setString(0, ""+temps+"%").list();
     if(list.size()>0){
      SysCard card=(SysCard)list.get(0);
      cardnum = Long.valueOf(card.getVchcode().substring(10));
     }
     for(int num=0;num<sysCardImport.getCardAmount();num++){ //生成充值卡卡号
      String cardroand="000000000"+(++cardnum);
      cardroand=cardroand.substring(cardroand.length()-10);     
      SysCard sysCard=new SysCard();
      SysPassword sysPassword=new SysPassword();
      
      String password=BJFYSystemUtil.getRandomString(sysCardImport.getCardPasswordLength(),2);
      
      sysCard.setVchcode(temps+cardroand);
      sysCard.setNummoney(sysCardImport.getCardMoneys());
      sysCard.setCstate("10");
      sysCard.setDatcreate(date);
      sysCard.setDatavailability(sdf.parse(sysCardImport.getCardDate()));
      sysCard.setVchremark(sysCardImport.getCardRemark());
      sysCard.setVchpassword(BJFYSystemUtil.getMD5(password+temparray[1]));
      sysCard.setNumscale(sysCardImport.getCardScale());
      sysCard.setVarkey(temparray[1]);
      sysCard.setVchtype(cardType.getId());
      
      sysPassword.setVchcode(temps+cardroand);
      sysPassword.setVchpassword(password);
      sysPassword.setVchpasschar(temparray[1]);
      session.save(sysPassword);
      session.save(sysCard);
      if ((i + 1) % 1000 == 0) {
       session.flush();
       session.clear();
      }
      i++;
     }
    }
    
   } catch (Exception e) {
    log.error(e);
    e.printStackTrace();
    flag = false;
   }
   return flag;
  }
 });
  return bool;
 }
下面是JDBC批处理的代码:
public boolean addCardListByJdbc( final SysCardImport sysCardImport,final Date date){
   boolean flag=true;
   Connection con= this.hibernateTemplate.getSessionFactory().openSession().connection();
   PreparedStatement  stm=null;
   PreparedStatement  stm2=null;
   try {  
    int i=0;
    String temp=sysCardImport.getCardSymbol();  //卡代号
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    //取得充值卡类型值和面额值
    SysPublictype cardType = (SysPublictype)hibernateTemplate.get(SysPublictype.class, sysCardImport.getCardType());
    SysPublictype cardMoney = (SysPublictype)hibernateTemplate.get(SysPublictype.class, sysCardImport.getCardMoney());
    temp+=cardType.getVchvalue();
    temp+=cardMoney.getVchvalue();
    
    con.setAutoCommit(false);
          
    stm=con.prepareStatement("insert into sys_card values(?,?,?,?,?,?,?,?,?,?)");
    stm2=con.prepareStatement("insert into sys_password values(?,?,?)");
    
    String templeng[]=sysCardImport.getPasswordChar();    
    for(int len=0;len<templeng.length;len++){   //循环遍历充值卡加密字符串
     String temparray[]=templeng[len].split(":");     
     String temps=temp+temparray[0]; //加密字符串代码
     long cardnum=0;
     List list= hibernateTemplate.find(" from SysCard t where t.vchcode like ? order by t.vchcode desc", temps+"%");
        
     if(list.size()>0){
      SysCard card=(SysCard)list.get(0);
      cardnum = Long.valueOf(card.getVchcode().substring(10));
     }
     
     for(int num=0;num<sysCardImport.getCardAmount();num++){ //生成充值卡卡号
      String cardroand="000000000"+(++cardnum);
      cardroand=cardroand.substring(cardroand.length()-10);     
      SysCard sysCard=new SysCard();
      SysPassword sysPassword=new SysPassword();      
      String password=BJFYSystemUtil.getRandomString(sysCardImport.getCardPasswordLength(),2);
      
      
      
      
      stm.setString(1,temps+cardroand);
      stm.setString(2, BJFYSystemUtil.getMD5(password+temparray[1]));
      stm.setLong(3, sysCardImport.getCardMoneys());
      stm.setLong(4, sysCardImport.getCardScale());
      stm.setString(5,cardType.getId() );
      stm.setDate(6, new java.sql.Date(System.currentTimeMillis()));
      stm.setDate(7, new java.sql.Date(date.getTime()));
      stm.setString(8, "10");
      stm.setString(9, temparray[1]);
      stm.setString(10, sysCardImport.getCardRemark());
      stm.addBatch();

      stm2.setString(1, temps+cardroand);
      stm2.setString(2, password);
      stm2.setString(3,temparray[1]);
      stm2.addBatch();
      if ((i + 1) % 1000 == 0) {
       stm.executeBatch();
       stm2.executeBatch();
       con.commit();
      }
      i++;
     }
    }
    
    if(stm!=null) {
     stm.executeBatch();
     stm2.executeBatch();
     con.commit();
    }
    
    
   } catch (Exception e) {
    log.error(e);
    e.printStackTrace();
    flag = false;
   }finally{
    try {
     con.close();
     stm=null;
     stm2=null;
    } catch (SQLException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    
   }
  
  
  return flag;
 }

综上所述,hibernate的批量更新和插入要创建和销毁大量的对象,尤其是带有复杂业务逻辑的,所以本人建议在大批量导入和更新时,最好使用JDBC的批处理.在批处理上hibernate和jdbc Batch不是一个等级的。

分享到:
评论
2 楼 genius 2008-12-17  
不知道你的HQL语句怎么写的,你可以发出来看看
1 楼 yuansheng_521 2008-11-21  
楼住可否把详细代码发给我看一下
我的是spring+hibernate+tomcat+sqlserver
我在插入数据时是查询一个表的数据,插入到另一个表!
速度开始在6条/秒
大约在7000多条时
速度明显下降
………………能帮我解释下原因么??
我邮箱42369832@qq.com

相关推荐

    hibernate-batch-size-test:Hibernate hibernate.jdbc.batch_size 测试

    Hibernate hibernate.jdbc.batch_size 测试带有 MySQL JDBC 驱动程序的 Hibernate 批量插入示例。 에 관한 설명

    Hibernate+中文文档

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    hibernate3.2中文文档(chm格式)

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    HibernateAPI中文版.chm

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    Hibernate中文详细学习文档

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    Hibernate 中文 html 帮助文档

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1. 大小...

    hibernate 体系结构与配置 参考文档(html)

    批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1. 大小...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1....

    Struts2项目综合案例

    其中dataInsert.sql是建表、视图sql,存储过程是批量插入测试数据,具体注意事项请看readme.txt文件。本压缩包仅有源代码和配置文件,相关运行的jar包需自己调式加入,如有问题,请发邮件或加我MSN:yetree@hotmail....

    Hibernate参考文档

    13.1. 批量插入(Batch inserts) 13.2. 批量更新(Batch updates) 13.3. StatelessSession (无状态session)接口 13.4. DML(数据操作语言)风格的操作(DML-style operations) 14. HQL: Hibernate查询语言 14.1. 大小...

    orm-compare:Java ORM工具(Hibernate,MyBaits,Bee)与select进行比较,更新插入。 您想要哪个功能?

    测试点:批量插入;选择分页; 交易(更新并选择)。 批量插入(单位:毫秒) 5千 1瓦 2w 5瓦 10瓦 蜜蜂 880 720 620 1420 4700 蜜蜂 359 358 484 1248 4000 蜜蜂 348 297 546 1279 3470 (AVG)...

    Spring.3.x企业应用开发实战(完整版).part2

    11.3.3 插入Lob类型的数据 11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和行集 11.4.1 自增键的使用 11.4.2 如何规划主键方案 11.4.3 以行集返回数据 11.5 其他类型的JDBCTemplate ...

    Spring3.x企业应用开发实战(完整版) part1

    11.3.3 插入Lob类型的数据 11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和行集 11.4.1 自增键的使用 11.4.2 如何规划主键方案 11.4.3 以行集返回数据 11.5 其他类型的JDBCTemplate ...

    JdbcTemplateTool.zip

    创建一张表employee插入一些测试数据.DROP TABLE IF EXISTS `employee`; CREATE TABLE `employee` (  `id` int(11) NOT NULL,  `name` varchar(300) NOT NULL,  `join_date` datetime NOT NULL,...

    Spring中文帮助文档

    11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用SimpleJdbcInsert来获取自动生成的主键 11.5.3. 指定SimpleJdbcInsert所使用的字段 11.5.4. 使用SqlParameterSource提供参数值 11.5.5. 使用SimpleJdbcCall...

    Spring API

    11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用SimpleJdbcInsert来获取自动生成的主键 11.5.3. 指定SimpleJdbcInsert所使用的字段 11.5.4. 使用SqlParameterSource提供参数值 11.5.5. 使用SimpleJdbcCall...

    iBATIS实战

    11.1.1 Hibernate版本的DAO实现 194 11.1.2 JDBC版本的DAO实现 199 11.2 为其他数据源使用DAO模式 203 11.2.1 示例:为LDAP使用DAO 203 11.2.2 示例:为Web服务使用DAO 208 11.3 使用Spring DAO 209 11.3.1 编写代码...

    SqlToolBox 1.8.2

    用户能自动快速获取单表的创建,查询,更新,删除,建表语句,整表全部数据插入语句,单表对应Pojo类和单表的Hibernate映射文件等常用文字,且可借此构造更复杂的Sql语句。 4. 能执行Sql语句并显示执行结果,如果是...

Global site tag (gtag.js) - Google Analytics