【Mybatis】(六)动态SQL

简介: 【Mybatis】(六)动态SQL

1、定义EmployeeMapperDynamicSQL接口


package com.lhk.mybatis.dao;
        import com.lhk.mybatis.bean.Employee;
        import org.apache.ibatis.annotations.Param;
        import java.util.List;
        public interface EmployeeMapperDynamicSQL {
            // 查询员工,要求携带了哪个字段查询字段就带上这个字段的值,测试where
            public List<Employee> getEmpByConditionIf(Employee employee);
            // 查询员工,测试Trim
            public List<Employee> getEmpByConditionTrim(Employee employee);
            // 查询员工,测试Choose,When,otherwise
            public List<Employee> getEmpByConditionChoose(Employee employee);
            // 更新员工信息
            public void updateEmp(Employee employee);
            // 插入员工信息
            public void insertEmp(Employee employee);
            // 通过foreach在指定集合中查询员工id
            public List<Employee> getEmpByConditionForeach(@Param("ids") List<Integer> id);
            // 通过foreach批量插入员工信息
            public void addEmp(@Param("emps") List<Employee> employee);
        }


2、定义EmployeeMapperDynamicSQL.xml配置文件


<?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.lhk.mybatis.dao.EmployeeMapperDynamicSQL">
        <!--
            • if 判断
            • choose (when, otherwise) 分支选择(带了break的switch-case)
                如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个
            • trim (where(封装查询条件), set(封装修改条件)) 字符串截取
            • foreach
        -->
        <resultMap id="Simple" type="com.lhk.mybatis.bean.Employee">
            <result column="last_name" property="lastName"></result>
        </resultMap>
        <!--查询员工,要求携带了哪个字段查询字段就带上这个字段的值
            getEmpByConditionIf
        -->
        <select id="getEmpByConditionIf" resultMap="Simple">
            select * from tb1_employee
    --         where
            <where>
                <!--
                测试where:
                1、当if条件不满足,即where元素中没有内容,在SQL语句中就不会出现where
                2、当if条件满足,where元素的内容是以and开头,where会自动去掉开头的and or,以保证where条件正确
                3、where不能解决SQL语句后面多出的and or,要通过trim解决
                test:判断表达式,从参数中取值进行判断-->
                <if test="id!=null">
                    id=#{id}
                </if>
                <if test="lastName!=null and lastName!=''">
                    and last_name like #{lastName}
                </if>
                <if test="email!=null and email.trim()!=''">
                    and email=#{email}
                </if>
                <if test="gender==0 and gender==1">
                    and gender=#{gender}
                </if>
            </where>
        </select>
        <!--通过Trim方式 getEmpByConditionTrim -->
        <select id="getEmpByConditionTrim" resultMap="Simple">
            select * from tb1_employee
            --         where
            <!--
                where,set标签的功能都可以通过Trim来实现
                解决SQL语句后面多出的and or,where标签不能解决
            <trim prefix="" 前缀,当trim元素内包含内容时,会给内容增加prefix指定的前缀
                  prefixOverrides="" 前缀覆盖,当trim元素内包含内容时,会把内容中匹配的前缀字符串去掉
                  suffix="" 后缀,当trim元素内包含内容时,会给内容增加suffix指定的后缀
                  suffixOverrides="" 后缀覆盖,当trim元素内包含内容时,会把内容中匹配的后缀字符串去掉
            </trim>
            -->
            <!--自定义字符串截取规则-->
            <!--在SQL语句前面添加where,去除SQL语句中后面多余的and -->
            <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and">
                <!-- test:判断表达式,从参数中取值进行判断-->
                <if test="id!=null">
                    id=#{id} and
                </if>
                <if test="lastName!=null and lastName!=''">
                    last_name like #{lastName} and
                </if>
                <if test="email!=null and email.trim()!=''">
                    email=#{email} and
                </if>
                <if test="gender==0 and gender==1">
                    gender=#{gender}
                </if>
            </trim>
        </select>
        <!--测试分支选择 getEmpByConditionChoose -->
        <select id="getEmpByConditionChoose" resultMap="Simple">
            select * from tb1_employee
            <where>
                <!-- 如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个 -->
                <choose>
                    <when test="id!=null">
                        id=#{id}
                    </when>
                    <when test="lastName!=null">
                        last_name like #{lastName}
                    </when>
                    <when test="email!=null">
                        email=#{email}
                    </when>
                    <otherwise>
                        gender=0
                    </otherwise>
                </choose>
            </where>
        </select>
        <!-- 测试update  updateEmp
            只更新要更新的值。为null的值就不更新
            set:1、如果该标签包含的元素中有返回值,就插入一个set
                 2、如果set后面的字符串是以逗号结尾,就删除这个逗号
                 3、如果set元素中没有内容,则仍然会出现SQL错误,所以id=#{id}仍有保留的必要
         -->
        <update id="updateEmp">
            update tb1_employee
            <set>
                <if test="lastName!=null">
                    last_name=#{lastName},
                </if>
                <if test="email!=null">
                    email=#{email},
                </if>
                <if test="gender!=null">
                  gender=#{gender}
                </if>
                id=#{id},
            </set>
            where id=#{id}
        </update>
        <!--测试insert insertEmp
            只插入要插入的值。为null的值就不插入。
            在列的部分增加if条件,则values的部分也要增加相同的if条件,
            必须保证上下相互对应,完全匹配
        -->
        <insert id="insertEmp">
            insert into tb1_employee(
            <if test="id!=null and id!=''">
                id,
            </if>
            <if test="lastName!=null and lastName!=''">
                last_name,
            </if>
            <if test="email!=null and email!=''">
                email,
            </if>
            <if test="gender!=null and gender!=''">
                gender
            </if>
            )
            <trim suffixOverrides=",">
                values(
                <if test="id!=null and id!=''">
                    #{id},
                </if>
                <if test="lastName!=null and lastName!=''">
                    #{lastName},
                </if>
                <if test="email!=null and email!=''">
                    #{email},
                </if>
                <if test="gender!=null and gender!=''">
                    #{gender}
                </if>
                )
            </trim>
        </insert>
        <!--测试foreach getEmpByConditionForeach-->
        <!--
            collection:指定要遍历的集合,
                   list类型的参数会特殊处理封装在map中,map的key就叫list
            item:将当前遍历出的元素赋值给指定的变量
            separate:每个元素之间的分隔符
            open:遍历出所有的结果拼接一个开始字符
            close:遍历出所有的结果拼接一个结束字符
            index:遍历list的时候,index是list的索引,item是list的值
                   遍历map的时候,index是map的key,item是map的值
        -->
        <select id="getEmpByConditionForeach" resultMap="Simple">
            select * from tb1_employee where id in
            <foreach collection="ids" item="item_id" separator="," open="(" close=")">
                #{item_id}
            </foreach>
        </select>
        <!-- 批量保存:addEmp-->
        <insert id="addEmp">
            insert into tb1_employee(last_name,email,gender,d_id)
            values
            <foreach collection="emps" item="emp" separator=",">
                (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
            </foreach>
        </insert>
    </mapper>


3、定义MybatisDynamicSQLTest测试类


package com.lhk.mybatis.test;
import com.lhk.mybatis.bean.Department;
import com.lhk.mybatis.bean.Employee;
import com.lhk.mybatis.dao.EmployeeMapperDynamicSQL;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MybatisDynamicSQLTest {
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "conf/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }
    /**
     * 测试If
     */
    @Test
    public void testgetEmpByConditionIf() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
            Employee employee = new Employee(2,"%e%","Jerry@qq.com","1");
            List<Employee> list = mapper.getEmpByConditionIf(employee);
            for (Employee emp : list) {
                System.out.println(emp);
            }
            //查询的时候如果某些条件没有,SQL拼装可能会出问题
            //1、给where后面加上1=1,以后的条件都and xxx
            //2、mybatis使用where标签将所有的查询条件包括在内
            //mybatis就会将where标签中的拼装的SQL中多的and,or去掉。只会去掉第一个多出来的and,or
        }finally {
            sqlSession.close();
        }
    }
    /**
     * 测试Trim
     */
    @Test
    public void testGetEmpByConditionTrim() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
            Employee employee = new Employee(null, "%e%", "Jerry@qq.com", "1");
            List<Employee> list = mapper.getEmpByConditionTrim(employee);
            for (Employee emp : list) {
                System.out.println(emp);
            }
        }finally {
            sqlSession.close();
        }
    }
    /**
     * 测试Choose
     */
    @Test
    public void testGetEmpByConditionChoose() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
            Employee employee = new Employee(null, null, "Jerry@qq.com", "1");
            List<Employee> list = mapper.getEmpByConditionChoose(employee);
            for (Employee emp : list) {
                System.out.println(emp);
            }
        }finally {
            sqlSession.close();
        }
    }
    /**
     * 测试set
     */
    @Test
    public void testUpdateEmp() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
            Employee employee = new Employee(null, null, null, null);
            mapper.updateEmp(employee);
            sqlSession.commit(); // 提交
        }finally {
            sqlSession.close();
        }
    }
    /**
     * 测试insert
     */
    @Test
    public void testInsertEmp() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
            Employee employee = new Employee(null, "lll", null, "0");
            mapper.insertEmp(employee);
            sqlSession.commit(); // 提交
        }finally {
            sqlSession.close();
        }
    }
    /**
     * 测试foreach实现in集合
     */
    @Test
    public void testGetEmpByConditionForeach() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
            List<Employee> list = mapper.getEmpByConditionForeach(Arrays.asList(2,6));
            for (Employee emp : list) {
                System.out.println(emp);
            }
        }finally {
            sqlSession.close();
        }
    }
    /**
     * 测试foreach实现批量插入
     */
    @Test
    public void testBatchSave() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
            List<Employee> emps = new ArrayList<>();
            emps.add(new Employee(null,"Smith","Smith@qq.com","1",new Department(1)));
            emps.add(new Employee(null,"Tom","Tom@qq.com","0",new Department(2)));
            mapper.addEmp(emps);
            sqlSession.commit(); //提交
        }finally {
            sqlSession.close();
        }
    }
}



