Серия MyBatis (шесть): использование тега if в MyBatis dynamic Sql

MyBatis

В этом блоге в основном объясняется, как использовать тег if для создания динамического SQL, который в основном включает следующие три сценария:

  1. Реализовать динамический запрос в соответствии с условиями запроса
  2. Динамически обновлять некоторые столбцы на основе значений параметров
  3. Динамически вставлять определенные столбцы на основе значений параметров

1. Используйте тег if для реализации динамического запроса

Предположим, есть такое требование: запрашивать список пользователей в соответствии с условиями ввода пользователя. Если имя пользователя введено, имя пользователя используется для нечеткого запроса. Если введен почтовый ящик, точный запрос основан на почтовом ящике. эти два условия, чтобы соответствовать пользователям.

Сначала добавим в интерфейс SysUserMapper следующий метод:

/**
 * 根据动态条件查询用户信息
 *
 * @param sysUser
 * @return
 */
List<SysUser> selectByUser(SysUser sysUser);

Затем добавьте следующий код в соответствующий файл SysUserMapper.xml:

<select id="selectByUser" resultType="com.zwwhnly.mybatisaction.model.SysUser">
    SELECT  id,
            user_name,
            user_password,
            user_email,
            create_time
    FROM sys_user
    WHERE 1 = 1
    <if test="userName != null and userName != ''">
        AND user_name LIKE CONCAT('%',#{userName},'%')
    </if>
    <if test="userEmail != null and userEmail != ''">
        AND user_email = #{userEmail}
    </if>
</select>

Простое объяснение кода:

1) Обязателен тестовый атрибут тега if. Значением атрибута является выражение суждения, которое соответствует требованиям OGNL. Как правило, в качестве результата используется только значение "истина" или "ложь".

2) Свойство условия оценки != null или свойство == null, которое применимо к любому типу поля, используется для определения того, является ли значение свойства пустым.

3) Свойство условия оценки != '' или свойство == '' применимо только к полям типа String и используется для определения того, является ли это пустой строкой.

4) Когда есть несколько условий оценки, используйте и или или для соединения, вложенные оценки могут быть сгруппированы круглыми скобками и эквивалентны и (&&) в Java или связаны с или (||) в Java.

Таким образом, смысл приведенного выше кода заключается в том, чтобы сначала определить, является ли поле нулевым, а затем определить, является ли поле пустой строкой.

Наконец, добавьте следующий тестовый метод в тестовый класс SysUserMapperTest:

@Test
public void testSelectByUser() {
    SqlSession sqlSession = getSqlSession();

    try {
        SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);

        // 只按用户名查询
        SysUser query = new SysUser();
        query.setUserName("ad");
        List<SysUser> sysUserList = sysUserMapper.selectByUser(query);
        Assert.assertTrue(sysUserList.size() > 0);

        // 只按邮箱查询
        query = new SysUser();
        query.setUserEmail("test@mybatis.tk");
        sysUserList = sysUserMapper.selectByUser(query);
        Assert.assertTrue(sysUserList.size() > 0);

        // 同时按用户民和邮箱查询
        query = new SysUser();
        query.setUserName("ad");
        query.setUserEmail("test@mybatis.tk");
        sysUserList = sysUserMapper.selectByUser(query);
        // 由于没有同时符合这两个条件的用户,因此查询结果数为0
        Assert.assertTrue(sysUserList.size() == 0);
    } finally {
        sqlSession.close();
    }
}

Запустите тестовый код, тест пройден, и выходной журнал выглядит следующим образом:

DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_name LIKE CONCAT('%',?,'%')

DEBUG [main] - ==> Parameters: ad(String)

TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time

TRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0

DEBUG [main] - <== Total: 1

DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_email = ?

DEBUG [main] - ==> Parameters: test@mybatis.tk(String)

TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time

TRACE [main] - <== Row: 1001, test, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0

DEBUG [main] - <== Total: 1

DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_name LIKE CONCAT('%',?,'%') AND user_email = ?

DEBUG [main] - ==> Parameters: ad(String), test@mybatis.tk(String)

DEBUG [main] - <== Total: 0

2. Используйте тег if для динамического обновления

Предположим, есть такое требование: при обновлении информации о пользователе нельзя обновлять поля, которые изначально имели значения, но не изменились на null или null, то есть обновляются только поля со значениями.

Сначала добавим в интерфейс SysUserMapper следующий метод:

/**
 * 根据主键选择性更新用户信息
 *
 * @param sysUser
 * @return
 */
int updateByIdSelective(SysUser sysUser);

Затем добавьте следующий код в соответствующий файл SysUserMapper.xml:

