• Mybatis 动态SQL – 使用trim标签替代where,set标签


    前面几篇我们介绍了where,set标签的使用;本篇我们继续介绍如何使用Mybatis提供的tirm标签替代where,set标签。

    如果您对where,set标签不太了解,建议您先进行了解后再阅读本篇,可以参考:

    Mybatis 动态SQL – 使用if,where标签动态生成条件语句

    Mybatis 动态SQL – 使用if,set标签动态生成更新语句

    一、数据准备

    这里我们直接使用脚本初始化数据库中的数据

    1. -- 如果数据库不存在则创建数据库
    2. CREATE DATABASE IF NOT EXISTS demo DEFAULT CHARSET utf8;
    3. -- 切换数据库
    4. USE demo;
    5. -- 创建用户表
    6. CREATE TABLE IF NOT EXISTS T_TEACHER(
    7. ID INT PRIMARY KEY COMMENT '教师编号',
    8. TEACHER_NAME VARCHAR(64) NOT NULL COMMENT '教师名称',
    9. DEPARTMENT VARCHAR(16) NOT NULL COMMENT '所属部门',
    10. BIRTH DATE NOT NULL COMMENT '出生年月',
    11. DEGREE VARCHAR(16) NOT NULL COMMENT '学历(ZK:专科, BK:本科, YJS:研究生, BS:博士)'
    12. );
    13. -- 插入用户数据
    14. INSERT INTO T_TEACHER(ID, TEACHER_NAME, DEPARTMENT, BIRTH, DEGREE)
    15. VALUES(1, '张三1', '001', '1990-06-12', 'BK'),
    16. (2, '李四1', '002', '1992-05-10', 'BK'),
    17. (3, '张三2', '003', '1988-01-15', 'YJS'),
    18. (4, '李四2', '001', '1979-03-10', 'BK'),
    19. (5, '李四3', '003', '1995-08-16', 'YJS');

    创建了一个名称为demo的数据库;并在库里创建了名称为T_TEACHER的教师表并向表中插入了数据

    二、环境搭建

    1、创建实体类

    在cn.horse.demo下创建TeacherInfo实体类:

    TeacherInfo类:

    1. package cn.horse.demo;
    2. import java.time.LocalDate;
    3. public class TeacherInfo {
    4. private Integer id;
    5. private String name;
    6. private String department;
    7. private LocalDate birth;
    8. private String degree;
    9. public void setId(Integer id) {
    10. this.id = id;
    11. }
    12. public void setDepartment(String department) {
    13. this.department = department;
    14. }
    15. public void setDegree(String degree) {
    16. this.degree = degree;
    17. }
    18. @Override
    19. public String toString() {
    20. StringBuilder stringBuilder = new StringBuilder();
    21. stringBuilder.append("{ ");
    22. stringBuilder.append("id: ");
    23. stringBuilder.append(this.id);
    24. stringBuilder.append(", ");
    25. stringBuilder.append("name: ");
    26. stringBuilder.append(this.name);
    27. stringBuilder.append(", ");
    28. stringBuilder.append("department: ");
    29. stringBuilder.append(this.department);
    30. stringBuilder.append(", ");
    31. stringBuilder.append("birth: ");
    32. stringBuilder.append(this.birth);
    33. stringBuilder.append(", ");
    34. stringBuilder.append("degree: ");
    35. stringBuilder.append(this.degree);
    36. stringBuilder.append(" }");
    37. return stringBuilder.toString();
    38. }
    39. }

    2、Mapper配置文件

    在resources的目录下新建TeacherInfoMapper.xml配置文件

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="cn.horse.demo.TeacherInfoMapper">
    6. <select id="findById" resultType="cn.horse.demo.TeacherInfo">
    7. SELECT
    8. ID,
    9. TEACHER_NAME name,
    10. DEPARTMENT,
    11. BIRTH,
    12. DEGREE
    13. FROM T_TEACHER
    14. WHERE ID = #{id}
    15. select>
    16. <select id="findByQuery" parameterType="cn.horse.demo.TeacherInfoQuery" resultType="cn.horse.demo.TeacherInfo">
    17. SELECT
    18. ID,
    19. TEACHER_NAME name,
    20. DEPARTMENT,
    21. BIRTH,
    22. DEGREE
    23. FROM T_TEACHER
    24. <where>
    25. <if test="null != degree and '' != degree">
    26. AND DEGREE = #{degree}
    27. if>
    28. <if test="null != department and '' != department">
    29. AND DEPARTMENT = #{department}
    30. if>
    31. where>
    32. select>
    33. <update id="updateByEntity" parameterType="cn.horse.demo.TeacherInfo">
    34. UPDATE T_TEACHER
    35. <set>
    36. <if test="null != department and '' != department">
    37. DEPARTMENT = #{department},
    38. if>
    39. <if test="null != degree and '' != degree">
    40. DEGREE = #{degree},
    41. if>
    42. set>
    43. WHERE ID = #{id}
    44. update>
    45. mapper>

    3、引入配置文件

    在resources下新建mybatis-config.xml配置文件,并引入TeacherInfoMapper.xml配置文件

    1. "1.0" encoding="UTF-8" ?>
    2. configuration
    3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
    5. <configuration>
    6. <settings>
    7. <setting name="logImpl" value="JDK_LOGGING"/>
    8. settings>
    9. <environments default="development">
    10. <environment id="development">
    11. <transactionManager type="JDBC"/>
    12. <dataSource type="POOLED">
    13. <property name="driver" value="org.gjt.mm.mysql.Driver"/>
    14. <property name="url" value="jdbc:mysql://localhost:3306/demo?useUnicode=true&useSSL=false&characterEncoding=utf8"/>
    15. <property name="username" value="root"/>
    16. <property name="password" value="horse"/>
    17. dataSource>
    18. environment>
    19. environments>
    20. <mappers>
    21. <mapper resource="demo/TeacherInfoMapper.xml" />
    22. mappers>
    23. configuration>

    4、会话工具类

    在cn.horse.demo包下新建SqlSessionUtils工具类

    1. package cn.horse.demo;
    2. import org.apache.ibatis.session.SqlSession;
    3. import org.apache.ibatis.session.SqlSessionFactory;
    4. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    5. import java.io.InputStream;
    6. import java.util.Objects;
    7. public class SqlSessionUtils {
    8. private static final SqlSessionFactory sqlSessionFactory;
    9. static {
    10. // 读取mybatis配置文件
    11. InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
    12. // 根据配置创建SqlSession工厂
    13. sqlSessionFactory = new SqlSessionFactoryBuilder()
    14. .build(inputStream);
    15. }
    16. /**
    17. * 开启会话
    18. * @return
    19. */
    20. public static SqlSession openSession() {
    21. return sqlSessionFactory.openSession();
    22. }
    23. /**
    24. * 关闭会话
    25. * @param sqlSession
    26. */
    27. public static void closeSession(SqlSession sqlSession) {
    28. if(Objects.nonNull(sqlSession)) {
    29. sqlSession.close();
    30. }
    31. }
    32. }

    5、JDK 日志系统配置

    在resources的目录下新建logging.properties配置文件

    1. handlers=java.util.logging.ConsoleHandler
    2. .level=INFO
    3. cn.horse.demo.TeacherInfoMapper.level=FINER
    4. java.util.logging.ConsoleHandler.level=ALL
    5. java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
    6. java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tT.%1$tL %4$s %3$s - %5$s%6$s%n

    在cn.horse.demo下新建JdkLogConfig类:

    JdkLogConfig类:

    1. package cn.horse.demo;
    2. import java.io.IOException;
    3. import java.io.InputStream;
    4. import java.util.logging.LogManager;
    5. public class JdkLogConfig {
    6. public JdkLogConfig() {
    7. try {
    8. InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("logging.properties");
    9. LogManager.getLogManager().readConfiguration(inputStream);
    10. } catch (IOException e) {
    11. throw new RuntimeException(e);
    12. }
    13. }
    14. }

    6、启动程序

    1. package cn.horse.demo;
    2. import org.apache.ibatis.session.SqlSession;
    3. import java.util.List;
    4. public class Main {
    5. public static void main(String[] args) {
    6. // 引入JDK日志配置
    7. System.setProperty("java.util.logging.config.class", "cn.horse.demo.JdkLogConfig");
    8. // 查询学历为本科的教师
    9. TeacherInfoQuery query = new TeacherInfoQuery();
    10. query.setDegree("BK");
    11. findAll("cn.horse.demo.TeacherInfoMapper.findByQuery", query);
    12. // 更新编号为2的教师
    13. TeacherInfo teacherInfo = new TeacherInfo();
    14. teacherInfo.setId(2);
    15. teacherInfo.setDegree("BK");
    16. updateByEntity("cn.horse.demo.TeacherInfoMapper.updateByEntity", teacherInfo);
    17. // 查询编号为2的教师
    18. findById("cn.horse.demo.TeacherInfoMapper.findById", 2);
    19. }
    20. private static void findAll(String statement, TeacherInfoQuery query) {
    21. SqlSession sqlSession = null;
    22. try {
    23. sqlSession = SqlSessionUtils.openSession();
    24. List teacherInfoList = sqlSession.selectList(statement, query);
    25. for (TeacherInfo teacherInfo: teacherInfoList) {
    26. System.out.println(teacherInfo);
    27. }
    28. } finally {
    29. SqlSessionUtils.closeSession(sqlSession);
    30. }
    31. }
    32. private static void updateByEntity(String statement, TeacherInfo teacherInfo) {
    33. SqlSession sqlSession = null;
    34. try {
    35. sqlSession = SqlSessionUtils.openSession();
    36. sqlSession.update(statement, teacherInfo);
    37. sqlSession.commit();
    38. } finally {
    39. SqlSessionUtils.closeSession(sqlSession);
    40. }
    41. }
    42. private static void findById(String statement, Integer id) {
    43. SqlSession sqlSession = null;
    44. try {
    45. sqlSession = SqlSessionUtils.openSession();
    46. TeacherInfo teacherInfo = sqlSession.selectOne(statement, id);
    47. System.out.println(teacherInfo);
    48. } finally {
    49. SqlSessionUtils.closeSession(sqlSession);
    50. }
    51. }
    52. }

    执行后的结果如下:

    三、trim标签替代where标签

    之前我们介绍过where标签的两个作用:

    (1)判断是否存在条件,如果条件不存在,则不再拼接where;如果条件存在,则拼接where

    (2)剔除where后面多余的AND或OR

    下面我们给出where等效的trim标签配置:

    1. <trim prefix="where" prefixOverrides="AND | OR">
    2. trim>

    prefix属性:当trim标签中内容不为空时,则拼接prefix的属性值

    prefixOverrides属性:当trim标签中的内容以AND或OR开头时,则剔除AND或OR

    下面我们修改TeacherInfoMapper.xml配置文件中的findByQuery查询语句:

    1. <select id="findByQuery" parameterType="cn.horse.demo.TeacherInfoQuery" resultType="cn.horse.demo.TeacherInfo">
    2. SELECT
    3. ID,
    4. TEACHER_NAME name,
    5. DEPARTMENT,
    6. BIRTH,
    7. DEGREE
    8. FROM T_TEACHER
    9. <trim prefix="where" prefixOverrides="AND | OR">
    10. <if test="null != degree and '' != degree">
    11. AND DEGREE = #{degree}
    12. if>
    13. <if test="null != department and '' != department">
    14. AND DEPARTMENT = #{department}
    15. if>
    16. trim>
    17. select>

    测试:

    1. // 引入JDK日志配置
    2. System.setProperty("java.util.logging.config.class", "cn.horse.demo.JdkLogConfig");
    3. // 查询学历为研究生的教师
    4. TeacherInfoQuery query = new TeacherInfoQuery();
    5. query.setDegree("YJS");
    6. findAll("cn.horse.demo.TeacherInfoMapper.findByQuery", query);

    执行后的结果如下:

    四、trim标签替代set标签

    之前我们介绍过set标签可用于剔除更新语句中多余的逗号

    下面我们给出set等效的trim标签配置:

    1. <trim prefix="set" suffixOverrides=",">
    2. trim>

    prefix属性:当trim标签中内容不为空时,则拼接prefix的属性值

    suffixOverrides属性:当trim标签中的内容以逗号结束时,则剔除逗号

    下面我们修改TeacherInfoMapper.xml配置文件中的updateByEntity查询语句:

    1. <update id="updateByEntity" parameterType="cn.horse.demo.TeacherInfo">
    2. UPDATE T_TEACHER
    3. <trim prefix="set" suffixOverrides=",">
    4. <if test="null != department and '' != department">
    5. DEPARTMENT = #{department},
    6. if>
    7. <if test="null != degree and '' != degree">
    8. DEGREE = #{degree},
    9. if>
    10. trim>
    11. WHERE ID = #{id}
    12. update>

    测试:

    1. // 引入JDK日志配置
    2. System.setProperty("java.util.logging.config.class", "cn.horse.demo.JdkLogConfig");
    3. // 更新编号为2的教师
    4. TeacherInfo teacherInfo = new TeacherInfo();
    5. teacherInfo.setId(2);
    6. teacherInfo.setDegree("BK");
    7. updateByEntity("cn.horse.demo.TeacherInfoMapper.updateByEntity", teacherInfo);
    8. // 查询编号为2的教师
    9. findById("cn.horse.demo.TeacherInfoMapper.findById", 2);

    查询的结果如下:

  • 相关阅读:
    虹科分享 | 简单实用的CANopen介绍,看完你就明白了(2)——CANopen框架与七种服务类型
    如何用Java+SpringBoot+Vue构建一个靓车汽车销售网站?
    如何将数据库从 CloudKit 迁移到 Firebase
    第一个MyBatis程序
    kubeadm系列-02-kubelet的配置和启动
    MYsql库、表的管理和视图
    JMeter压测如何分配业务比例?
    LeetCode常见题型——树
    关于我写的IDEA插件能一键生成service,mapper....这件事(附源码)
    Node学习十五 —— 使用TLS/SSL提高安全性
  • 原文地址:https://blog.csdn.net/m1729339749/article/details/132830398