<where> tag of MyBatis dynamic SQL -

Introduction

The where tag is mainly used to simplify conditional judgment in SQL statements, and can automatically handle AND/OR conditions.
In the case of the if tag and the choose-when-otherwise tag, a condition '1=1' is added to the SQL statement, which not only ensures that the condition after where is successful, but also avoids that the first word after where is and or keywords like or.
Assuming that the condition '1=1' is removed, the following statement can appear

select * from t_customer where and username like concat('%','#{username}','%')

The above statement is directly followed by and because where appears, and a syntax error will be reported when SQL is running.
At this time, you can use the where tag to process

grammar

<where>
    <if test="判断条件">
        AND/OR ...
    </if>
</where>

When the judgment condition in the if statement is true, the where keyword will be added to the assembled SQL, otherwise it will not be added. where will retrieve the statement, it will remove the AND or OR keywords of the first SQL conditional statement after where.

Network case

<select id="selectWebsite" resultType="net.biancheng.po.Website">
    select id,name,url from website
    <where>
        <if test="name != null">
            AND name like #{name}
        </if>
        <if test="url!= null">
            AND url like #{url}
        </if>
    </where>
</select>

where tag - complete case

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

7 Label function test

When the judgment condition in the if statement is true, the where keyword will be added to the assembled SQL, otherwise it will not be added. where will retrieve the statement, it will remove the AND or OR keywords of the first SQL conditional statement after where.

7.1 Added in com.biem.mapper.CustomerMapper.class

    public List<Customer> findCustomerByIf(Customer customer);

    public List<Customer> findCustomerByWhere(Customer customer);

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

<!-- public List<Customer> findCustomerByIf(Customer customer);-->
    <select id="findCustomerByIf" parameterType="customer" resultType="customer">
        select * from t_customer where
        <if test="username !=null and username != ''">
            and username like concat('%', #{username}, '%')
        </if>
        <if test="jobs !=null and jobs != ''">
            and jobs=#{jobs}
        </if>
    </select>

    <!-- public List<Customer> findCustomerByWhere(Customer customer);-->
    <select id="findCustomerByWhere" parameterType="customer" resultType="customer">
        select * from t_customer
        <where>
            <if test="username !=null and username != ''">
                and username like concat('%', #{username}, '%')
            </if>
            <if test="jobs !=null and jobs != ''">
                and jobs=#{jobs}
            </if>
        </where>

8 Functional test

Create class com.biem.test.TestCustomer.java in src/test/java, the content is as follows

package com.biem.test;

import com.biem.mapper.CustomerMapper;
import com.biem.pojo.Customer;
import com.biem.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * ClassName: TestCustomer
 * Package: com.biem.test
 * Description:
 *
 * @Create 2023/4/5 22:32
 * @Version 1.0
 */
public class TestCustomer {
    
    


    @Test
    public void testFindCustomerByIf(){
    
    
        // 通过工具类获取SqlSession对象
        SqlSession session = MybatisUtil.openSession();
        // 创建Customer对象,封装需要组合查询的条件
        Customer customer = new Customer();
        customer.setJobs("teacher");

        CustomerMapper mapper = session.getMapper(CustomerMapper.class);
        List<Customer> customers = mapper.findCustomerByIf(customer);

        System.out.println("customers = " + customers);

        // 关闭SqlSession
        session.close();
    }

    @Test
    public void testFindCustomerByWhere(){
    
    
        // 通过工具类获取SqlSession对象
        SqlSession session = MybatisUtil.openSession();
        // 创建Customer对象,封装需要组合查询的条件
        Customer customer = new Customer();
        customer.setJobs("teacher");

        CustomerMapper mapper = session.getMapper(CustomerMapper.class);
        List<Customer> customers = mapper.findCustomerByWhere(customer);

        System.out.println("customers = " + customers);

        // 关闭SqlSession
        session.close();
    }

}

Result analysis: testFindCustomerByIf will report an error due to a syntax error when the username is null

com.biem.test.TestCustomer,testFindCustomerByIf
DEBUG 04-06 09:56:24,100 ==>  Preparing: select * from t_customer where and jobs=?  (BaseJdbcLogger.java:159) 
DEBUG 04-06 09:56:24,152 ==> Parameters: teacher(String) (BaseJdbcLogger.java:159) 

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'and jobs='teacher'' at line 4
### The error may exist in com/biem/mapper/CustomerMapper.xml
### The error may involve com.biem.mapper.CustomerMapper.findCustomerByIf-Inline
### The error occurred while setting parameters
### SQL: select * from t_customer where                                 and jobs=?

Guess you like

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