<update id="updateByIdSelective">
    UPDATE sys_user
    SET
    <if test="userName != null and userName != ''">
        user_name = #{userName},
    </if>
    <if test="userPassword != null and userPassword != ''">
        user_password = #{userPassword},
    </if>
    <if test="userEmail != null and userEmail != ''">
        user_email = #{userEmail},
    </if>
    <if test="userInfo != null and userInfo != ''">
        user_info = #{userInfo},
    </if>
    <if test="headImg != null">
        head_img = #{headImg,jdbcType=BLOB},
    </if>
    <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
    </if>
    id = #{id}
    WHERE id = #{id}
</update>

Наконец, добавьте следующий тестовый метод в тестовый класс SysUserMapperTest:

@Test
public void testUpdateByIdSelective() {
    SqlSession sqlSession = getSqlSession();

    try {
        SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);

        SysUser sysUser = new SysUser();
        // 更新id=1的用户
        sysUser.setId(1L);
        // 修改邮箱
        sysUser.setUserEmail("test@mybatis.tk");

        int result = sysUserMapper.updateByIdSelective(sysUser);
        Assert.assertEquals(1, result);

        // 查询id=1的用户
        sysUser = sysUserMapper.selectById(1L);
        // 修改后的名字保持不变,但是邮箱变成了新的
        Assert.assertEquals("admin", sysUser.getUserName());
        Assert.assertEquals("test@mybatis.tk", sysUser.getUserEmail());
    } finally {
        sqlSession.close();
    }
}

Запустите тестовый код, тест пройден, и выходной журнал выглядит следующим образом:

DEBUG [main] - ==> Preparing: UPDATE sys_user SET user_email = ?, id = ? WHERE id = ?

DEBUG [main] - ==> Parameters: test@mybatis.tk(String), 1(Long), 1(Long)

DEBUG [main] - <== Updates: 1

DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE id = ?

DEBUG [main] - ==> Parameters: 1(Long)

TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time

TRACE [main] - <== Row: 1, admin, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0

DEBUG [main] - <== Total: 1

3. Используйте тег if для динамической вставки

Предположим, есть такое требование: при вставке данных в таблицу базы данных, если значение параметра столбца не пусто, используется входящее значение, а если значение входящего параметра пусто, используется значение по умолчанию в базе данных ( Обычно пустой), вместо того, чтобы использовать переданное нулевое значение.

Чтобы лучше понять пример, мы сначала установим значение по умолчанию для поля user_email таблицы sys_user: test@mybatis.tk, оператор Sql выглядит следующим образом:

ALTER TABLE sys_user
MODIFY COLUMN user_email VARCHAR(50) NULL DEFAULT  'test@mybatis.tk'
COMMENT '邮箱'
AFTER user_password;

Сначала добавим в интерфейс SysUserMapper следующий метод:

/**
 * 根据传入的参数值动态插入列
 *
 * @param sysUser
 * @return
 */
int insertSelective(SysUser sysUser);

Затем добавьте следующий код в соответствующий файл SysUserMapper.xml:

<insert id="insertSelective" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO sys_user(user_name, user_password,
    <if test="userEmail != null and userEmail != ''">
        user_email,
    </if>
    user_info, head_img, create_time)
    VALUES (#{userName},#{userPassword},
    <if test="userEmail != null and userEmail != ''">
        #{userEmail},
    </if>
    #{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})
</insert>

Наконец, добавьте следующий тестовый метод в тестовый класс SysUserMapperTest:

@Test
public void testInsertSelective() {
    SqlSession sqlSession = getSqlSession();

    try {
        SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);

        SysUser sysUser = new SysUser();
        sysUser.setUserName("test-selective");
        sysUser.setUserPassword("123456");
        sysUser.setUserInfo("test info");
        sysUser.setCreateTime(new Date());

        sysUserMapper.insertSelective(sysUser);

        // 获取刚刚插入的数据
        sysUser = sysUserMapper.selectById(sysUser.getId());
        // 因为没有指定userEmail,所以用的是数据库的默认值
        Assert.assertEquals("test@mybatis.tk", sysUser.getUserEmail());
    } finally {
        sqlSession.close();
    }
}

Запустите тестовый код, тест пройден, и выходной журнал выглядит следующим образом:

DEBUG [main] - ==> Preparing: INSERT INTO sys_user(user_name, user_password, user_info, head_img, create_time) VALUES (?,?, ?,?,?)

DEBUG [main] - ==> Parameters: test-selective(String), 123456(String), test info(String), null, 2019-07-08 11:40:36.927(Timestamp)

DEBUG [main] - <== Updates: 1

DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE id = ?

DEBUG [main] - ==> Parameters: 1021(Long)

TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time

TRACE [main] - <== Row: 1021, test-selective, 123456, test@mybatis.tk, 2019-07-08 11:40:37.0

DEBUG [main] - <== Total: 1

4. Исходный код и ссылка

Адрес источника:GitHub.com/Как Ухань, где/каждый шаг…, добро пожаловать на скачивание.

Лю Цзэнхуэй "MyBatis от входа до мастерства"