Data Access 之 MyBatis(四) - Dynamic SQL(上)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Data Access 之 MyBatis(四) - Dynamic SQL

一、动态SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

新建数据库表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_teacher
-- ----------------------------
DROP TABLE IF EXISTS `t_teacher`;
CREATE TABLE `t_teacher` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `teacher_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `class_name` varchar(255) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `birth_date` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_teacher
-- ----------------------------
BEGIN;
INSERT INTO `t_teacher` VALUES (1, 'stark', '三年二班', '浦东', '2022-02-13');
INSERT INTO `t_teacher` VALUES (2, 'steve', '三年三班', '静安', '2022-02-12');
INSERT INTO `t_teacher` VALUES (3, 'clint', '三年四班', '黄埔', '2022-02-11');
INSERT INTO `t_teacher` VALUES (4, 'banner', '三年二班', '静安', '2022-02-16');
INSERT INTO `t_teacher` VALUES (5, 'thor', '三年四班', '浦东', '2022-02-16');
INSERT INTO `t_teacher` VALUES (6, 'strange', '三年三班', '黄埔', '2022-02-16');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
复制代码

工程搭建

创建一个maven项目mybatis-dynamic-sql,加入相关依赖

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.18</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
复制代码

在resource目录下新增数据库信息配置文件db.properties

jdbc_driver=com.mysql.cj.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
jdbc_username=root
jdbc_password=root
复制代码

在resource目录下新增MyBatis全局配置文件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 resource="db.properties" />
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!--设置默认指向的数据库-->
    <environments default="dev">
        <!--配置环境,不同的环境不同的id名字-->
        <environment id="dev">
            <!-- 采用JDBC方式对数据库事务进行commit/rollback -->
            <transactionManager type="JDBC"></transactionManager>
            <!--采用连接池方式管理数据库连接-->
            <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>
</configuration>
复制代码

在resource目录下新增logback.xml日志配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
       <encoder>
           <pattern>[%thread] %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
       </encoder>
   </appender>
    <root level="debug">
        <appender-ref ref="console"/>
    </root>
</configuration>
复制代码

新建entity包,增加Teacher实体类,对应t_teacher表

@Data
public class Teacher {
    private Integer id;
    private String teacherName;
    private String className;
    private String address;
    private Date birthDate;
}
复制代码

在mapper包中新增TeacherMapper接口,并增加一个方法

public interface TeacherMapper {
    Teacher getTeacherById(Integer id);
}
复制代码

在resources目录下新建mappers文件夹,新增SQL映射文件 TeacherMapper.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.citi.mapper.TeacherMapper">
    <select id="getTeacherById" resultType="com.citi.entity.Teacher">
        select * from t_teacher where id = #{id}
    </select>
</mapper>
复制代码

在MyBatis全局配置文件mybatis-config.xml中注册TeacherMapper.xml

<mappers>
    <mapper resource="mappers/TeacherMapper.xml"/>
</mappers>
复制代码

在test包下新增TeacherMapperTest类,对getTeacherById方法测试

public class TeacherMapperTest {
    SqlSessionFactory sqlSessionFactory = null;
    SqlSession openSession = null;
    @Before
    public void setUp() throws Exception {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        openSession = sqlSessionFactory.openSession();
    }
    @Test
    public void getTeacherById() {
        TeacherMapper teacherMapper = openSession.getMapper(TeacherMapper.class);
        Teacher teacher = teacherMapper.getTeacherById(1);
        System.out.println(teacher);
    }
}
复制代码

执行该测试方法

f5f9c36ed7b54c2db8352d9c18f2f0c5_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

if,判断条件

if标签可以对WHERE关键字后面的条件进行判断,通过test属性进行条件判断

在TeacherMapper中新增一个方法,根据条件获取Teacher列表

List<Teacher> getTeacherList(Teacher teacher);
复制代码

在TeacherMapper.xml中新增SQL语句

<select id="getTeacherList" resultType="com.citi.entity.Teacher">
    select * from t_teacher where
    <!--test="",编写判断条件 id!= null,取出传入的JavaBean属性中ID的值,判断是否为空-->
    <if test="id!=null">
        id > #{id} and
    </if>
    <if test="className!=null">
        class_name like #{className} and
    </if>
    <if test="birthDate!=null">
        birth_date &lt; #{birthDate}
    </if>
</select>
复制代码

如果判断的test=true则加入if标签内的查询条件,test=false就忽略该if标签下的查询条件。一些判断的字符如大于、小于、&&等可以参考HTML ISO 8859-1

在TeacherMapperTest中新增测试方法

@Test
public void getTeacherList() {
    TeacherMapper teacherMapper = openSession.getMapper(TeacherMapper.class);
    Teacher teacher = new Teacher();
    teacher.setId(1);
    teacher.setClassName("三年%");
    teacher.setBirthDate(new Date());
    List<Teacher> teacherList = teacherMapper.getTeacherList(teacher);
    System.out.println(teacherList);
}
复制代码

执行测试,查看控制台输出的SQL语句

fc38c314b8f147cfb2138d3606db1e00_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
SQL Oracle 数据库
使用访问指导(SQL Access Advisor)优化数据库业务负载
本文介绍了Oracle的SQL访问指导(SQL Access Advisor)的应用场景及其使用方法。访问指导通过分析给定的工作负载,提供索引、物化视图和分区等方面的优化建议,帮助DBA提升数据库性能。具体步骤包括创建访问指导任务、创建工作负载、连接工作负载至访问指导、设置任务参数、运行访问指导、查看和应用优化建议。访问指导不仅针对单条SQL语句,还能综合考虑多条SQL语句的优化效果,为DBA提供全面的决策支持。
28 11
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
27天前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
2月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
54 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标签的用法
|
2月前
|
SQL 存储 机器学习/深度学习
将 AWS Data Lake 和 S3 与 SQL Server 结合使用
将 AWS Data Lake 和 S3 与 SQL Server 结合使用
70 0
|
3月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
67 1
|
4月前
|
SQL 流计算
Flink SQL 在快手实践问题之使用Dynamic Cumulate Window绘制直播间累计UV曲线如何解决
Flink SQL 在快手实践问题之使用Dynamic Cumulate Window绘制直播间累计UV曲线如何解决
77 1
|
5月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
106 3
|
5月前
|
SQL Java 数据库连接
mybatis动态SQL常用语法总结
MyBatis 使用 OGNL 表达式语言处理动态SQL,如 `if` 标签进行条件判断,`choose`、`when`、`otherwise` 实现多条件选择,`where`、`set` 管理SQL关键字,`trim` 提供通用修剪功能,`foreach` 遍历集合数据。`sql` 和 `include` 用于代码重用,`selectKey` 处理插入后的返回值。参数传递支持匿名、具名、列表、Map、Java Bean和JSON方式。注意SQL转义及使用合适的jdbcType映射Java类型。
110 7