`
yinwufeng
  • 浏览: 287191 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ibatis +spring ,hibernate 批量操作

阅读更多

[转]ibatis +spring ,hibernate 批量操作


 

程序功能:
使用ibatis+spring将oracle数据库中的tfile表中的数据抽取到db2数据库的tfile表,这两个表的结构相同。

测试环境:
celeron M 1.4/512M/mysql 5.0数据库
代码:

public   static   void  main(String[] args)  {
        
//  TODO Auto-generated method stub
        ClassPathResource resource  =   new  ClassPathResource(
                
" applicationContext.xml " );
        BeanFactory factory 
=   new  XmlBeanFactory(resource);
        TFileDAO tFileDao 
=  (TFileDAO) factory.getBean( " tfile " );

        TFileDAO test2FileDao 
=  (TFileDAO) factory.getBean( " test2tfile " );
        
// 获取全部数据
        List list  =  tFileDao.getAll();
        
// 开启事务
        DataSourceTransactionManager txm  =  (DataSourceTransactionManager) factory
                .getBean(
" test2transactionManager " );
        DefaultTransactionDefinition def 
=   new  DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status 
=  txm.getTransaction(def);
        
try   {
            test2FileDao.getSqlMapClient().startBatch();
            
for  ( int  i  =   0 , count  =  list.size(); i  <  count; i ++ {
            
// 插入数据
                test2FileDao.insert((TFile) list.get(i));
            }

            test2FileDao.getSqlMapClient().executeBatch();// 这两句有问题,请见Spring+ibatis心得2!
        }
  catch  (Exception e)  {
            txm.rollback(status);
            System.out.println(e);
        }

        txm.commit(status);
        System.out.println(list.size());
    }
1、保证使用长事务,不要在每个插入都事务提交,这样性能可以有很大幅度的提升
2、使用 test2FileDao.getSqlMapClient().startBatch();
              test2FileDao.getSqlMapClient().executeBatch();
             可以发起jdbc对批量数据插入的优化与自动代码压缩功能。

      结 语:这次使用ibatis在同样的硬件、数据库、数据条数的环境下测试,在不起用batch,所有数据库,数据池特性均使用默认设置情况下使用19秒,并 且使用一次性将数据读入内存的方式,效果优于hibernate,所以真信优化后的程序应该比hibernate效率更高。但是从程序编写方面来 讲,hibernate省去了过多的代码,可以让程序员更轻松些。
 
1、上回的心得中我强调了startBatch()的批处理的作用,但是其中的使用是个错误用法,并没有发挥出startBatch()的实力,对此给与观众的误导我将在此表示到欠,并贴出正确的用法
public   class  LocalDaoImpl  extends  SqlMapClientDaoSupport  implements  LocalDao  {

    
public   void  insertBuNaTaxBatLst( final  PaginatedList list)
    
{
         getSqlMapClientTemplate().execute(
new  SqlMapClientCallback()  {
                
public  Object doInSqlMapClient(SqlMapExecutor executor)
                        
throws  SQLException  {
                    executor.startBatch();
                    
//  do some iBatis operations here
                     for ( int  i = 0 ,count = list.size();i < count;i ++ )
                    
{    
                        executor.insert(
" insertBuNaTaxBatLst " , list.get(i));
                        
if  (i  %   50   ==   0 {
                            System.out.println(
" ---- "   +  i);//没有意义只为测试
                        }

                    }

                    executor.executeBatch();
                    
return   null ;
                }

            }
);
    }


}

这样才能利用上startBatch()威力。
2、注意ibatis的事物默认情况下是自动提交的,如果发现速度上有问题可以留意一下,ibatis只有在显示的声明事物管理的情况下才自动将事物管理改为不自动方式。
3、 还是startBatch(),据我测试分析这个鬼东西只有在executeBatch(),才把所有的语句提交到数据库,在提交之前缓存中保留了大量的 sql语句和数据对象,很有可能out of memony,对此要留意,可以在大量数据要做插入时,分批用Batch,如:有40000条数据可将其分为4个Batch块,让后将这4个Batch用 一个事物提交以保证数据完整性。
注:最近在做数据抽取项目,愿与大家沟通心得

  到一个这东西都写到3了,针对上回说到30000条数据的批量插入工作。30000条数据的批量插入在一个事务里处理固然是快,但是这只是测试环 境,30000条数据在数据库的缓存里必然对数数据库的缓存和锁数量都是一个大的挑战,固在新的程序中我们使用了分批事务提交的方式,这样为了保持数据的 正确行就只能人为控制数据库中已被插入的数据是否delete掉。另外,使用Batch块提交会引发一个问题就是,如果batch块中发生了异常,我们得 不到异常数据的行号即任何信息,所以只能是鱼和熊掌不可兼得(我已关注过insert方法中返回pk的方法了,但好像在batch中他反回不了出错的行 号,也许是我没有找到方法,如有人有好方法请共享一下,在这里表示感谢),大家酌情考虑吧,只能到到自己需要的平衡点了。
      建议:如果 对数据的准确性毋庸置疑的话就是用batch处理。如果不能确定准确性的话,如果对那条数据出错无所谓的话就也可以用batch,但是非要返回出错行号的 话就不要用batch了,直接在外面套用一个事务,然后try catch一下,处理一下行号。

========================================

程序功能:
使用hibernate+spring将oracle数据库中的tfile表中的数据抽取到db2数据库的tfile表,这两个 表的结构相同。(原本要使用一些Spring的特性,但是程序改来改去发现Spring特性一个都没用上,实际上完全可以由hibernate创建两个 sessionFactory完成)
测试环境:
celeron M 1.4/512M/mysql 5.0数据库
代码:

public   void  save()  {
  Session session
=  fileDAO.getDataSession();
  Session session2
=  fileDAO2.getDataSession();
  Transaction tx 
= session2.beginTransaction();
  
int  count = 0 ;
  List list 
= fileDAO.getList(session, count);
  
while (list.size() != 0 )
  
{
   
for ( int  i = 0 ,num  = list.size();i < num;i ++ )
   
{
    session2.save(list.get(i));
    session.evict(list.get(i));
    
if (num % 50 == 0 )
    
{
     session2.flush();
     session2.clear();
    }

   }

   count
=  count + 500 ;
   list 
= fileDAO.getList(session, count);
   
  
//  System.out.println(count);
   
  }

  tx.commit();
  session.close();
  session2.close();
}

配置文件:

< prop  key ="hibernate.jdbc.batch_size" > 50 </ prop >
< prop  key ="hibernate.cache.use_second_level_cache" > false </ prop >

1、为保证不会出现内存溢出
   hibernate.jdbc.batch_size 设为 20-50
   并在代码中没隔50个insert后手工清理数据

  if (num % 50 == 0 )
    
{
     session2.flush();
     session2.clear();
    }

2、为保证减少二级缓存导致的过多的内存开销关,闭二级缓存
  hibernate.cache.use_second_level_cache 设为false
3、保证使用长事务,不要在每个插入都事务提交,这样性能可以有很大幅度的提升(由于原先配的事务没有正常运行,在初次测试时此程序插入4万条数据用了12分钟,使用了长事务后仅为34秒)
4、 使用ScrollableResults(提供了数据库的游标特性)然后插入的效果好像要优于分批抓取分批插入的效果,(4万条数据,用 ScrollableResult耗时29秒)但网上有人声称批量抓取插入的效果要好可能在远程数据库的情况下批量抓取的可靠性更高一点的原因。这一点我 询问过公司里做数据库比较好的人,批量处理数据是要使用游标处理的。就游标而言分为动态游标,静态游标,动态游标慢于静态游标,静态游标慢于静态查询,但 是如果用分批抓取数据的话就涉及到数据分段截取,为保证每次分段截取时数据的正确性,应该要预先对数据处理,所以批量抽取数据的速度可能会慢一些。以下为 使用ScrollableResult的程序

Session session =  fileDAO.getDataSession();
  Session session2
=  fileDAO2.getDataSession();
  Transaction tx 
= session2.beginTransaction();
  ScrollableResults tFiles 
=  session.createQuery(
    
" from TFile as model  " ).setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);
  
int  count = 0 ;
  
while (tFiles.next())
  
{
   session2.save(tFiles.get(
0 ));
   
if ( ++ count % 50 == 0 )
    
{
     session2.flush();
     session2.clear();
    }

  }

  tx.commit();
  session.close();
分享到:
评论

相关推荐

    Ibatis中文版教程

    iBatis与Hibernate、JDO或EJB等框架有所不同,它更轻量级,专注于POJO(Plain Old Java Object,普通的Java对象)的持久化,并允许开发者直接使用SQL语句和存储过程进行数据库操作。 ### 一、iBatis基础概念 #### ...

    ibatis 开发指南 2004

    14. **与其他框架集成**:探讨如何将iBatis与Spring、Hibernate等其他框架集成,构建更强大的企业级应用。 这本指南对于初学者和有经验的开发者来说都是宝贵的资源,它帮助读者理解iBatis的工作原理,掌握其核心...

    spring面试题.doc

    7. **Spring与Ibatis整合**:整合过程通常涉及配置Spring的XML文件,定义SqlSessionFactory,配置数据源,以及配置Mapper接口和XML映射文件。 8. **声明式事务管理**:Spring通过`&lt;tx:annotation-driven&gt;`标签启用...

    iBATIS实战

    11.3.2 为什么使用Spring代替iBATIS 211 11.4 创建自己的DAO层 211 11.4.1 从实现中分离出接口 212 11.4.2 创建一个工厂以解耦 212 11.5 小结 214 第12章 扩展iBATIS 215 12.1 理解可插拔组件的设计 215 12.2 使用...

    iBatis教程中文版

    g firstName) { this.firstName = firstName; } public String getLastName() { ...在实际的企业开发中,结合Spring等框架使用,可以构建出稳定可靠的SS(Spring + iBatis)或SSH(Spring + Struts + Hibernate)架构。

    spring2.0 中文教程

    3. **数据访问集成**:Spring 2.0增强了对各种持久层技术的支持,包括JDBC、Hibernate、iBatis等。它提供了一致的编程模型和事务管理策略,简化了数据库操作。 4. **Web MVC框架**:Spring 2.0的Web MVC框架提供了...

    IBatis框架

    作为一个轻量级的框架,IBatis 提供了数据库操作的灵活性,使得开发者能够将 SQL 查询与 Java 代码直接结合,避免了传统的 ORM(对象关系映射)框架如 Hibernate 的复杂性。它允许开发者直接编写 SQL,从而更好地...

    ibatis开发指南

    相对于全自动化的一站式ORM(对象关系映射)解决方案如Hibernate和Apache OJB,iBATIS提供了一种半自动化的策略,使得开发者在数据库操作上拥有更高的灵活性和控制权。 描述中提到,iBATIS不同于“一站式”ORM解决...

    Spring Framework 2.0开发参考手册(中文版chm)

    在数据访问集成方面,Spring提供了对各种持久层技术的支持,如JDBC、Hibernate、iBatis和JPA等。Spring的JdbcTemplate和HibernateTemplate提供了简洁的API,用于执行数据库操作,同时降低了与数据库交互的复杂性。...

    ibatis帮助文档

    Ibatis是由Clinton Begin创建的,它摒弃了传统的Hibernate对象关系映射的复杂性,允许开发者直接编写SQL语句,同时提供了动态SQL的支持,提高了开发效率。Ibatis的目标是使SQL和Java代码更好地结合,通过XML或注解的...

    spring-framework-2.0.6-with-dependencies.zip

    4. **数据访问支持**:Spring对各种数据库访问技术提供了支持,包括JDBC、Hibernate、iBatis等ORM框架,使得数据库操作更为方便。 5. **国际化支持**:Spring提供了强大的国际化(i18n)支持,通过ResourceBundle和...

    ibatis2讲义

    尽管Hibernate等全功能ORM框架提供了丰富的功能,但在某些特定场景下,IBATIS表现出更多的灵活性和性能优势: - **安全性需求**:当开发团队只能访问有限的SQL查询或存储过程时,IBATIS允许开发者直接编写这些查询...

    spring in action 2.0

    3. **数据访问集成**:Spring 2.0增强了对各种持久化技术的支持,包括JDBC、ORM(如Hibernate、iBatis)和OXM(Object-XML Mapping)。这使得开发者可以轻松地在不同持久化策略之间切换,提高了代码的可重用性。 4....

    Spring中文帮助文档

    11.4.2. 使用SimpleJdbcTemplate进行批量操作 11.5. 通过使用SimpleJdbc类简化JDBC操作 11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用SimpleJdbcInsert来获取自动生成的主键 11.5.3. 指定SimpleJdbcInsert...

    Spring API

    11.4.2. 使用SimpleJdbcTemplate进行批量操作 11.5. 通过使用SimpleJdbc类简化JDBC操作 11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用SimpleJdbcInsert来获取自动生成的主键 11.5.3. 指定SimpleJdbcInsert...

    Spring教程

    Spring提供了与多种持久层技术的集成,如JDBC、ORM框架(Hibernate、iBatis等)。它通过数据源、事务管理以及DAO(Data Access Object)模板类等,简化了数据库操作。Spring的声明式事务管理使得事务处理代码不再...

    Spring PPT文档

    4. **对象/关系映射(ORM Module)**:Spring集成了多种ORM框架,如JDO、Hibernate和iBatis,使得开发者能将这些ORM技术与Spring的其他功能(如事务管理)结合使用,提高了代码的可维护性和可测试性。 5. **面向切面...

    spring2.0技术手册.rar

    在数据访问/集成方面,Spring支持多种数据库访问技术,包括JDBC、Hibernate、iBatis等ORM框架,以及JPA。它提供了一种统一的API,使得在不同的持久化技术之间切换变得更加容易。此外,Spring还提供了事务管理服务,...

    java crm管理系统

    虽然Hibernate和iBatis提供了更高级的抽象,但在某些特定的数据库操作中,如批量更新或复杂事务控制,开发者可能直接使用JDBC来获取更高的控制权。 5. **EXT标签**:EXT通常指的是EXT JS,这是一个用于构建富客户端...

    SSI电子书

    Spring JDBC和Hibernate等ORM工具集成,简化了数据库操作。Spring还提供了事务管理、安全控制、消息服务等多种企业级功能,是一个全面的开发平台。 这三本书籍的PDF资源分别涵盖了Spring、Struts2和iBatis的开发...

Global site tag (gtag.js) - Google Analytics