<foreach> tag of MyBatis dynamic SQL

Introduction

The foreach tag is used for loop statements, it supports the collection of data and List and set interfaces well, and provides the function of traversal.
For some SQL statements that contain in conditions and need to iterate the condition set to generate, you can use foreach to realize the iteration of SQL conditions.

select * 
from TABLE
where (id=1 or id=3 or id=4)

To query the data with ids 1, 3, and 4 in a table, you can store the data of these ids that need to be checked in a collection, and query these data by traversing the collection. In this case, we use foreach.

The foreach tag has six attributes : item, index, collection, open, close, separator

Attributes effect
item Indicates the alias for each element in the collection when iterating
index Specify a name to indicate the position of each iteration during the iteration process
open Indicates what the statement starts with (since it is an in conditional statement, it must start with '(')
close Indicates what the statement ends with (since it is an in conditional statement, it must end with ')'.
separator Indicates what symbol is used as a separator between each iteration (since it is an in conditional statement, it must use ',' as a separator).
collection This attribute is mandatory, but the value of this attribute is different in different situations, mainly in the following three situations:
(1) If a single parameter is passed in and the parameter type is a List, the value of the collection attribute is list
(2) If a single parameter is passed in and the parameter type is an array array, the attribute value of collection is array
(3) If there are multiple parameters passed in, they need to be encapsulated into a Map, of course, a single parameter can also be encapsulated into Map. The key of the Map is the parameter name, and the value of the collection attribute is the key of the passed List or array object in its encapsulated Map.

grammatical format

trim is generally used to remove redundant AND keywords and commas in SQL statements, or to add suffixes such as where and set to SQL statements, and can be used for selective insert, update, delete, or conditional queries. The trim syntax is as follows.

<foreach item="item" index="index" collection="list|array|map key" open="(" separator="," close=")">
    参数值
</foreach>

Network case

+----+----------------+----------------------------+-----+---------+---------------------+
| id | name           | url                        | age | country | createtime          |
+----+----------------+----------------------------+-----+---------+---------------------+
|  1 | 编程帮         | https://www.biancheng.net/ |  10 | CN      | 2021-02-23 10:20:40 |
|  2 | C语言中文网    | http://c.biancheng.net/    |  12 | CN      | 2021-03-08 11:23:27 |
|  3 | 百度           | https://www.baidu.com/     |  18 | CN      | 2021-03-08 11:23:53 |
|  4 | 淘宝           | https://www.taobao.com/    |  17 | CN      | 2021-03-10 10:33:54 |
|  5 | Google         | https://www.google.com/    |  23 | US      | 2021-03-10 10:34:34 |
|  6 | GitHub         | https://github.com/        |  13 | US      | 2021-03-10 10:34:34 |
|  7 | Stack Overflow | https://stackoverflow.com/ |  16 | US      | 2021-03-10 10:34:34 |
|  8 | Yandex         | http://www.yandex.ru/      |  11 | RU      | 2021-03-10 10:34:34 |
+----+----------------+----------------------------+-----+---------+---------------------+
<select id="selectWebsite"
    parameterType="net.biancheng.po.Website"
    resultType="net.biancheng.po.Website">
    SELECT id,name,url,age,country
    FROM website WHERE age in
    <foreach item="age" index="index" collection="list" open="("
        separator="," close=")">
        #{age}
    </foreach>
</select>

basic environment

1. Database preparation

# 创建一个名称为t_customer的表
CREATE TABLE t_customer (
    id int(32) PRIMARY KEY AUTO_INCREMENT,
    username varchar(50),
    jobs varchar(50),
    phone varchar(16)
);
# 插入3条数据
INSERT INTO t_customer VALUES ('1', 'joy', 'teacher', '13733333333');
INSERT INTO t_customer VALUES ('2', 'jack', 'teacher', '13522222222');
INSERT INTO t_customer VALUES ('3', 'tom', 'worker', '15111111111');

2. Create a new project or Module

insert image description here

3 Add in pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mybatis</artifactId>
        <groupId>com.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.biem</groupId>
    <artifactId>dynamaicSql</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--1.引入mybatis包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--2.单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--3.mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
            <scope>runtime</scope>
        </dependency>

        <!--4.log4j日志-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>
    </dependencies>
</project>

4. Create package and folder


Create package com.biem.pojo under src/main/java/
com.biem.mapper
com.biem.util
Create folder
com/ biem/mapper under src/main/resources/
Create package
com.biem under src/test/java .test

5 Framework configuration files

5.1 mybatis core configuration file mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入properties文件-->
    <properties resource="jdbc.properties"></properties>

    <!--将下划线映射为驼峰-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!--设置类型别名-->
    <typeAliases>
        <!--
            以包为单位,将包下所有的类型设置设置默认的类型别名,即类名且不区分大小写
        -->
        <package name="com.biem.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

    </environments>

    <!-- 引入映射文件 -->
    <mappers>
        <!--
            以包为单位引入映射文件
            要求:
            1. mapper接口所在的包要和映射文件所在的包一致
            2. mapper接口要和映射文件的名字一致
        -->
        <package name="com.biem.mapper"/>
    </mappers>


</configuration>

5.2 mybatis property file jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=root

5.3 log4j.xml file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n"/>
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug"/>
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info"/>
    </logger>
    <root>
        <level value="debug"/>
        <appender-ref ref="STDOUT"/>
    </root>
</log4j:configuration>

6 User Profiles

6.1 Entity class

package com.biem.pojo;

import lombok.*;

/**
 * ClassName: Customer
 * Package: com.biem.pojo
 * Description:
 *
 * @Create 2023/4/5 22:17
 * @Version 1.0
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class Customer {
    
    
    private Integer id;
    private String username;
    private String jobs;
    private String phone;
}

It is necessary to introduce lombok in pom.xml to simplify the code of the original entity class

6.2 mybatis interface class

package com.biem.mapper;

/**
 * ClassName: CustomerMapper
 * Package: com.biem.mapper
 * Description:
 *
 * @Create 2023/4/5 22:19
 * @Version 1.0
 */
public interface CustomerMapper {
    
    
}

6.3 mybatis user configuration file

<?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="com.biem.mapper.CustomerMapper">
    <!-- namespace要和mapper接口的全类名保持一致,例如com.biem.mybatis.mapper.xxxMapper -->

    <!-- sql语句要和接口的方法名保持一致 -->

</mapper>

6.4 mybatis tool class

package com.biem.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * ClassName: MybatisUtil
 * Package: com.biem.utils
 * Description:
 *
 * @Create 2023/4/5 22:23
 * @Version 1.0
 */
public class MybatisUtil {
    
    
    //利用static(静态)属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;
    //利用静态块在初始化类时实例化sqlSessionFactory
    static {
    
    
        InputStream is= null;
        try {
    
    
            is = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * openSession 创建一个新的SqlSession对象
     * @return SqlSession对象
     */
    public static SqlSession openSession(boolean autoCommit){
    
    
        return sqlSessionFactory.openSession(autoCommit);
    }

    public static SqlSession openSession(){
    
    
        return sqlSessionFactory.openSession();
    }
    /**
     * 释放一个有效的SqlSession对象
     * @param session 准备释放SqlSession对象
     */
    public static void closeSession(SqlSession session){
    
    
        if(session != null){
    
    
            session.close();
        }
    }
}

The project structure is as follows
insert image description here

foreach element iterates over an array

1 Add in com.biem.mapper.CustomerMapper.class

public List<Customer> findCustomerByArray(int [] ids);

2 Add in com/biem/mapper/CustomerMapper.xml

    <!--public List<Customer> findCustomerByArray(int [] arrays);-->
    <select id="findCustomerByArray" parameterType="java.util.Arrays" resultType="customer">
        select * from t_customer where id in
        <foreach item = "id" index = "index" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>

3. Functional test com.biem.test.TestMybatis.java

    @Test
    public void testFindCustomerByArray(){
    
    
        // 通过工具类获取SqlSession对象
        SqlSession session = MybatisUtil.openSession();
        int[] ids={
    
    1,3};
        CustomerMapper mapper = session.getMapper(CustomerMapper.class);
        List<Customer> customers = mapper.findCustomerByArray(ids);
        System.out.println("customers = " + customers);
        // 关闭SqlSession
        session.close();
    }

foreach element iteration List

1 Add in com.biem.mapper.CustomerMapper.class

public List<Customer> findCustomerByList(List<Integer> ids);

2 Add in com/biem/mapper/CustomerMapper.xml

    <!--public List<Customer> findCustomerByList(List<Integer> ids);-->
    <select id="findCustomerByList" parameterType="java.util.List" resultType="customer">
        select * from t_customer where id in
        <foreach item = "id" index = "index" collection="list" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>

3. Functional test com.biem.test.TestMybatis.java

@Test
    public void testFindCustomerByList(){
    
    
        // 通过工具类获取SqlSession对象
        SqlSession session = MybatisUtil.openSession();
        List<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);
        CustomerMapper mapper = session.getMapper(CustomerMapper.class);
        List<Customer> customers = mapper.findCustomerByList(ids);
        System.out.println("customers = " + customers);
        // 关闭SqlSession
        session.close();
    }

foreach element iteration Map

1 Add in com.biem.mapper.CustomerMapper.class

public List<Customer> findCustomerByMap(Map<String, Object> map);

2 Add in com/biem/mapper/CustomerMapper.xml

    <!--public List<Customer> findCustomerByMap(Map<String, Object> map);-->
    <select id="findCustomerByMap" parameterType="java.util.Map" resultType="customer">
        select * from t_customer where jobs=#{jobs} and id in
        <foreach item = "ids" index = "index" collection="id" open="(" separator="," close=")">
            #{ids}
        </foreach>
    </select>

Analysis: Use the foreach tag to iterate the Map collection. Since the incoming parameter is of the Map type, you need to obtain the corresponding value according to the key in SQL. In the above statement, #{jobs} obtains the value whose key is jobs in the Map collection value, while collection="id" gets the value of the value corresponding to key="id" in the Map collection.

3. Functional test com.biem.test.TestMybatis.java

    @Test
    public void testFindCustomerByMap(){
    
    
        // 通过工具类获取SqlSession对象
        SqlSession session = MybatisUtil.openSession();
        List<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        Map<String, Object> maps = new HashMap<>();
        maps.put("id", ids);
        maps.put("jobs","teacher");
        CustomerMapper mapper = session.getMapper(CustomerMapper.class);
        List<Customer> customers = mapper.findCustomerByMap(maps);
        System.out.println("customers = " + customers);
        // 关闭SqlSession
        session.close();
    }

Guess you like

Origin blog.csdn.net/yandao/article/details/129985425