ibatis批量插入-iterate标签应用
来源:互联网 发布:如何用c语言求素数 编辑:程序博客网 时间:2024/06/06 03:29
项目开发中在很多地方可能会遇到同时插入多条记录到数据库的业务场景,如果业务级别循环单条插入数据会不断建立连接且有多个事务,这个时候如果业务的事务执行频率相当较高的话(高并发),对数据库的性能影响是比较大的;为了提高效率,批量操作会是不错的选择,一次批量操作只需要建立一次连接且一个事务,能很大程度上提高数据库的效率。
批量插入操作的sql语句原型如下:
- insert into
- wsjiang_test(col1, col2, col3)
- values
- (col1_v, col2_v, col3_v),
- (col1_v, col2_v, col3_v),
- ...
这里我们以ibatis为例,进行应用说明!
一、 ibatis iterate标签配置说明
- < iterate
- property ="" /*可选,
- 从传入的参数集合中使用属性名去获取值,
- 这个必须是一个List类型,
- 否则会出现OutofRangeException,
- 通常是参数使用java.util.Map时才使用,
- 如果传入的参数本身是一个java.util.List, 不能只用这个属性.
- 不知道为啥官网: http://ibatis.apache.org/docs/dotnet/datamapper/ch03s09.html#id386679
- 说这个属性是必须的, 但是测试的时候是可以不设置这个属性的, 还望那位大虾知道, 讲解一下.
- */
- conjunction ="" /*可选,
- iterate可以看作是一个循环,
- 这个属性指定每一次循环结束后添加的符号,
- 比如使每次循环是OR的, 则设置这个属性为OR*/
- open ="" /*可选, 循环的开始符号*/
- close ="" /*可选, 循环的结束符号*/
- prepend ="" /*可选, 加在open指定的符号之前的符号*/
- > </ iterate >
二、 ibatis iterate标签使用示例
1、批量查询
- < select id ="iterate_query" parameterClass ="java.util.List" >
- <![CDATA[
- selelct * from wsjiang_test where id=1
- ]]>
- < iterate prepend ="prepend" conjunction ="conn" open ="open" colse ="close" >
- /*使用java.util.List作为参数不能设置property属性*/
- <![CDATA[
- #v[]#
- ]]> /*这里的"[]"是必须的, 要不然ibatis会把v直接解析为一个String*/
- </ iterate >
- </ select >
如果传入一个List为[123,234,345], 上面的配置将得到一个sql语句:
select * from wsjiang_test where id=1 prepend open 123 conn 234 conn 345 close
2、批量插入
A、不使用open/close属性
- < insert id =" iterate_insert1 " parameterClass ="java.util.List" >
- <![CDATA[
- insert into wsjinag_test( col1 , col2 , col3 ) values
- ]]>
- < iterate conjunction ="," >
- <![CDATA[
- (#test[]. col1 #, # test []. col2 #, # test []. col3 #)
- ]]>
- </ iterate >
- </ insert >
上面的配置将得到一个sql语句:
insert into wsjiang_test( col1, col2, col3 ) values (?, ?, ?) , (?, ?, ?) , (?, ?, ?)
B、使用open/close属性
- < insert id ="betchAddNewActiveCode" parameterClass ="java.util.List" >
- <![CDATA[
- insert into wsjinag_test( col1 , col2 , col3 ) values
- ]]>
- < iterate conjunction ="," open ="(" close =")" >
- <![CDATA[
- /*这里不加"("和")"*/
- #test[]. col1 #, # test []. col2 #, # test []. col3 #
- ]]>
- </ iterate >
- </ insert >
上面的配置将得到一个sql语句:
insert into wsjiang_test( col1, col2, col3 ) values (?, ?, ? , ?, ?, ? , ?, ?, ?)
这两种使用方式区别是相当大的. conjunction, open 和close这几个属性需小心使用,将其区分开.
三、单条插入返回新增记录主键
通常情况,ibatis的insert方法需要返回新增记录的主键,但并非任何表的insert操作都会返回主键(这是一个陷阱);要返回这个新增记录的主键,前提是表的主键是自增型的,或者是Sequence的;且必须启用ibatis的selectKey 标签; 否则获取新增记录主键的值为0或者null。
ibatis的配置:
- < insert id =" iterate_insert1 " parameterClass ="Object" >
- <![CDATA[
- insert into wsjinag_test( col1 , col2 , col3 )
- values (# col1 #, # col2 #, # col3 #)
- ]]>
- < selectKey keyProperty ="id" resultClass= "Long" >
- <![CDATA[
- SELECT LAST_INSERT_ID() AS value
- ]]>
- </ selectKey >
- </ insert >
四、 插入返回 新增记录数
在第三节中已经讲清楚通过ibatis的insert方法只能得到新增记录的ID; 如果对于无需知道新增记录ID,只需要知道有没有插入成功的业务场景时,特别是对于批量插入,配置的selectKey 可能会有问题时,一次插入多条,拿不到新增的ID,这时我们就只能返回插入成功的记录数来区分是否新增成功!但是insert方法是不会返回记录数;于是我们可以使用ibatis的update方法来调用没有配置 selectKey 标签的insert语句,这样就能返回影响(插入)的记录数了!
mybatis批量插入和删除
实体类:
import java.io.Serializable;public class AttachmentTable implements Serializable { private static final long serialVersionUID = 8325882509007088323L; private Integer id; // 附件名称 private String name; // 日志ID private Integer logid; // 附件URL private String url; // getter/setter.......}
Mapper接口:
import java.util.List;import model.AttachmentTable;public interface AttachmentTableMapper { int insert(AttachmentTable record); void insertByBatch(List<AttachmentTable> attachmentTables);}
Mapper.xml:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="mapper.AttachmentTableMapper"> <resultMap id="BaseResultMap" type="model.AttachmentTable"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="logID" jdbcType="INTEGER" property="logid" /> </resultMap> <resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="model.AttachmentTable"> <result column="url" jdbcType="LONGVARCHAR" property="url" /> </resultMap> <sql id="Base_Column_List"> id, name, logID </sql> <sql id="Blob_Column_List"> url </sql> <insert id="insert" parameterType="model.AttachmentTable"> insert into attachment_table (id, name, logID,url) values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{logid,jdbcType=INTEGER},#{url,jdbcType=LONGVARCHAR}) </insert> <insert id="insertByBatch" parameterType="java.util.List"> insert into attachment_table (name, logID,url) values <foreach collection="list" item="item" index="index" separator=","> (#{item.name,jdbcType=VARCHAR}, #{item.logid,jdbcType=INTEGER},#{item.url,jdbcType=LONGVARCHAR}) </foreach> </insert></mapper>
【注:标红的地方是需要注意的地方,我第一次做时直接“#{name,jdbcType=VARCHAR}”,没有加前缀“item”,导致报错“找不到name”】
(二)多参数批量删除示例
package com.vrv.linkdood.app.workreport.demomodule.mapper;import org.apache.ibatis.annotations.Param;public interface AttachmentTableMapper { void deleteByLogIdAndNames(@Param("logid") Integer logID, @Param("names") String[] names);}
<delete id="deleteByLogIdAndNames"> delete from attachment_table where logid = #{logid,jdbcType=INTEGER} AND NAME IN <foreach collection="names" item="item" index="index" open="(" close=")" separator=","> #{item} </foreach> </delete>
具体说明:在list和数组中是其中的对象,在map中是value。
该参数为必选。collection
要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。
当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
如果User有属性List ids。入参是User对象,那么这个collection = "ids"
如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"
上面只是举例,具体collection等于什么,就看你想对那个元素做循环。
该参数为必选。
- ibatis批量插入-iterate标签应用
- ibatis批量插入 批量删除 -iterate标签应用
- ibatis批量插入数据-iterate标签详解及应用
- ibatis批量插入数据-iterate标签详解及应用
- ibatis使用iterate实现批量插入insert正确写法
- iBatis iterate标签
- iBatis iterate标签
- ibatis iterate标签
- ibatis <iterate>标签
- ibatis标签之iterate
- ibatis <iterate>标签
- iBatis iterate标签
- logic:iterate标签应用
- ibatis中动态语句的iterate标签
- ibatis批量插入实例
- ibatis批量插入
- Ibatis批量插入数据
- ibatis批量插入
- SIP capture
- 大数据层--HDFS基本操作
- 【题解】codeforces786C Till I Collapse
- 全文搜索怎么给查询语句与文档相关性打分
- Java 线程的生命周期 演示 线程的状态 附代码实现
- ibatis批量插入-iterate标签应用
- 2015年第六届蓝桥杯C/C++程序设计本科B组省赛 星系炸弹(结果填空)
- Spring事务的隔离级别
- Java中(Integer)127 == (Integer)127和(Integer)129 == (Integer)129表达式结果差异分析
- BZOJ P1143[CTSC2008]祭祀river
- 1019. General Palindromic Number (20)
- 剪邮票
- 排序——交换排序之冒泡排序
- 【UESTC】保护果实