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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 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


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
druid Java 数据库连接
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
SpringBoot原理分析 | Spring Data整合:JDBC、Druid、Mybatis
445 0
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
489 0
|
SQL Oracle 数据库
使用访问指导(SQL Access Advisor)优化数据库业务负载
本文介绍了Oracle的SQL访问指导(SQL Access Advisor)的应用场景及其使用方法。访问指导通过分析给定的工作负载,提供索引、物化视图和分区等方面的优化建议,帮助DBA提升数据库性能。具体步骤包括创建访问指导任务、创建工作负载、连接工作负载至访问指导、设置任务参数、运行访问指导、查看和应用优化建议。访问指导不仅针对单条SQL语句,还能综合考虑多条SQL语句的优化效果,为DBA提供全面的决策支持。
362 11
|
SQL Java 关系型数据库
spring data elasticsearch 打印sql(DSL)语句
spring data elasticsearch 打印sql(DSL)语句
1143 0
|
XML Java 关系型数据库
IDEA 报错: java.sql.SQLException: Access denied for user ‘root ‘@‘localhost‘ (using password: YES)
IDEA 报错: java.sql.SQLException: Access denied for user ‘root ‘@‘localhost‘ (using password: YES)
2949 0
|
SQL 存储 机器学习/深度学习
将 AWS Data Lake 和 S3 与 SQL Server 结合使用
将 AWS Data Lake 和 S3 与 SQL Server 结合使用
288 0
|
SQL 存储 数据可视化
access sql 数据库,Access SQL
access sql 数据库,Access SQL
解决java.sql.SQLException: Access denied for user ‘Lenovo‘@‘localhost‘ (using password: YES)问题~
解决java.sql.SQLException: Access denied for user ‘Lenovo‘@‘localhost‘ (using password: YES)问题~
533 0
|
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类型。
|
SQL XML Java
MyBatis第四课动态SQL
MyBatis第四课动态SQL