Mybatis之批量操作

摘要:
#{item.xx};#{item.xx}<如果它是数组,则它是arrayitem=“item”loop open=“”开始标识符中每个项的别名;并返回每个用户插入的ID-->insertid=“batchSave”parameterType=“java.util.List”useGeneratedKeys=“true”keyProperty=“ID”&gt!年龄)值<

首先批量操作的优点是:大大的提高查询的效率。

举个简单的例子:如果在程序中遍历来执行sql的话,这种情况就是有多少行数据就要执行多少条sql,这样导致的效率将是非常低。

如下可能需要40s

insert into USER (name,age) values ('张三','33');
insert into USER (name,age) values ('张三','33');
insert into USER (name,age) values ('张三','33');
insert into USER (name,age) values ('张三','33');
。。。

如果改成批量执行的话,如下可能只需要3s.:

insert into USER (name,age) values
('张三','33'),
('张三','33'),
('张三','33'),
...

下面将进行详细讲解用法。

==============================

批量操作包括批量插入和批量更新和批量删除:

主要是应用<foreach>来实现。

格式如:

<foreach collection="list" item="item" open="(" close=")" separator="," index="index"> #{item.xx}, #{item.xx} </foreach>

其中foreach中的包含的属性值有:

collection="list" 其中list是固定的,如果是数组就是array

item="item" 循环中每一项的别名

open="" 开始标识,比如删除in (id1,id2),open="(" close=")"

close="" 结束标识

separator="," 分隔符号

index="index" 下标值

========================================================================

批量新增:

<!-- 批量保存用户,并返回每个用户插入的ID -->

<insert id="batchSave" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">

INSERT INTO `test`.`tb_user`(`username`, age)

VALUES

<foreach collection="list" item="item" separator=",">

