【MyBatis】(4)動態SQL

前言

該文章記錄了MaBatis動態SQL常用標籤。

一、動態SQL 介紹

動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。

使用動態 SQL 並非一件易事,但藉助可用於任何 SQL 映射語句中的強大的動態 SQL 語言,MyBatis 顯著地提升了這一特性的易用性。

如果你之前用過 JSTL 或任何基於類 XML 語言的文本處理器,你對動態 SQL 元素可能會感覺似曾相識。在 MyBatis 之前的版本中,需要花時間瞭解大量的元素。藉助功能強大的基於 OGNL 的表達式,MyBatis 3 替換了之前的大部分元素,大大精簡了元素種類,現在要學習的元素種類比原來的一半還要少。

  1. if
  2. choose (when, otherwise)
  3. trim (where, set)
  4. foreach

動態sql就是:可以通過標籤動態的拼接sql命令。

官方文檔 介紹的挺不錯的,我這邊將給出一些動態sql的增刪改查實踐。

二、動態SQL 案例

該案例實現了用戶的增刪改查。

1.實體類

實體類:使用了lombok

@Data
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String password;
    private int age;
    private String phone;
    private String email;
}

2.接口

UserMapper接口

public interface UserMapper {
    int insUser(User u);

    int delUserById(int id);

    int delUserByIds(String[] id);

    int updUser(User u);

    User selUserById(int id);

    List<User> selUserList(User user);
}

3.xml映射文件

xml映射文件,將動態SQL添加上去了。可以把下面這個當作一個模板來使用

<?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.shengjava.mapper.UserMapper">
    <!-- 結果映射 -->
    <resultMap id="userResultMap" type="User">
        <id property="id" column="user_id"/>
        <result property="name" column="user_name"/>
        <result property="password" column="user_password"/>
        <result property="age" column="user_age"/>
        <result property="phone" column="user_phone"/>
        <result property="email" column="user_email"/>
    </resultMap>
    <!-- 插入語句 -->
    <insert id="insUser" parameterType="User">
        insert into user
        <!-- 動態拼接 -->
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">user_id,</if>
            <if test="name != null">user_name,</if>
            <if test="password != null">user_password,</if>
            <if test="age != null">user_age,</if>
            <if test="phone != null">user_phone,</if>
            <if test="email != null">user_email</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">#{id},</if>
            <if test="name != null">#{name},</if>
            <if test="password != null">#{password},</if>
            <if test="age != null">#{age},</if>
            <if test="phone != null">#{phone},</if>
            <if test="email != null">#{email},</if>
        </trim>
    </insert>
    <!-- 刪除語句 -->
    <delete id="delUserById" parameterType="int">
        delete
        from user
        where user_id = #{id};
    </delete>
    <!-- 刪除語句 -->
    <delete id="delUserByIds" parameterType="String">
        delete
        from user
        where user_id in
        <!-- 動態拼接(遍歷) -->
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
    <!-- 修改語句 -->
    <update id="updUser" parameterType="User">
        update user
        <trim prefix="SET" suffixOverrides=",">
            <if test="name != null">user_name = #{name},</if>
            <if test="password != null">user_password = #{password},</if>
            <if test="age != null">user_age = #{age},</if>
            <if test="phone != null">user_phone = #{phone},</if>
            <if test="email != null">user_email = #{email},</if>
        </trim>
        where user_id = #{id}
    </update>
    <!-- sql查詢語句片段 -->
    <sql id="selUser">
        select user_id, user_name, user_password, user_age, user_phone, user_email
        from user
    </sql>
    <!-- 根據id查詢用戶信息 -->
    <select id="selUserById" parameterType="int" resultMap="userResultMap">
        <!-- 引入sql語句片段 -->
        <include refid="selUser"/>
        where user_id = #{id}
    </select>
    <!-- 查詢複合條件的用戶列表(如果傳入空用戶,則查詢全部) -->
    <select id="selUserList" resultMap="userResultMap" parameterType="User">
        <include refid="selUser"/>
        <!-- where語句 -->
        <where>
            <!-- 動態拼接 -->
            <if test="id != null ">and user_id = #{id}</if>
            <if test="name != null ">and user_name = #{name}</if>
            <if test="password != null ">and user_password = #{password}</if>
            <if test="age != null ">and user_age = #{age}</if>
            <if test="phone != null ">and user_phone = #{phone}</if>
            <if test="email != null ">and user_email = #{email}</if>
        </where>
    </select>
</mapper>

測試類:
測試增刪改查,不過需要注意,需要手動提交一下事務。

public class MyBatisTest {
    SqlSessionFactory sqlSessionFactory;

    @Before
    public void before() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void insert() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            int insCount = 0;
            User user = new User(101, "zhangsan", "123456", 22, "18812341234", "[email protected]");
            insCount += mapper.insUser(user);
            /*for (int id = 102; id <= 105; id++) {
                User u = new User(id, "zhangsan", "123456", 22, "18812341234", "[email protected]");
                insCount += mapper.insUser(u);
            }*/
            // 提交事務
            session.commit();
            System.out.println("成功插入條數:" + insCount);
        }
    }

    @Test
    public void deleteById() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            int i = mapper.delUserById(101);
            // 提交事務
            session.commit();
            System.out.println("成功刪除條數:" + i);
        }
    }

    @Test
    public void deleteByIds() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            String[] ids = {"102", "103", "104", "105"};
            int i = mapper.delUserByIds(ids);
            // 提交事務
            session.commit();
            System.out.println("成功刪除條數:" + i);
        }
    }
    @Test
    public void upd() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = new User(101, "updatezhangsan", "update123456", 55, "update18812341234", "[email protected]");
            int i = mapper.updUser(user);
            // 提交事務
            session.commit();
            System.out.println("成功修改條數:" + i);
        }
    }
    @Test
    public void select() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selUserById(1);
            System.out.println(user);
        }
    }
    @Test
    public void selectList() {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            // 查詢全部則直接傳null,如果需要查詢指定值則創建User對象並賦值即可
            List<User> users = mapper.selUserList(null);
            System.out.println(users);
        }
    }
}

參考

官方文檔:動態 SQL


相關

我的該分類的其他相關文章,請點擊:【Spring + Spring MVC + MyBatis】文章目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章