MyBatis 教程

👉 所有文章
文章列表 准备工作 回顾 JDBC 数据准备 查找id为1的用户信息 自定义连接池 不用MyBatis配置文件 查询密码为123的所有用户 如果Bean中成员变量和表中字段命名不一致 更多查询用户的方式 对查询结果排序 日志 添加、删除、修改数据 事务 动态SQL 一对一和一对多的实现 一对一和一对多的延迟加载 多对多的实现 分页查询 把SQL写在注解中 自动生成Mapper代码和映射XML mybatis generator 生成 select for update mybatis generator 支持数据版本号

MyBatis: 动态SQL


动态SQL,是指SQL语句不是硬编码到代码中的,而是程序根据不同情况生成不同的SQL语句。MyBatis中动态SQL的内容还是挺多的,本文只做简单的介绍。更多内容请参考官方的《动态SQL》

本节示例代码在 mybatis-demo-011

数据准备

数据准备

user表的默认内容如下:

mysql> select * from user;
+----+--------+----------------+----------+
| id | name   | email          | password |
+----+--------+----------------+----------+
|  1 | letian | letian@111.com | 123      |
|  2 | xiaosi | xiaosi@111.com | 123      |
+----+--------+----------------+----------+

项目结构

使用 IDEA 创建 gradle 项目,最终结构如下:

示例1

在 UserMapper接口增加方法

/**
 * 根据用户名和密码查询用户。用户名可选
 */
User findByName(@Param("name") String name, @Param("optionalPassword") String password);

findByName 根据用户名和密码查询用户,其中用户名是必须的,密码是可选的。也就是,若没有密码,则SQL查询条件中不会有密码的判断。

在 UserMapper.xml 增加映射

<select id="findByName" resultType="bean.User">
    select * from blog_db.user
    where name=#{name}
    <if test="optionalPassword != null">
        and password = #{optionalPassword}
    </if>
</select>

<if>中判断 optionalPassword 是否为空,若不为空,则将and password = #{optionalPassword}作为SQL的一部分。

在Main类中增加示例代码

@Test
public void test_01() throws IOException {
    try (SqlSession sqlSession = getSqlSession()) {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findByName("letian", null);
        log.info("{}", user);
    }
}

@Test
public void test_02() throws IOException {
    try (SqlSession sqlSession = getSqlSession()) {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findByName("letian", "1234");
        log.info("{}", user);
    }
}

运行 test_01 ,输出:

 INFO [main] - User(id=1, name=letian, email=letian@111.com, password=123)

运行 test_02 ,输出:

 INFO [main] - null

示例2

在 UserMapper接口增加方法

/**
 * 根据查询条件查询所有符合要求的用户
 */
List<User> find(User queryCondition);

在 UserMapper.xml 增加映射

<select id="find" parameterType="bean.User" resultType="bean.User">
    select * from blog_db.user
    <where>
        <if test="id != null">
            and id = #{id}
        </if>
        <if test="name != null">
            and name = #{name}
        </if>
        <if test="email != null">
            and email = #{email}
        </if>
        <if test="password != null">
            and password = #{password}
        </if>
    </where>
</select>

这里用了 <where><if>,每个<if>中判断某个字段是否有值,若有值,则在查询条件中增加该字段的判等。注意,每个<if>中的最前面都是and,会不会动态生成的SQL中出现where and 这种错误的SQL?不会,mybatis会处理好这种情况。

在Main类中增加示例代码

@Test
public void test_03() throws IOException {
    try (SqlSession sqlSession = getSqlSession()) {
        User queryCondition = new User();
        queryCondition.setId(1L);
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.find(queryCondition);
        log.info("{}", userList);
    }
}

@Test
public void test_04() throws IOException {
    try (SqlSession sqlSession = getSqlSession()) {
        User queryCondition = new User();
        queryCondition.setPassword("123");
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.find(queryCondition);
        log.info("{}", userList);
    }
}

test_03中查询条件给了id,运行结果为:

 INFO [main] - [User(id=1, name=letian, email=letian@111.com, password=123)]

test_03`中查询条件给了password,运行结果为:

 INFO [main] - [User(id=1, name=letian, email=letian@111.com, password=123), User(id=2, name=xiaosi, email=xiaosi@111.com, password=123)]

得到两条记录,符合预期 😁


( 本文完 )

文章目录