目录
相关文章
|
4月前
|
SQL Java 测试技术
3、Mybatis-Plus 自定义sql语句
这篇文章介绍了如何在Mybatis-Plus框架中使用自定义SQL语句进行数据库操作。内容包括文档结构、编写mapper文件、mapper.xml文件的解释说明、在mapper接口中定义方法、在mapper.xml文件中实现接口方法的SQL语句,以及如何在单元测试中测试自定义的SQL语句,并展示了测试结果。
3、Mybatis-Plus 自定义sql语句
|
22天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
38 10
|
3月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
4月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
3月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
52 1
|
4月前
|
SQL Java 数据库连接
Mybatis系列之 动态SQL
文章详细介绍了Mybatis中的动态SQL用法,包括`<if>`、`<choose>`、`<when>`、`<otherwise>`、`<trim>`和`<foreach>`等元素的应用,并通过实际代码示例展示了如何根据不同条件动态生成SQL语句。
|
4月前
|
SQL Java 关系型数据库
SpringBoot 系列之 MyBatis输出SQL日志
这篇文章介绍了如何在SpringBoot项目中通过MyBatis配置输出SQL日志,具体方法是在`application.yml`或`application.properties`中设置MyBatis的日志实现为`org.apache.ibatis.logging.stdout.StdOutImpl`来直接在控制台打印SQL日志。
SpringBoot 系列之 MyBatis输出SQL日志
|
4月前
|
SQL 关系型数据库 MySQL
解决:Mybatis-plus向数据库插入数据的时候 报You have an error in your SQL syntax
该博客文章讨论了在使用Mybatis-Plus向数据库插入数据时遇到的一个常见问题:SQL语法错误。作者发现错误是由于数据库字段中使用了MySQL的关键字,导致SQL语句执行失败。解决方法是将这些关键字替换为其他字段名称,以避免语法错误。文章通过截图展示了具体的操作步骤。
|
5月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
95 3