mybatis <foreach>标签动态增删改查方式
作者:如漩涡 发布时间:2022-07-27 20:03:16
<foreach>标签动态增删改查
mybatis<foreach>
有的时候在项目中需要查询某个列表时,可能会在代码中进行嵌套循环再取值,其实mybatis提供了这么一个标签,可以在SQL中进行循环(是不是很酸爽)
先来了解一下foreach这个标签有哪些元素:
item
:表示集合中每一个元素进行迭代时的别名index
:指定一个名字,用于表示在迭代过程中,每次迭代到的位置open
:表示该语句以什么开始separator
:表示在每次进行迭代之间以什么符号作为分隔符close
:表示以什么结束collection
:被循环的集合或者数组
注意:
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
如果传入的参数是多个的时候,我们就需要把它们封装成一个Map或者Object。
实战
话不多说,看代码,首先是mybatis的XML如何写,拿动态创建表为例子,什么是动态创建表,就是可以随便生成表名,字段是传入进来的集合数组,根据这个数组内容来创建字段
<update id="createTable" parameterType="java.util.HashMap">
CREATE TABLE IF NOT EXISTS ed_temp_${tableName}(
id VARCHAR(32) NOT NULL,
log_id VARCHAR(32),
state INT,
message VARCHAR(255)
<foreach collection="list" item="column" open="," separator="VARCHAR(255),"
close="VARCHAR(255), PRIMARY KEY (id)">
${column.name}
</foreach>
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
</update>
这个<foreach>看出,我传入的叫一个list的集合,别名叫column,从,开始,因为上面message少个逗号,中间用VARCHAR(255),做分隔符,已什么为结束都定义好了。
看Mapper类
/**
* 动态创建表
*/
void createTable(HashMap<String , Object> map);
看实现
/**
* 创建表
* @param templateId 模板id
*/
private void createTable(String templateId){
List<EdTemplateField> fields = edTemplateFieldMapper.findByTemplate(templateId);
List<EdFieldColumns> columns = new ArrayList<>();
HashMap<String,Object> map = new HashMap<>(16);
map.put("tableName",templateId);
for (EdTemplateField field : fields) {
columns.add(edFieldColumnsMapper.findByField(field.getId()).get(0));
}
map.put("list",columns);
edTemplateMapper.createTable(map);
}
逻辑是这样的,通过传入的ID,去寻找所需要的值,再创建一个List和一个Map,将表名放进来,在将需要的数组放进来,调用mapper的方法,最后就能成功创建一张动态表
往这个动态表里插入数据的方式也用到了<foreach>,应该说不得不用,不然怎么插入,又不知道表名又没有实体类
XML
<insert id="tableInsert" parameterType="java.util.HashMap">
INSERT INTO ed_temp_${tableName}(
id,log_id,state,message
<foreach collection="columns" item="column" open="," separator="," >
${column.name}
</foreach>
)VALUES(
<foreach collection="values" item="value" open="REPLACE(UUID(),'-','')," separator="," >
#{value}
</foreach>
)
</insert>
两个<foreach>标签,一个是字段,刚刚那个动态建表的字段,一个是值
mapper类
/**
* 动态插入
* @param map
*/
void tableInsert(HashMap<String,Object> map);
实现方法
/**
* 保存数据到临时表
* @param templateId 模板id
* @param list 数据集合
* @param hearTitle 数据对应的字段
*/
private void tableInsert(String templateId,List<String> list,List<String> hearTitle){
List<EdFieldColumns> columns = new ArrayList<>();
HashMap<String,Object> map = new HashMap<>(16);
map.put("tableName",templateId);
for (String s : hearTitle) {
columns.add(edFieldColumnsMapper.findByTemplateIdAndName(s,templateId));
}
map.put("columns",columns);
map.put("values",list);
edTemplateMapper.tableInsert(map);
}
说明
其余的类代码就不贴了,逻辑是这样的,创建一个放字段的集合和传入的map,集合的值必须要和字段对应的上,不然插错字段值那就很尴尬,所以必须要通过动态创建的字段和值的顺序是一样的,比如第一个创建了name那插入的第一个就是name,这个意思,所以这里是根据顺序,先排好了字段,放入map里,再将要放入动态表的值放进来,进行mapper操作
有了建表以及插入,当然少不了删除和更新
删除表的xml
<update id="deleteTable" parameterType="java.lang.String">
DROP TABLE ${tempTable}
</update>
<delete id="deleteTemporary">
DELETE
FROM
${tableName}
WHERE
id = #{id}
</delete>
用于来删除不需要的表,以及删除数据
void deleteTable(@param(value = "tempTable") String tempTable);
void deleteTemporary(@Param("tableName") String tableName,
@Param("id") String id);
这是mapper接口的写法,传入要删除的表名就可以
更新的XML
<update id="updateTemporary">
UPDATE ${tableName}
SET
<foreach collection="dataMap" index="key" item="value" separator="," >
${key} = #{value}
</foreach>
WHERE
id = #{id}
</update>
对应的mapper接口
void updateTemporary(@Param("tableName") String tableName,
@Param("id") String id,
@Param("dataMap") HashMap dataMap);
mapper.xml中<foreach>标签使用
循环参数内容,还具备在内容的前后添加内容,还具备添加分隔符功能。
适用场景
in 查询.批量新增中(mybatis 中 foreach 效率比较低)
1 如果希望批量新增,SQL 命令
insert into tableName VALUES (default,1,2,3),(default,4,5,6),(default,7,8,9)
2 openSession()必须指定底层 JDBC 的
PreparedStatement.addBatch();
factory.openSession(ExecutorType.BATCH);
来源:https://blog.csdn.net/m0_37701381/article/details/80254901


猜你喜欢
- 将数组元素反转有多种实现方式,这里介绍常见的三种.直接数组元素对换@Testpublic void testReverseSelf() th
- 本文实例讲述了Java基本数据类型与类型转换。分享给大家供大家参考,具体如下:相关内容:基本数据类型整型浮点型字符型布尔型数据类型转换数组首
- 概述在本文章中,我们对如何在 Java 中对 Array 和 List 进行转换进行一些说明和示例。这些示例通过使用 Core Java 和
- 1.URI与URLURI(Uniform Resource Identifier,统一资源标志符),表示web上的每一种可用资源,具体的东西
- 大家在使用APP的时候,有的APP在点击语音搜索界面后,会出现一个小话筒,小话筒会类似雷达似得在闪烁,表示正在倾听你说话的内容(这个大家可以
- 在工作中要求将图片上传至本地,如下代码将介绍如何将图片上传至本地准备工作:环境:eclipse4.5-x64,jdk1.7-x64,mave
- 关闭时可使用如下代码public static void waitUntilTerminate(final ExecutorService
- HttpClient模拟浏览器登录后发起请求浏览器实现这个效果需要如下几个步骤: 1请求一个需要登录的页
- 在Spring4之后,要使用注解开发,必须要保证aop的包导入了使用注解需要导入context约束,增加注解的支持!<?xml ver
- 一、抽象类是什么?在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的
- 线程池类图我们最常使用的Executors实现创建线程池使用线程主要是用上述类图中提供的类。在上边的类图中,包含了一个Executor框架,
- tokentoken的意思是“令牌”,是用户身份的验证方式,最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳
- 实现android双击后退键退出当前APP功能实现该功能基本思路是,1, 监听后退键 , 比较两次后退间隔 , 低于两秒则出发退出2, 退出
- 本文汇总了Spring的常用注解,以方便大家查询和使用,具体如下:使用注解之前要开启自动扫描功能其中base-package为需要扫描的包(
- 介绍主要使用了goole的zxing包,下面给出了示例代码,很方便大家的理解和学习,代码都属于初步框架,功能有了,需要根据实际使用情况完善优
- 前言在SpringIOC中,我们熟知的BeanScope有单例(singleton)、原型(prototype), Bean的Scope影响
- 今天接触了一下ToStringBuilder类,这里做一个备忘。ToStringBuilder在包 common-lang 中,主要用于一个
- 前言《JAVA打砖块》游戏是自制的游戏。玩家操作一根萤幕上水平的“棒子”,让一颗不断弹来弹去的&am
- 一、简介1.什么是GUID?全局唯一标识符(GUID,Globally Unique Identifier),GUID也称作 UUID(Un
- TimeSpan结构:表示一个时间间隔。它含有以下四个构造函数:TimeSpan(Int64)将 TimeSpan结构的新实例初始