(#{item.username}, #{item.age})

</foreach>

</insert>

扩展:useGeneratedKeys="true" keyProperty="id" 这两个属性的设置表示按主键自增的方式自动生成主键。

如果这种写法在Oracle不兼容的话,可以使用:

INSERT ALL

INTO A(field_1,field_2) VALUES (value_1,value_2)

INTO A(field_1,field_2) VALUES (value_3,value_4)

INTO A(field_1,field_2) VALUES (value_5,value_6)

SELECT 1 FROM DUAL;

详解:

"INSERT ALL INTO  a表
VALUES(各个值)  
INTO a表 VALUES (其它值) 
INTO a表 VALUES(其它值) .... 再跟一个SELECT 语句"。

后边跟的SELECT 语句我们可以从虚拟表里查如 SELECT 1 FROM DUAL。注意后边跟的SELECT语句可以随意,不过不是把它SELECT出来的内容插入前边的表里,而是起到前边的多个数据每次插入多少行的作用,这个多少行是和后边跟的SELECT语句查出来几条而定的,如后边的跟的SELECT 语句查出了15条记录,那么前边的"INSERT ALL INTO  a表 VALUES(各个值1)  INTO a表 VALUES (其它值2) INTO a表 VALUES(其它值3)"就会先插入值1对应的各个字段插入15条记录,然后插入值2各个对应的字段15条记录,然后插入值3对应的各个字段15条记录,也就是说有点按列插入的意思

       我们要的是批量插入多个VALUES这样的一条记录,所以后边的SELECT 语句只要能查出一条记录就行,建议大家后边用SELECT 1 FROM DUAL

实际项目中的例子有:

<!-- 批量添加添加 -->
<insert id="batchInsert">
INSERT ALL
<foreach collection="list" item="entity" separator="">
into T_JW_XKGL_XKGZXSFW
(
XKGZXSFW_ID,
XKGZ_ID,
XQ_ID,
XYH,
NJ,
ZYDL_ID,
ZY_ID,
ZYFX_ID,
SFXFZ,
SFGAT,
SFLXS,
SFYXS,
SFJHS,
XSQT,
CXB,
CJR,
CJRXM,
CJSJ
)
values (
#{entity.electiveCourseRuleStuScopeID,jdbcType=VARCHAR},
#{entity.electiveCourseRuleID,jdbcType=VARCHAR},
#{entity.campusID,jdbcType=VARCHAR},
#{entity.collegeNum,jdbcType=VARCHAR},
#{entity.grade,jdbcType=VARCHAR},
#{entity.professionBroadID,jdbcType=VARCHAR},
#{entity.professionID,jdbcType=VARCHAR},
#{entity.professionDirID,jdbcType=VARCHAR},
#{entity.creditSystem,jdbcType=VARCHAR},
#{entity.hongKongMacaoTaiwan,jdbcType=VARCHAR},
#{entity.overseasStu,jdbcType=VARCHAR},
#{entity.medicalInsuranceStu,jdbcType=VARCHAR},
#{entity.exchangeStu,jdbcType=VARCHAR},
#{entity.stuGroup,jdbcType=VARCHAR},
#{entity.innovationClazz,jdbcType=VARCHAR},
#{entity.creator,jdbcType=VARCHAR},
#{entity.creatorName,jdbcType=VARCHAR},
#{entity.createTime,jdbcType=TIMESTAMP}
)
</foreach>
SELECT 1 FROM DUAL
</insert>

======================================================

批量删除

<!-- 批量删除用户 -->

<delete id="batchDelete" parameterType="java.util.List">

DELETE FROM USER

WHERE id IN

<foreach collection="list" item="item" open="(" close=")" separator=",">

  #{item}

</foreach>

</delete>

================================

第二种批量新增数据的方式:

oracle语法:

insert into tableX
(a,b,c) 
select * from (
select 1,2,3 from dual
union
select 4,5,6 from dual
) t

 在使用mybatis时,oracle需要写成下面格式

<foreach collection="list" item="file" index="index" separator="UNION">
实操例子有:
<insert   parameterType="java.util.List">
		insert into XTGL_GGGL_JSFW (GGJSFW_ID, JS_ID, TZGG_ID,
		CJR, CJSJ, ZHXGR,
		ZHXGSJ)
		<foreach close=")" collection="list" item="item" index="index"
			open="(" separator="union">
			select
			#{item.noticeRoseScopeId,jdbcType=VARCHAR}, #{item.roseId,jdbcType=VARCHAR}, #{item.noticeId,jdbcType=VARCHAR},
			#{item.creator,jdbcType=VARCHAR},
			#{item.createTime,jdbcType=VARCHAR}, #{item.editor,jdbcType=VARCHAR},
			#{item.editeTime,jdbcType=VARCHAR}
			from dual
		</foreach>
	</insert>

  

运行通过。在Oracle的版本中,有几点需要注意的:

        1.SQL中没有VALUES;

        2.<foreach>标签中的(selece ..... from dual);

        3.<foreach>标签中的separator的属性为"UNION ALL",将查询合并结果集。

==============================

批量更新

<update id="updateByElectiveCourseResultIds">
update T_JW_XKGL_XKJG
set xkcgbz=#{dto.successFlag,jdbcType=VARCHAR},
ZHXGR =#{dto.editor,jdbcType=VARCHAR},
ZHXGRXM =#{dto.editorName,jdbcType=VARCHAR},
ZHXGSJ =#{dto.editeTime,jdbcType=DATE}
where xkjg_id in
<foreach collection="dto.electiveCourseResultIds" index="index" item="item"
open="(" separator="," close=")">
  #{item}
</foreach>
</update>

=======================

实现代码:从网上摘得一个例子(服务层得实现类下)

public void batchAddDevice(int sceneId, String list) {
    List<SceneDevice> sceneDevicesList = new ArrayList<>();
    Map deviceMap = new HashMap<>();
    Gson gson = new Gson();
    JSONArray jsonArray = JSONArray.fromObject(list);
    for(int i = 0;i < jsonArray.size(); i++){
        SceneDevice sceneDevice = new SceneDevice();
        String jsonString =  jsonArray.getString(i);
        deviceMap = gson.fromJson(jsonString, deviceMap.getClass());
        sceneDevice.setId(Integer.parseInt(deviceMap.get("id").toString()));
        sceneDevice.setSceneId(sceneId);
        sceneDevice.setDeviceId(Integer.parseInt(deviceMap.get("deviceId").toString()));
        sceneDevice.setPattern(deviceMap.get("pattern").toString());
        sceneDevicesList.add(sceneDevice);
    }
    curdRepo.batchAddDevice(sceneDevicesList);
}
其中crudRepo接口声明得方法是:
public void  batchAddDevice(@Param("list") List<SceneDevice> list);
解释:
@Param("list")表示传到Mapper中得集合名字叫做list

=======================================================================
注意:批量新增不能通过dblinke进行DDL操作,不然会报错

Mybatis之批量操作第1张

免责声明:文章转载自《Mybatis之批量操作》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java生鲜电商平台-提现模块的设计与架构eclipse如何把多个项目放在一个文件夹下下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Handler处理长时间事件

当我们在处理一些比较长时间的事件时候,比如读取网络或者数据库的数据时候,就要用到Handler,有时候为了不影响用户操作应用的流畅还要开多一个线程来区别UI线程,在新的线程里面处理长时间的操作。开发的时候遇到数据处理都可以这样用handler,灵活修改一下就可以做各种效果了。 第一步:ProgressDialog弹出旋转框来提示长时间操作。 第二步:开多一...

docker容器以非root用户启动应用

  docker容器启动应用默认的是root用户,可以使用ps命令来查看。很多的目录及文件权限是777,这些都是不安全的。        最近的一项工作就是要以非root用户启动docker,并且修改777权限为755.        在Dockefile中创建指定的用户xxx和用户组,然后用su-exec xxx  java ... 来启动应用,使用ps...

Android之RadioButton多行

RadioGroup设置orientation="vertical"竖向单列显示 RadioGroup设置orientation="horizontal"横向单行显示 如何实现多行多列RadioButton呢? step1:重写RadioGroup类 package com.hz.w504_sing_common; import java.util....

Asp.net2.0 VS 2005下的repeater控件本功能分页实例(共有 条记录 共有几页 当前第 页 首页,上一页,下一页,尾页 DropDownList跳转)

一、预览效果二、前台控件呈现部分 <asp:repeater id="LeaveMessage" runat="server" ><ItemTemplate><table width="100%" border="0" align="center" cellpadding="1" cellspacing="1" bgcolor=...

Ubuntu下设置开机自动挂载硬盘

Ubuntu下设置开机自动挂载硬盘       我们在linux中常常用mount命令把硬盘分区或者光盘挂载到文件系统中。/etc/fstab就是在开机引导的时候自动挂载到linux的文件系统。   如果给计算机配了一块新磁盘,已经分区,格式化,挂载,但当计算机重启后,然后我们想让计算机启动时自动挂载,方法就是修改文件 /etc/fstab,...

JS实现 Tab栏切换案例

要求:当鼠标点击上面相应的选项卡(tab),下面页面的内容也随之而改变。 结构分析:   全部的内容都放到一个大的盒子里面,盒子里面又可以分为上面和下面两个盒子。   上面的盒子放了 5个li,装着5个小的选项卡,默认会有一个被选中;   下面的盒子也包含了 5个 div 模块,模块内容与上面的选项一一对应,当前默认的只有第一个 div会被显示出来。 实现...