oracle +mybatis mybatis批量删除sql 会不会内存溢出

3920人阅读
使用mybatis的删除前台选定的几条数据;删除一条数据;删除所有数据。
我是使用了list来传值,因为我的需求是通过完税证号码删除记录。
mapper里边使用foreach标签
java代码:
&& &String[] split = wszhm.split(&,&);
&&&&&& List list = new ArrayList();
&&&&&& for(int i=0;i&split.i++){
&& &&& &&& list.add(split[i]);
&&& delete = this.getSqlSessionTemplate().delete(HgjksDelServiceHandler.class.getName()+&.delHgjkss&, list);
以下是mapper里边的:
&!--& 删除 --&
&delete id=&delHgjkss& parameterType = &java.util.List&&
&& & delete from jh_hgjksdr where 1=1
&& & &if test=&wszhm !=null and wszhm != ''&&
&& & and wszhm in
&& && &foreach collection=&list&& index=&index& item=&item& open=&(& separator=&,& close=&)&& &
&& &&& #{item}
&& && &/foreach&
&& & &/if&
一般传值主要有三种:
&1.&&&& 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2.&&&& 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3.&&&& 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,
实际上如果你在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,
所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
.cn/s/blog_6a0cd5e501011snl.html
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6215次
排名:千里之外
原创:23篇
(11)(17)(1)09:57 提问
求经验!Mybatis 针对Oracle数据库如何写“多条件”批量删除语句?
我的写法:
&delete id="delMultiByIds2" parameterType="java.util.List"&
delete from tb_duty where
&foreach collection="list" item="item" index="index" separator="or"&
( dscd=#{item.dscd},
and unit_id=#{item.unitId},
and year=#{item.year},
and month=#{item.month},
and flag=#{item.flag} )
&/foreach&
语句的语法没错,只是无法删除数据库中的记录,肯定是语句的写法有问题。
希望有经验的高手指教一把!
按赞数排序
问题解决后兴奋地写下:
程序批量删除无法删除的主要问题最终还是在sql语句上,虽然debug日志上能看到sql语句和参数都没有问题,但是!sql语句执行的时候并没有拿到这些个参数。经调试,将foreach中参数赋值的写法由原先的
&foreach collection="list" item="item" index="index" separator="union all"&
。。。B.dscd=#{item.dscd} and B.unit_id=#{item.unitId} 。。。
&/foreach&
&foreach collection="list" item="item" index="index" separator="union all"&
。。。B.dscd=${item.dscd} and B.unit_id=${item.unitId} 。。。
&/foreach&
至此,困扰我许久的问题得以解决!
附:Mybatis针对Oracle数据库“多条件”批量删除的mapper.xml
&!-- 批量删除值班表 --&
&delete id="delMultiByIds2" parameterType="java.util.List"&
delete from tb_duty A
where exists
select 1 from(
&foreach collection="list" item="item" index="index" separator="union all"&
B.* from tb_duty B where 1=1 and
B.dscd=${item.dscd} and B.unit_id=${item.unitId} and
B.year=${item.year} and B.month=${item.month} and B.flag=${item.flag}
&/foreach&
A.duty_id=S.duty_id
传递的参数后台是否能够获取的到?
这个当然能获取到,都在list里的对象里面。
后台没有输出错误原因么
&!-- 批量删除值班表 --&
&delete id="delMultiByIds2" parameterType="java.util.List" &
delete from tb_duty
where exists
&foreach collection="list" item="item" index="index" separator="union all"&
&include refid="Base_Column_List" /& from tb_duty where 1=1 and
dscd=#{item.dscd} and unit_id=#{item.unitId} and
year=#{item.year} and month=#{item.month} and flag=#{item.flag}
&/foreach&
最新的sql在plsql里面执行没有问题,但是通过mabatis执行还是无法实现删除效果!继续等待。。。一但解决,我会里面贴上解决方案。
最新的sql:
&!-- 批量删除值班表 --&
&delete id="delMultiByIds2" parameterType="java.util.List" &
delete from tb_duty A
where exists
&foreach collection="list" item="item" index="index" separator="union all"&
B.* from tb_duty B where 1=1 and
B.dscd=#{item.dscd} and B.unit_id=#{item.unitId} and
B.year=#{item.year} and B.month=#{item.month} and B.flag=#{item.flag}
A.duty_id=B.duty_id
&/foreach&
直接拿打印的sql语句(语句和参数都有)在plsql里面执行可以,但是程序上走一遍还是不行。无法删除!
delete from tb_duty A where exists ( select B.* from tb_duty B where 1=1 and B.dscd=? and B.unit_id=? and B.year=? and B.month=? and B.flag=? and A.duty_id=B.duty_id union all select B.* from tb_duty B where 1=1 and B.dscd=? and B.unit_id=? and B.year=? and B.month=? and B.flag=? and A.duty_id=B.duty_id union all select B.* from tb_duty B where 1=1 and B.dscd=? and B.unit_id=? and B.year=? and B.month=? and B.flag=? and A.duty_id=B.duty_id )
Parameters: 340100(String), 4(Integer), 2015(String), 7(String), 1(Integer), 340100(String), 4(Integer), 2015(String), 6(String), 1(Integer), 340100(String), 4(Integer), 2015(String), 5(String), 1(Integer)
继续等待。。。。。。
问题很可能出在Spring和Mybatis整合事务起没起作用上!
控制台有2句可疑的话(已标记):
09:16:21,877 DEBUG [org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession
09:16:21,877 DEBUG [org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f703110] was not registered for synchronization because synchronization is not active
09:16:21,877 DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Fetching JDBC Connection from DataSource
09:16:21,877 DEBUG [org.springframework.jdbc.datasource.DriverManagerDataSource] - Creating new JDBC DriverManager Connection to [jdbc:oracle:thin:@10.34.0.84:1521:orcl]
09:16:21,924 DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] - JDBC Connection [oracle.jdbc.driver.T4CConnection@616b6449] will not be managed by Spring
09:16:21,924 DEBUG [com.sunny.dao.duty.DutyMapper.delMultiByIds2] - ==&
Preparing: delete from tb_duty A where exists ( select S.* from( select T.* from tb_duty T right join ( select B.* from tb_duty B where 1=1 and B.dscd=? and B.unit_id=? and B.year=? and B.month=? and B.flag=? union all select B.* from tb_duty B where 1=1 and B.dscd=? and B.unit_id=? and B.year=? and B.month=? and B.flag=? ) B on T.duty_id=B.duty_id ) S where A.duty_id=S.duty_id )
09:16:21,924 DEBUG [com.sunny.dao.duty.DutyMapper.delMultiByIds2] - ==& Parameters: 340100(String), 4(Integer), 2015(String), 9(String), 1(Integer), 340100(String), 4(Integer), 2015(String), 5(String), 1(Integer)
09:16:21,924 DEBUG [com.sunny.dao.duty.DutyMapper.delMultiByIds2] - &==
Updates: 0
09:16:21,924 DEBUG [org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f703110]
09:16:21,924 DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Returning JDBC Connection to DataSource
09:16:21,924 DEBUG [org.springframework.web.method.HandlerMethod] - Method [delMultiByIds] returned [{"success":false}]
上面的标记没反应,是下面这2句:
JDBC Connection [oracle.jdbc.driver.T4CConnection@616b6449] will not be managed by Spring
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f703110]
其他相似问题25740人阅读
mybatis(2)
MyBatis中批量插入&&
&insert id=&insertbatch& parameterType=&java.util.List&&
& &selectKey keyProperty=&fetchTime& order=&BEFORE&
& resultType=&java.lang.String&&
& SELECT CURRENT_TIMESTAMP()
& &/selectKey&
& insert into kangaiduoyaodian ( depart1, depart2, product_name,
& generic_name, img, product_specification, unit,
& approval_certificate, manufacturer, marketPrice, vipPrice,
& website, fetch_time, productdesc ) values
& &foreach collection=&list& item=&item& index=&index&
& separator=&,&&
& ( #{item.depart1}, #{item.depart2}, #{item.productName},
& #{item.genericName}, #{item.img},
& #{item.productSpecification}, #{item.unit},
& #{item.approvalCertificate}, #{item.manufacturer},
& #{item.marketprice}, #{item.vipprice}, #{item.website},
& #{fetchTime}, #{item.productdesc} )
& &/foreach&
& &/insert&
&insert id=&batchInsertB2B& parameterType=&ArrayList&&
insert into xxxxtable(hkgs,hkgsjsda,office,asdf,ddd,ffff,supfullName,classtype,agent_type,remark)
&foreach collection=&list& item=&item& index=&index& separator=&union all&&
select #{item.hkgs,jdbcType=VARCHAR},
#{item.hkgsjsda,jdbcType=VARCHAR},
#{item.office,jdbcType=VARCHAR},
#{item.asdf,jdbcType=VARCHAR},
#{item.ddd,jdbcType=VARCHAR},
#{item.ffff,jdbcType=VARCHAR},
#{item.supfullName,jdbcType=VARCHAR},0,0,
#{item.remark,jdbcType=VARCHAR} from dual
&/foreach&
可以考虑用union all来实现批量插入。
insert into XX_TABLE(XX,XX,XX)select 'xx','xx','xx' union all select 'xx','xx','xx' union all select 'xx','xx','xx' ...
先拼装好语句再动态传入insert into XX_TABLE(XX,XX,XX)后面部分
MyBatis中批量删除
&!-- 通过主键集合批量删除记录 --&
&delete id=&batchRemoveUserByPks& parameterType=&java.util.List&&
DELETE FROM LD_USER WHERE ID in&
&foreach item=&item& index=&index& collection=&list& open=&(& separator=&,& close=&)&&
&/foreach&
MyBatis中in子句
1.只有一个参数
参数的类型要声明为List或Array
Sql配置如下:
&select id=&selectProduct& resultMap=&Map&&
FROM PRODUCT
WHERE PRODUCTNO IN
&&&& &foreach item=&productNo& index=&index& collection=&参数的类型List或array&&
&&&&&&&&&&& #{productNo}
&&& &/foreach&
2.多个参数
首先要将多个参数写入同一个map,将map作为一个参数传入mapper
Sql配置如下:
&select id=&selectProduct& resultMap=&Map&&
FROM PRODUCT
WHERE PRODUCTNO IN
&&&& &foreach item=&productNo& index=&index& collection=&map中集合参数的名称&&
&&&&&&&&&&& #{productNo}
&&& &/foreach&
&MyBatis批量修改
&&update&id=&updateOrders&&parameterType=&java.util.List&&
&update&orders&set&state&=&'0'&where&no&in
&&foreach&collection=&list&&item=&nos&&open=&(&&separator=&,&&close=&)&&
&&/foreach&
&&/update&
&MyBatis的前身就是著名的Ibatis,不知何故脱离了Apache改名为MyBatis。
&MyBatis所说是轻量级的ORM框架,在网上看过一个测试报告,感觉相比于Hibernate来说,优势并不明显。
下面说一下比较有趣的现象,根据MyBatis的官方文档,在获得sqlSession时,它有为批量更新而专门准备的:
= sessionFactory.openSession();//用于普通update
session = sessionFactory.openSession(ExecutorType.BATCH,
true);//用于批量update
&一般来说,对MYSQL数据库批量操作时速度取决于,是为每一个处理分别建立一个连接,还是为这一批处理一共建立一个连接。按MyBatis的手册说明,选择ExecutorType.BATCH意味着,获得的sqlSession会批量执行所有更新语句。不过我测试了一下,批量插入1000条数据,发觉ExecutorType.BATCH方式的效率居然比普通的方式差很多。我测试用的Mapper中的insert配置如下,再用for循环插入1000条记录:
id=&insert& parameterType=&sdc.mybatis.test.Student&&
&!-- WARNING - @mbggenerated This element is automatically generated by
MyBatis Generator, do not modify. This element was generated on Mon May 09
11:09:37 CST 2011. --&
insert into student (id, name, sex,
address, telephone, t_id
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{sex,jdbcType=VARCHAR},
#{address,jdbcType=VARCHAR}, #{telephone,jdbcType=VARCHAR}, #{tId,jdbcType=INTEGER}
&我不清楚原因在哪里, 就配置了MyBatis的log4j,想查看下日志。下载了log4j.jar和commons-logging.jar并配置到项目的类路径,然后在代码路径下新建文件log4j.properties,内容如下:
log4j.rootLogger=DEBUG, stdout
# SqlMap logging configuration...
.ibatis=DEBUG
.mon.jdbc.SimpleDataSource=DEBUG
.ibatis.sqlmap.engine.cache.CacheModel=DEBUG
.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG
.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG
.mon.util.StopWatch=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
&然后再次测试普通的sqlSession,发现日志内容中虽然插入了1000条数据,但只新建了一次连接,最后又关闭了该连接(日志如下)。也就是说MyBatis中的普通sqlSession好像已经对批量插入默认是一次连接中完成,那么还提供ExecutorType.BATCH方式干什么,况且该方式好像效率也不行,或者是我使用ExecutorType.BATCH方式不对??
DEBUG [main] - Created connection
DEBUG [main] - ooo Connection Opened
DEBUG [main] -
==& Executing: insert into student
( name, sex, address,
telephone, t_id
( ?, ?, ?,
DEBUG [main] -
==& Parameters: 新人0(String), male(String),
addr0(String), dd(String),3(Integer)
DEBUG [main] -
==& Executing: insert into student
( name, sex, address,
telephone, t_id
( ?, ?, ?,
DEBUG [main] -
==& Parameters: 新人1(String), male(String),
...............
...............
DEBUG [main] - xxx Connection Closed
DEBUG [main] - Returned connection
3502256 to pool.
&最后一点是关于数据库批量插入时sql语句级的优化,我特意测试了两种方式,在StudentMapper中配置了两种insert模式。第一种对应insert value1,insert value2,,,,;第二种对应insert values (value1, value2,....)。发现后者果然比前者快很多啊。下面是两种insert模式,及测试结果对应图:&
&!-- 在外部for循环调用一千次
id=&insert& parameterType=&sdc.mybatis.test.Student&&
insert into student (id, name, sex,
address, telephone, t_id
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{sex,jdbcType=VARCHAR},
#{address,jdbcType=VARCHAR}, #{telephone,jdbcType=VARCHAR}, #{tId,jdbcType=INTEGER}
&!-- 批量 ,传入一个长度为1000的list
id=&insertBatch&&
insert into student ( &include
refid=&Base_Column_List&/& )
collection=&list& item=&item&
index=&index& separator=&,&&
(null,#{item.name},#{item.sex},#{item.address},#{item.telephone},#{item.tId})
&/foreach&
MyBatis配置文件的DTD文件(与Ibatis3不同):MyBatis的中文手册:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:146962次
积分:1243
积分:1243
排名:千里之外
原创:11篇
转载:49篇
评论:10条
(1)(1)(1)(1)(1)(1)(1)(2)(3)(4)(1)(1)(1)(3)(8)(1)(10)(13)(5)(1)Mybatis(27)
Oracle Mysql SQL(4)
oracle批量新增的sql是:
&insert id=&insertAttractionsBatch& parameterType=&Java.util.List&&
insert into ATTRACTIONS (
ID, NAME, LONGITUDE, LATITUDE,
UPDATE_TIME
&foreach collection=&list& item=&item& index=&index& separator=&union all& &
#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.longitude,jdbcType=DECIMAL}, #{item.updateTime,jdbcType=TIMESTAMP}
from dual)
&/foreach&
需要重点注意的是sql中没有values,和&foreach&标签中的(selece ..... from dual)
MySql中的sql是这样的:
&insert id=&insertAttractionsBatch& parameterType=&java.util.List&&
insert into ATTRACTIONS (
ID, NAME, LONGITUDE, LATITUDE,
UPDATE_TIME
&foreach collection=&list& item=&item& index=&index& separator=&union all& &
#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.longitude,jdbcType=DECIMAL}, #{item.updateTime,jdbcType=TIMESTAMP}
&/foreach&
Mysql更新是这样的:
第一种方式:
&update id=&updateBatch& parameterType=&Map&&
a=#{fptm},
b=#{csoftrain}
where c in
&foreach collection=&cs& index=&index& item=&item& pen=&(&separator=&,&close=&)&&
&/foreach&
但是这种方式修改的字段值都是一样的。
第二种方式:
&update id=&batchUpdate&
parameterType=&java.util.List&&
&foreach collection=&list& item=&item& index=&index& open=&& close=&& separator=&;&&
update test
test=${item.test}+1
where id = ${item.id}
&/foreach&
这种方式,可以一次执行多条SQL语句
oracle更新不能按普通的方式,需要这样:
&update id=&updateAttractionsBatch& parameterType=&java.util.List&&
&foreach collection=&list& item=&item& index=&index& separator=&;& &
update ATTRACTIONS
&if test=&item.id!=null and item.id!=''&&
id = #{item.id},
&if test=&item.head!=null and item.head!=''&&
HEAD = #{item.head},
where id = #{item.id}
&/foreach&
删除与MySql一样如下:
&delete id=&deleteAttractions& parameterType=&java.util.List&&
delete from ATTRACTIONS
&foreach collection=&list& index=&index& item=&item& open=&(& separator=&or& close=&)&&
id=#{item.id}
&/foreach&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:253258次
积分:5944
积分:5944
排名:第4254名
原创:314篇
转载:300篇
评论:18条
阅读:1889
(3)(8)(2)(1)(2)(4)(1)(2)(1)(11)(13)(14)(24)(59)(83)(77)(67)(139)(103)(2)6941人阅读
java(522)
通过Mybatis做7000+数据量的批量插入的时候报错了,error log如下:
current_timestamp,
current_timestamp
) 被中止,呼叫 getNextException 以取得原因。
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2743)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:411)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2892)
at com.alibaba.druid.filter.FilterChainImpl.statement_executeBatch(FilterChainImpl.java:2596)
at com.alibaba.druid.wall.WallFilter.statement_executeBatch(WallFilter.java:473)
at com.alibaba.druid.filter.FilterChainImpl.statement_executeBatch(FilterChainImpl.java:2594)
at com.alibaba.druid.filter.FilterAdapter.statement_executeBatch(FilterAdapter.java:2474)
at com.alibaba.druid.filter.FilterEventAdapter.statement_executeBatch(FilterEventAdapter.java:279)
at com.alibaba.druid.filter.FilterChainImpl.statement_executeBatch(FilterChainImpl.java:2594)
at com.alibaba.druid.proxy.jdbc.StatementProxyImpl.executeBatch(StatementProxyImpl.java:192)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeBatch(DruidPooledPreparedStatement.java:559)
at org.apache.ibatis.executor.BatchExecutor.doFlushStatements(BatchExecutor.java:108)
at org.apache.ibatis.executor.BaseExecutor.flushStatements(BaseExecutor.java:127)
at org.apache.ibatis.executor.BaseExecutor.flushStatements(BaseExecutor.java:120)
at org.apache.ibatis.mit(BaseExecutor.java:235)
at org.apache.ibatis.mit(CachingExecutor.java:112)
at org.apache.ibatis.session.mit(DefaultSqlSession.java:196)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:390)
... 39 more
可以看到这种异常无法捕捉,仅能看到异常指向了druid和ibatis的原码处,初步猜测是由于默认的SqlSession无法支持这个数量级的批量操作,下面就结合源码和官方文档具体看一看。
项目使用的是Spring+Mybatis,在Dao层是通过Spring提供的SqlSessionTemplate来获取SqlSession的:
@Resource(name = &sqlSessionTemplate&)
private SqlSessionTemplate sqlSessionT
public SqlSessionTemplate getSqlSessionTemplate()
return sqlSessionT
}为了验证,接下看一下它是如何提供SqlSesion的,打开SqlSessionTemplate的源码,看一下它的构造方法:
/** * Constructs a Spring managed SqlSession with the {@code SqlSessionFactory} * provided as an argument. * * @param sqlSessionFactory */
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
}接下来再点开getDefaultExecutorType这个方法:
public ExecutorType getDefaultExecutorType() {
return defaultExecutorT
}可以看到它直接返回了类中的全局变量defaultExecutorType,我们再在类的头部寻找一下这个变量:
/** * @author Clinton Begin */
public enum ExecutorType {
SIMPLE, REUSE, BATCH
仔细观察一下,发现有3个枚举类型,其中有一个BATCH是否和批量操作有关呢?我们看一下mybatis官方文档中对这三个值的描述:&
- ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。&
- ExecutorType.REUSE: 这个执行器类型会复用预处理语句。&
- ExecutorType.BATCH:这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行还会标定它们是 必须的,来保证一个简单并易于理解的行为。
可以看到我的使用的SIMPLE会为每个语句创建一个新的预处理语句,也就是创建一个PreparedStatement对象,即便我们使用druid连接池进行处理,依然是每次都会向池中put一次并加入druid的cache中。这个效率可想而知,所以那个异常也有可能是insert
timeout导致等待时间超过数据库驱动的最大等待值。
好了,已解决问题为主,根据分析我们选择通过BATCH的方式来创建SqlSession,官方也提供了一系列重载方法:
SqlSession openSession()
SqlSession openSession(boolean autoCommit)
SqlSession openSession(Connection connection)
SqlSession openSession(TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)
可以观察到主要有四种参数类型,分别是&
- Connection connection&
- ExecutorType execType&
- TransactionIsolationLevel level&
- boolean autoCommit
官方文档中对这些参数也有详细的解释:
SqlSessionFactory 有六个方法可以用来创建 SqlSession 实例。通常来说,如何决定是你 选择下面这些方法时:&
Transaction (事务): 你想为 session 使用事务或者使用自动提交(通常意味着很多 数据库和/或 JDBC 驱动没有事务)?&
Connection (连接): 你想 MyBatis 获得来自配置的数据源的连接还是提供你自己&
Execution (执行): 你想 MyBatis 复用预处理语句和/或批量更新语句(包括插入和 删除)?
所以根据需求选择即可,由于我们要做的事情是批量insert,所以我们选择SqlSession
openSession(ExecutorType execType, boolean autoCommit)
顺带一提关于TransactionIsolationLevel也就是我们经常提起的事务隔离级别,官方文档中也介绍的很到位:
MyBatis 为事务隔离级别调用使用一个 Java 枚举包装器, 称为 TransactionIsolationLevel,&
否则它们按预期的方式来工作,并有 JDBC 支持的 5 级 (&
READ_UNCOMMITTED&
READ_COMMITTED,&
REPEATABLE_READ,&
SERIALIZA BLE)
回归正题,初步找到了问题原因,那我们换一中SqlSession的获取方式再试试看。
testing… 2minutes later…
不幸的是,依旧报相同的错误,看来不仅仅是ExecutorType的问题,那会不会是一次commit的数据量过大导致响应时间过长呢?上面我也提到了这种可能性,那么就再分批次处理试试,也就是说,在同一事务范围内,分批commit insert
batch。具体看一下Dao层的代码实现:
public boolean insertCrossEvaluation(List&CrossEvaluation& members)
throws Exception {
// TODO Auto-generated method stub
int result = 1;
SqlSession batchSqlSession =
batchSqlSession = this.getSqlSessionTemplate()
.getSqlSessionFactory()
.openSession(ExecutorType.BATCH, false);// 获取批量方式的sqlsession
int batchCount = 1000;// 每批commit的个数
int batchLastIndex = batchC// 每批最后一个的下标
for (int index = 0; index & members.size();) {
if (batchLastIndex &= members.size()) {
batchLastIndex = members.size();
result = result * batchSqlSession.insert(&MutualEvaluationMapper.insertCrossEvaluation&,members.subList(index, batchLastIndex));
System.out.println(&index:& + index+ & batchLastIndex:& + batchLastIndex);
// 数据插入完毕,退出循环
result = result * batchSqlSession.insert(&MutualEvaluationMapper.insertCrossEvaluation&,members.subList(index, batchLastIndex));
System.out.println(&index:& + index+ & batchLastIndex:& + batchLastIndex);
index = batchLastI// 设置下一批下标
batchLastIndex = index + (batchCount - 1);
batchSqlSession.close();
return Tools.getBoolean(result);
再次测试,程序没有报异常,总共7728条数据 insert的时间大约为10s左右
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1324124次
积分:15556
积分:15556
排名:第691名
原创:549篇
转载:744篇
评论:55条
欢迎访问我的GitHub:
联系方式:新浪微博
(11)(7)(14)(24)(17)(25)(19)(8)(24)(33)(27)(17)(33)(23)(16)(19)(19)(23)(23)(15)(22)(11)(21)(33)(33)(64)(41)(35)(56)(48)(29)(64)(46)(35)(38)(53)(51)(67)(51)(31)(23)(13)(10)(3)(1)(3)(3)(7)(7)

我要回帖

更多关于 mybatis中批量删除 的文章

 

随机推荐