MyBatis批量插入数据实现(MySQL)

假如需要搬一万块砖到楼顶,有一部电梯,电梯一次可以放适量的砖(最多放 500)。可以选择一次运送一块砖,也可以一次运送 500 块砖,哪个时间消耗大?

一、sql 层面实现数据插入

  1. 单条插入数据的写法:
insert into table ([列名],[列名])  values ([列值],[列值]));
或:
insert into table values ([列值],[列值]));
  1. 批量插入
    一种可以在代码中循环执行上面的语句,但是这种效率太差。另一种,可以用 MySQL 支持的批量插入语句,这种方式更高效。
insert into table  ([列名],[列名]) 
 VALUES
([列值],[列值]),
([列值],[列值]),
([列值],[列值]);

批量的好处:可以避免程序和数据库建立多次连接,增加服务器负荷。

二、MyBatis 层面批量插入数据到数据库

两种方式:xml 文件和注解。使用批量插入执行的 sql 语句应该等价于:

 insert into table (id, name,sex,address)
 values
 (?,?,?,?),(?,?,?,?),(?,?,?,?),(?,?,?,?)

1️⃣xml 配置

最基础的是用 mapping.xml 配置的方式,包括以下两种具体方式:

  1. mapping.xml 中 insert 语句可以写成单条插入,在调用方循环 1000 次
<!-- 在外部for循环调用1000次 -->
<insert id="insert" parameterType="com.xxp.mybatis.Person">
    insert into person (id, name,sex,address)
    values 
    (#{id,jdbcType=INTEGER},#{name,jdbcType=VARCHAR},
    #{sex,jdbcType=VARCHAR},#{address,jdbcType=VARCHAR})
</insert>
  1. mapping.xml 中 insert 语句写成一次性插入一个 1000 的 list
<insert id="insertBatch" >
    insert into person ( <include refid="Base_Column_List" /> ) 
    values 
    <foreach collection="list" item="item" index="index" separator=",">
        (null,#{item.name},#{item.sex},#{item.address})
    </foreach>
</insert>

参数解释
foreach 的主要作用在构建 in 条件中,它可以在 sql 语句中进行迭代一个集合。foreach 元素的属性主要有 collection,item,separator,index,open,close。

  1. collection:指定要遍历的集合。表示传入过来的参数的数据类型。该属性是必须指定的,要做 foreach 的对象。在使用 foreach 的时候最关键的也是最容易出错的就是 collection 属性。在不同情况 下,该属性的值是不一样的,主要有一下 3 种情况:
    a. 如果传入的是单参数且参数类型是一个 List 的时候,collection 属性值为 list。
    b. 如果传入的是单参数且参数类型是一个数组的时候,collection 的属性值为 array。
    c. 如果传入的参数是多个的时候,就需要把它们封装成 Map,当然单参数也可以封装成 Map。Map 对象没有默认的键。

  2. item:表示集合中每一个元素进行迭代时的别名。将当前遍历出的元素赋值给指定的变量,然后用#{变量名},就能取出变量的值,也就是当前遍历出的元素。

  3. separator:表示在每次进行迭代之间以什么符号作为分隔符。select * from tab where id in(1,2,3)相当于1,2,3之间的","

  4. index:索引。index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置。遍历 list 的时候 index 就是索引,遍历 map 的时候 index 表示的就是 map 的 key,item 就是 map 的值。

  5. open/close:表示该语句以什么开始/结束。

mapper 接口中的使用:

public interface TabMapper {
    public List<Tab> getTabsByConditionLike(@Param("list")List<Integer> ids);
}

2️⃣注解

MyBatis 提供用于插入数据的注解有两个:@insert,@InsertProvider。类似还有:@DeleteProvider、@UpdateProvider和@SelectProvider。
作用:
用来在实体类的 Mapper 类里注解保存方法的 sql 语句。
区别:
@Insert 是直接配置 sql 语句,而 @InsertProvider 则是通过 sql 工厂类及对应的方法生产 sql 语句,这种方法的好处在于,可以根据不同的需求生产出不同的 sql,适用性更好。
使用:

@Insert("insert into blog(blogId,title,author) values(#blogId,#title,#author)")
public boolean saveBlog(Blog blog);
@InsertProvider
在 mapper 接口中的方法上使用 @InsertProvider 注解:

参数解释:
type 为工厂类的类对象,
method 为对应的工厂类中的方法,方法中的 @Param(“list”) 是因为批量插入传入的是一个 list,但是 Mybatis 会将其包装成一个 map。其中 map 的 key 为“list”,value为传入的 list。

三、xml/注解 两种方式的区别

1️⃣foreach 相当语句逐条 insert 语句执行,将出现如下问题:

  1. mapper 接口的 insert 方法返回值将是最后一条 insert 语句的操作成功的记录数目(就是0或1),而不是所有 insert 语句的操作成功的总记录数目;
  2. 当其中一条不成功时,不会进行整体回滚。

2️⃣注解方式:当有一条插入不成功时,会整体回滚。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容