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不是一个等级的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值