`
laorer
  • 浏览: 433663 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

阅读更多
 
 
http://www.blogjava.net/zp0127/default.html?page=2
 

程序功能:
使用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();
分享到:
评论

相关推荐

    Struts2+Spring+Hibernate和Struts2+Spring+Ibatis

    Struts2+Spring+Hibernate和Struts2+Spring+Ibatis是两种常见的Java Web应用程序集成框架,它们分别基于ORM框架Hibernate和轻量级数据访问框架Ibatis。这两种框架结合Spring,旨在提供一个强大的、可扩展的、易于...

    struts2+spring+ibatis+mysql

    "Struts2+Spring+Ibatis+MySQL" 是一个经典的Java Web开发框架组合,用于构建高效、可扩展的企业级应用程序。这个组合集成了强大的MVC(Model-View-Controller)框架Struts2、依赖注入与面向切面编程的Spring框架、...

    Struts2+iBATIS+Spring整合

    Struts2+iBATIS+Spring整合是Java Web开发中一种常见的技术栈组合,这三种框架协同工作,可以构建出高效、灵活的企业级应用。Struts2作为MVC(Model-View-Controller)架构的一部分,主要负责处理HTTP请求,管理前端...

    ibatis+Spring demo

    内容包里面是源代码,运行该例子的方式就是,使用里面的sql...使用cmd进入该解压包,运行 java -jar *.jar ibatis2spring.jar 就可以了。欲了解代码的详细,请访问作者博客,搜索《ibatis + Spring 多表查询》文章。

    compass+ibatis+spring+struts2整合开发

    compass+ibatis+spring+struts2整合开发compass+ibatis+spring+struts2整合开发compass+ibatis+spring+struts2整合开发compass+ibatis+spring+struts2整合开发

    Struts2-Ibatis+spring.rar

    Struts2-Ibatis+spring.rar Struts2-Ibatis+spring.rar Struts2-Ibatis+spring.rar Struts2-Ibatis+spring.rar Struts2-Ibatis+spring.rar

    struts2+ibatis+spring 安例

    Struts2、iBatis和Spring是Java Web开发中非常重要的三个框架,它们共同构建了一个高效、灵活的应用架构。这个实例结合了这三个框架,旨在帮助开发者理解如何将它们整合在一起,提升开发效率。 Struts2作为MVC...

    ibatis+spring+struts2 整合开发例子

    "ibatis+spring+struts2 整合开发例子"就是一个典型的Java Web应用集成开发案例,旨在帮助开发者理解和掌握这三大框架的协同工作原理。接下来,我们将详细讨论这三个组件以及它们的整合过程。 Ibatis是一个轻量级的...

    oa_权限系统ibatis+spring+struts2

    oa_权限系统ibatis+spring+struts2 oa_权限系统ibatis+spring+struts2 oa_权限系统ibatis+spring+struts2

    Ibatis+Spring+struts1框架搭建

    【标题】:Ibatis+Spring+Struts1框架搭建 在Web开发中,Ibatis、Spring和Struts1是三个非常重要的组件,它们分别负责不同的职责。Ibatis是一个优秀的持久层框架,Spring是一个全面的后端应用框架,而Struts1则是一...

    springMVC+ibatis+hibernate+spring+boostrap框架

    控制器通过 Spring 的 DI 获取服务层对象(可能包含了 Hibernate 或 iBatis),执行业务逻辑和数据操作;最后,结果通常被渲染成 HTML,Bootstrap 的样式使得页面在不同设备上都能良好显示。 总结来说,Spring MVC ...

    ibatis+Spring+struts2整合实例

    本实例关注的是“ibatis+Spring+struts2”的整合,这是一个经典的Java Web开发组合,用于实现数据访问、业务逻辑控制和用户界面交互。下面我们将深入探讨这三个组件及其整合的关键知识点。 1. **iBATIS**:iBATIS...

    struts2+hibernate+spring+ibatis 小实例

    struts2+hibernate+spring+ibatis 小实例struts2+hibernate+spring+ibatis 小实例struts2+hibernate+spring+ibatis 小实例struts2+hibernate+spring+ibatis 小实例struts2+hibernate+spring+ibatis 小实例struts2+...

    struts2+hibernate+spring+ibatis+ext整合

    这个框架主要struts2+hibernate+spring+ibatis+ext整合,不要说hibernate和ibatis整合是多此一举哦,当你想用hibernate时把ibatis取了,用ibatis时把hibernate取了就可以了,这样很方便的!

    ibatis+spring+struts

    在IT行业中,集成框架是构建复杂企业级应用的常用手段,而"Ibatis+Spring+Struts"就是一个经典的Java Web开发组合,也被称作SSM框架。这个框架集合了Struts的MVC设计模式、Spring的依赖注入和事务管理以及Ibatis的...

    struts2+spring+ibatis+jquery ajax的登陆注册实时验证

    Struts2、Spring、iBatis和jQuery AJAX是Java Web开发中的四大核心技术,它们共同构建了一个功能强大的MVC(模型-视图-控制器)架构。本文将深入探讨这些技术在登录注册系统中的应用。 首先,Struts2是Apache基金会...

    Ibatis+Spring+struts完整代码案例

    【Ibatis+Spring+Struts整合详解】 Ibatis、Spring和Struts是Java Web开发中的三大框架,它们各自负责不同的职责,共同构建了一个强大的企业级应用框架。Ibatis作为持久层框架,处理数据库操作;Spring提供了依赖...

    struts2+ibatis+spring+Hessian 整合项目

    struts2+ibatis+spring+Hessian 整合项目 web项目整合,服务端用hessian协议远程调用服务端的方法,hessian是用spring代理整合,struts2+ibatis+spring的整合项目,用作学习和开发基础平台构建很有用处,工程导入...

    backbone+bootstrap+ibatis+spring例子

    下面将详细介绍这些技术及其在"backbone+bootstrap+ibatis+spring例子"中的应用场景。 **Backbone.js** 是一个轻量级的JavaScript框架,主要用于构建结构化的前端应用。它提供了Model、View、Collection和Router等...

    springMVC+ibatis+hibernate+spring+boostrap框架的lib包

    Spring MVC、iBatis、Hibernate、Spring 和 Bootstrap 是在 Web 开发中广泛使用的五种技术。下面将分别介绍这些框架的核心概念、功能以及它们如何协同工作。 **Spring MVC** Spring MVC 是 Spring 框架的一个模块,...

Global site tag (gtag.js) - Google Analytics