服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - mybatis <foreach>标签动态增删改查方式

mybatis <foreach>标签动态增删改查方式

2022-09-15 17:22如漩涡 Java教程

这篇文章主要介绍了mybatis <foreach>标签动态增删改查方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

<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如何写,拿动态创建表为例子,什么是动态创建表,就是可以随便生成表名,字段是传入进来的集合数组,根据这个数组内容来创建字段

?
1
2
3
4
5
6
7
8
9
10
11
12
<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类

?
1
2
3
4
/**
     * 动态创建表
     */
    void createTable(HashMap<String , Object> map);

看实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    /**
     * 创建表
     * @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

?
1
2
3
4
5
6
7
8
9
10
11
12
    <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类

?
1
2
3
4
5
/**
     * 动态插入
     * @param map
     */
    void tableInsert(HashMap<String,Object> map);

实现方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
     * 保存数据到临时表
     * @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

?
1
2
3
4
5
6
7
8
9
10
<update id="deleteTable" parameterType="java.lang.String">
    DROP TABLE ${tempTable}
</update>
<delete id="deleteTemporary">
        DELETE
        FROM
             ${tableName}
        WHERE
            id = #{id}
    </delete>

用于来删除不需要的表,以及删除数据

?
1
2
3
void deleteTable(@param(value = "tempTable") String tempTable);
void deleteTemporary(@Param("tableName") String tableName,
                         @Param("id") String id);

这是mapper接口的写法,传入要删除的表名就可以

更新的XML

?
1
2
3
4
5
6
7
8
9
<update id="updateTemporary">
        UPDATE ${tableName}
        SET
        <foreach collection="dataMap" index="key" item="value"  separator="," >
            ${key} = #{value}
        </foreach>
        WHERE
            id = #{id}
    </update>

对应的mapper接口

?
1
2
3
 void updateTemporary(@Param("tableName") String tableName,
                         @Param("id") String id,
                         @Param("dataMap") HashMap dataMap);

mapper.xml中<foreach>标签使用

循环参数内容,还具备在内容的前后添加内容,还具备添加分隔符功能。

适用场景

in  查询.批量新增中(mybatis 中 foreach 效率比较低)

1 如果希望批量新增,SQL 命令

?
1
insert into tableName VALUES (default,1,2,3),(default,4,5,6),(default,7,8,9)

2 openSession()必须指定底层 JDBC 的

?
1
2
PreparedStatement.addBatch();   
factory.openSession(ExecutorType.BATCH);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/m0_37701381/article/details/80254901

延伸 · 阅读

精彩推荐
  • Java教程java高并发的用户线程和守护线程详解

    java高并发的用户线程和守护线程详解

    本篇文章主要介绍了浅谈java中守护线程与用户线程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    路人甲Java4152022-03-02
  • Java教程Java中BigDecimal除法使用不当导致精度问题

    Java中BigDecimal除法使用不当导致精度问题

    本文主要介绍了Java中BigDecimal除法使用不当导致精度问题,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    一灰灰8962022-03-09
  • Java教程java中dart类详细讲解

    java中dart类详细讲解

    这篇文章主要介绍了dart类详细讲解,实例讲解的很清晰,有对于这方面不太清楚的同学可以跟着学习下...

    流年少年10752021-08-06
  • Java教程java实现oracle插入当前时间的方法

    java实现oracle插入当前时间的方法

    这篇文章主要介绍了java实现oracle插入当前时间的方法,以实例形式对比分析了java使用Oracle操作时间的技巧,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    java潮人6792019-12-13
  • Java教程讲解ssm框架整合(最通俗易懂)

    讲解ssm框架整合(最通俗易懂)

    这篇文章主要介绍了讲解ssm框架整合(最通俗易懂),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    沸羊羊_5582020-09-20
  • Java教程java序列化和java反序列化示例

    java序列化和java反序列化示例

    在web项目开发的时候,经常用到序列化和反序列化用来传递大流量的数据,类只有实现Serializable借口才能被序列化,下来是java序列化和反序列化演示 ...

    java教程网4462019-10-30
  • Java教程Java @Pointcut注解表达式案例详解

    Java @Pointcut注解表达式案例详解

    这篇文章主要介绍了Java @Pointcut注解表达式案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    晚风丶寒雨3912021-12-16
  • Java教程在jetbrains官网上申请学生免费使用产品的权限

    在jetbrains官网上申请学生免费使用产品的权限

    JetBrains公司的产品非常好用,比如PyCharm(python开发的IDE)、WebStorm(前端开发神器)、IDEA(Java开发的IDE)、PhpStorm等等。当然这些软件都是收费的。如果你是一个学...

    lian_老练3142020-07-29