`

ibatis 学习笔记(一) 批量处理 存储过程

阅读更多
/*
*在项目中,遇到这样的一个问题,当某一模块需要插入,更新一批大的数据量时,
*此处大的含义是:更新到的数据记录比较多
*用ibatis实现一条一条的插入,更新,如此循环下去。速度很慢
*分析:
* 这些操作有个共同点:
* PreparedStatement对象和已映射的语句完全一致(简单点说:就是操作不断重复)
* 由于事物是交给spring管理了,所以每做一次操作都会起一个事物,久而久之导致
* 性能问题。
* 
* batch批处理就适合那些查询,插入,更新,删除等大量重复的操作
*
* 存储过程也比较适合这样的场合,但要求很多 
* 批处理 是把 所有sql语句  放入一块内存中,然后一次性全部写到服务器,这个节省了客* 服端到服务器的访问时间
*/
-- Create table
create or replace table DEMO
(
  UUID      NUMBER,
  UUSER     VARCHAR2(50),
  UPASSWORD VARCHAR2(50)
)

--Insert a million records with the DEMO procedure
create or replace procedure demo_p(total in integer) AS
uuid number :=1;
uuser varchar2(50) := 'user';
upassword varchar2(50) :='password';
begin
loop  
  insert into demo(uuid,uuser,upassword) values(uuid,uuser||uuid,upassword||uuid);
  uuid := uuid + 1;
  exit when uuid >= total;
end loop;
end;

---Clear table then call procedure to insert a million records 
truncate table demo;
call demo_p(1000);
select * from demo;

--Java实现
--1--ibatis普通实现插入一百条条数据--

--2--ibatis批量插入一百万条数据--

--3--ibatis调用存储过程插入一百万条数据--




1--构建环境 添加 classes12.jar ibatis-2.3.4.726.jar

2--写好ibatis基本配置文件,公共资源文件

SqlMapConfig.properties
# DB Config 
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
username=scott
password=tiger


SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<!-- Always ensure to use the correct XML header as above! -->
<sqlMapConfig>
	<properties  resource = "com/oyp/sqlmap/SqlMapConfig.properties" />
	
	<settings  cacheModelsEnabled="true" enhancementEnabled="true"
		lazyLoadingEnabled="true" maxRequests="32" maxSessions="10"
		maxTransactions="5" useStatementNamespaces="false" />
	
	<transactionManager type = "JDBC">
		<dataSource type  = "SIMPLE">
			<property name="JDBC.Driver" value="${driver}" />
			<property name="JDBC.ConnectionURL" value="${url}" />
			<property name="JDBC.Username" value="${username}" />
			<property name="JDBC.Password" value="${password}" />
		</dataSource>
	</transactionManager>
	<sqlMap resource = "com/oyp/sqlmap/User.xml"/>
	
</sqlMapConfig>



3--dto层,或者说是model层
User.java

package com.oyp.model;

import java.io.Serializable;
/**
 * @author oyp 2009-12-14
 */
public class User implements Serializable {
	private static final long serialVersionUID = 2804032598967813289L;
	private int id;
	private String name;
	private String password;
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}




4--sqlmap映射文件

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap 
    PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" 
    "http://www.ibatis.com/dtd/sql-map-2.dtd">
    
    <sqlMap namespace = "user" >
        <typeAlias alias = "user" type = "com.oyp.model.User"/>
     	<insert id = "insert_user" parameterClass = "user" >
     	  INSERT INTO DEMO (UUID, UUSER, UPASSWORD) VALUES ( #id#,#name#, #password# )
     	</insert>
     	
     	<update id = "clear_user" >
				truncate table demo
     	</update>
     	  
     	  <parameterMap id="oypmap" class="java.util.Map">
			<parameter property="total" javaType="int" jdbcType="INTEGER" mode="IN" />
		 </parameterMap>
     	 <procedure id="procedureoyp" parameterMap="oypmap"  >
			{ call demo_p(?) }
		 </procedure> 
    </sqlMap>


5--DAO层
package com.oyp.dao;

import java.sql.SQLException;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.oyp.model.User;

public class UserDAO {
	
	public static SqlMapClient sqlMap = AppSqlConfig.getSqlMap();
	
	public static void insertUser(User user) throws SQLException {
		sqlMap.insert("insert_user",user);
	}
	public static void clearTable()  {
		try {
			sqlMap.update("clear_user");
		}catch (SQLException e) {
			e.printStackTrace();
		}
	}
}


5--获取封装数据库信息的Ibatis对象
package com.oyp.dao;

import java.io.IOException;
import java.io.Reader;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class AppSqlConfig {
	private static final SqlMapClient sqlMap;
	static {
	    try {
	      Reader reader = Resources.getResourceAsReader("com/oyp/sqlmap/SqlMapConfig.xml");
	      sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
	      reader.close(); 
	    } catch (IOException e) {
	      // Fail fast.
	      throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
	    }
	  }
	public static SqlMapClient getSqlMap() {
		return sqlMap;
	}


}



大公告成,等着测试下
休息................

开始测试

/**
 * 描述:一般处理
 * @author oyp 2009-12-15
 */
public class Main {
	public static int number =Util.number;
	public static void main (String[] args) throws SQLException {
		//清空表
		UserDAO.clearTable();
		//一般处理
		List<User> list = new ArrayList<User>();
		for (int i = 0 ; i < number; i++) {
			User tempuser = new User();
			tempuser.setId(i);
			tempuser.setName("user"+i);
			tempuser.setPassword("password"+i);
			list.add(tempuser);
		}
		//开始
		UserDAO.sqlMap.startTransaction();
		long begin = System.currentTimeMillis();
		for (int i = 0 ; i < number ; i++) {
			try {
				 UserDAO.insertUser(list.get(i));
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		UserDAO.sqlMap.commitTransaction();
		UserDAO.sqlMap.endTransaction();
		System.out.println(System.currentTimeMillis()-begin);
	}
}


/**
 * 描述:batch处理
 * @author oyp 2009-12-15
 */
public class MainBatch {
	public static int number =Util.number;
	public static void main (String[] args) throws SQLException {
		//清空表
		UserDAO.clearTable();
		//批量插入的对象
		List<User> list = new ArrayList<User>();
		for (int i = 0 ; i < number; i++) {
			User tempuser = new User();
			tempuser.setId(i);
			tempuser.setName("user"+i);
			tempuser.setPassword("password"+i);
			list.add(tempuser);
		}
		//批量处理开始
	    long begin = System.currentTimeMillis();
	    UserDAO.sqlMap.startTransaction();
	    for (int i = 0 ; i < number ; i ++) {
	    	if (i % 10000 == 0) {
	    		UserDAO.sqlMap.startBatch();
	    	}
	    	UserDAO.insertUser(list.get(i));
	    	if ((i+1) % 10000 ==0) { 
	    		UserDAO.sqlMap.executeBatch();
	    	}
	    }
	    UserDAO.sqlMap.executeBatch();
	    UserDAO.sqlMap.commitTransaction();
	    UserDAO.sqlMap.endTransaction();
	    System.out.println(System.currentTimeMillis()-begin);
	}
}

/*
 *描述:调用存储过程
 *@author oyp 2009-12-15
 */


public class MainProcedure {
	public static int number =Util.number;
	public static void main (String[] args) throws SQLException {
		//清空表
		UserDAO.clearTable();
		HashMap map = new HashMap();
		map.put("total", number);
		//调用存储过程
		long begin = System.currentTimeMillis();
		UserDAO.sqlMap.startTransaction();
	    UserDAO.sqlMap.insert("procedureoyp",map);
	    UserDAO.sqlMap.commitTransaction();
	    UserDAO.sqlMap.endTransaction();
	    System.out.println(System.currentTimeMillis()-begin);
	}
	
}





1-- Util.number = 1000 ;
   普通处理:593ms
   批量处理:94ms
   存储过程处理:218ms

2--Util.number = 10000;
   普通处理:2734ms
   批量处理:328ms
   存储过程处理:1172ms

3--Util.number = 100000;
   普通处理: 32641 ms  休息....
   批量处理: 1937ms   休息....
   存储过程处理:8453 ms

4--Util.number = 300000;
   批量处理: 3937 ms   休息....

5--Util.number = 1000000;
    批量处理: 电脑被我折腾着不行了
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap      space
	at java.util.Arrays.copyOf(Arrays.java:2760)
	at java.util.Arrays.copyOf(Arrays.java:2734)
	at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
	at java.util.ArrayList.add(ArrayList.java:351)
	at MainBatch.main(MainBatch.java:24)
  (注:因为要创建插入数据库的对象所以内存耗尽, :twisted: 公司配的电脑太差!)

   存储过程: 119906 ms 

 

这些纯属菜鸟级的试验,真正的项目当中要考虑到各方面的原因,要比这复杂多了,所以哪里需要改善,或者有什么好的建议,尽管砸吧!~~(事务,数据库)
   
   ps: 这种情况,存储过程的效率怎么比不上批处理  ??

  












分享到:
评论
2 楼 liaozhi_ITOYO 2015-06-01  
1 楼 boy_scarecrow 2013-07-04  
不错,借鉴了!

相关推荐

    IBatis学习笔记以及使用心得

    IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得

    ibatis学习笔记

    ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记

    iBatis2学习笔记

    6.iBatis2学习笔记:一对多映射(双向).doc 7.iBatis2学习笔记:多对多映射(双向) .doc 8.iBatis2学习笔记:总结与思考.doc 9.iBatis2实体状态图解.doc 10.iBatis insert操作陷阱.doc 每章都有小例子。 呵呵,希望...

    ibatis应对批量update

    为了解决这个问题,ibatis(现已更名为MyBatis)提供了一种支持批量更新的机制,能够显著提高数据处理的速度。 #### 批量Update背景与问题 在实际应用中,经常会遇到需要批量更新数据库中的数据的情况,例如:商品...

    ibatis学习笔记(一)

    这篇“ibatis学习笔记(一)”可能是博主对Ibatis基础概念、安装配置以及基本使用的介绍,让我们通过标签“源码”和“工具”来深入探讨Ibatis的相关知识。 首先,Ibatis是一个轻量级的Java ORM(对象关系映射)框架...

    ibatis学习笔记.txt

    ### iBatis 学习笔记知识点总结 #### 一、iBatis 概念与特点 **1.1 iBatis 定义** - **iBatis** 是一个基于 Java 的开源持久层框架,它专注于 SQL 映射,提供了一种将对象与数据库交互过程中的 SQL 语句进行分离的...

    ibatis 学习笔记

    iBATIS 是一款著名的Java持久层框架,它与Hibernate等全自动化ORM解决方案不同,提供了一种半自动化的处理方式,让开发者对SQL拥有更大的控制权。在iBATIS中,主要包括SQL Maps和Data Access Objects(DAO)两个核心...

    ibatIS调用存储过程

    ibatIS调用存储过程是数据库操作中常见的一种技术,特别是在复杂的业务逻辑处理或数据批量操作时,存储过程能够提供更高的效率和更好的性能。本文将深入探讨如何在ibatIS框架中调用存储过程,以及涉及到的相关知识点...

    持久层框架ibatis学习笔记

    通过本文的学习笔记,我们可以了解到 iBatis 在简化数据库访问的同时提供了足够的灵活性。尽管 iBatis 相比 Hibernate 在自动化程度上略显不足,但对于需要高度定制 SQL 查询的场景来说,iBatis 的优势十分明显。...

    Ibatis调用存储过程调用存储过程

    本文将围绕“Ibatis调用存储过程”这一主题展开讨论,旨在帮助读者理解并掌握在Ibatis中调用存储过程的方法。 #### 二、存储过程与Ibatis简介 ##### 2.1 存储过程简介 存储过程是一种在数据库中预先编译好的SQL...

    ibatis3批量插入

    通过Ibatis3xml文件配置+Mysql实现数据批量插入,原先在网上找很多,都是关于批量更新,批量插入的很少,而且其写法又完全不同,所以自己研究了一下。可供参考。另外插入时如出现内容报错,请参照my.cnf修改书库配置...

    ibatis批量处理

    iBatis(现已更名为MyBatis)是一款优秀的持久层框架,它支持定制化SQL、存储过程及高级映射。iBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。iBatis可以非常简单地将接口和Java的POJOs(Plain Old ...

    ibatis调用存储过程.txt

    ibatis提供了一种简洁的方式来管理和执行SQL语句,同时支持存储过程的调用,这对于需要处理复杂数据库操作的应用程序来说非常有用。理解ibatis的工作原理和如何配置存储过程是非常重要的,这将有助于开发者更高效地...

    IBatis查删改查与调用存储过程 mysql数据库

    "IBatis查删改查与调用存储过程 mysql数据库" 这个标题揭示了本文将深入探讨如何使用IBatis框架在MySQL数据库中执行基本的CRUD(创建、读取、更新、删除)操作,以及如何调用存储过程。IBatis是一个轻量级的Java持久...

    ibatis调用存储过程

    本篇文章将详细介绍如何在iBATIS中调用存储过程,包括带参数和不带参数的存储过程,并通过一个具体的例子进行说明。 首先,存储过程是预编译的SQL语句集合,它可以包含复杂的业务逻辑,例如多条SQL语句、循环、条件...

    Ibatis学习笔记,文档,资源6合1

    这个压缩包集合了Ibatis的学习笔记、文档和相关资源,为想要深入理解和掌握Ibatis的人提供了一站式的自学材料。 Ibatis的核心概念是SQL Mapping,它允许开发者将SQL语句直接写在XML配置文件中,或者使用注解方式,...

    IBATIS学习笔记

    ### IBATIS学习笔记知识点详解 #### 一、IBATIS简介 iBatis是一个用于Java的数据持久化框架,类似于Hibernate、JDO和EJB等技术。它的主要特点是将对象映射为SQL语句,这使得开发人员可以更加灵活地控制SQL的执行,...

    ibatis调用oracle存储过程分页

    ibatis调用oracle存储过程分页

Global site tag (gtag.js) - Google Analytics