mybatis學習筆記(四):動態 SQL 語句完成 增、刪、改、查


接上一篇文章:mybatis學習筆記(三):分頁查詢

其中 db.properties、mybatis.xml、Student.java、MybatisUtils.java 不變;


修改數據庫數據爲:

修改 StudentMapper.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="studentNamespace">

    <!-- resultMap 標籤:映射實體與表的關係 -->
    <resultMap id="studentMap" type="com.mybatis.demo.Student">
        <id property="sid" column="id"/>
        <result property="sname" column="name"/>
        <result property="ssal" column="sal"/>
    </resultMap>

    <!-- 動態查詢:pid、pname、psal 是傳入的 map 集合中的 key -->
    <select id="findAllBySynSQL" parameterType="map" resultType="com.mybatis.demo.Student" resultMap="studentMap">
        select id,name,sal from students
        <where>
            <if test="pid != null">
                and id = #{pid}
            </if>
            <if test="pname != null">
                and name = #{pname}
            </if>
            <if test="psal != null">
                and sal = #{psal}
            </if>
        </where>
    </select>

    <!-- 動態更新:set 標籤會自動判斷哪個是最後一個字段,然後去掉其後面的逗號 -->
    <update id="updateBySynSQL" parameterType="map">
        update students
        <set>
            <if test="pname != null">
                name = #{pname},
            </if>
            <if test="psal != null">
                sal = #{psal},
            </if>
        </set>
        where id = #{pid}
    </update>

    <!-- 動態刪除:數組版本 -->
    <delete id="deleteBySynSQLArray">
        delete from students where id in
        <!--
            foreache 標籤用於迭代數組元素:
                collection:表示迭代的集合是一個數組;
                open:表示封裝迭代元素的開始符號;
                close:表示封裝迭代元素的結束符號;
                separator:表示封裝迭代元素的分隔符,以逗號分隔;
                item:用於接收迭代的數組;理論上可以隨便寫,但是 #{} 中的值必須和要 item 的值一致;
                    例如 item="xxxx",#{xxxx} 也可以;但是建議寫成和傳入的參數名一致,增加可讀性;
            例如:傳入的數組對象 ids 爲 {1, 2, 3, 4},最終迭代的結果爲 (1, 2, 3, 4),
                那麼 SQL 語句就會變成 delete from students where id in (1, 2, 3, 4);
        -->
        <foreach collection="array" open="(" close=")" separator="," item="ids">
            #{ids}
        </foreach>
    </delete>

    <!-- 動態刪除:List 版本 -->
    <delete id="deleteBySynSQLList">
        delete from students where id in
        <!-- collection="list":表示迭代的集合是一個 list -->
        <foreach collection="list" open="(" close=")" separator="," item="ids">
            #{ids}
        </foreach>
    </delete>

    <!-- 定義 SQL 片段:對應要增加的字段 -->
    <sql id="columnID">
        <!-- trim 標籤用於去掉最後一個逗號(注意:set 標籤可以自動去掉最後一個逗號,SQL 片段不能自動去掉) -->
        <trim suffixOverrides=",">
            <!--
                下面 if 標籤中的 sid 是 student 對象中的屬性,id 是表中的字段;
                即如果 sid 屬性有值,則說明 id 字段要增加數據,此時要加上 id 字段;
            -->
            <if test="sid != null">
                id,
            </if>
            <if test="sname != null">
                name,
            </if>
            <if test="ssal != null">
                sal,
            </if>
        </trim>
    </sql>

    <!-- 定義 SQL 片段:對應要增加的數據 -->
    <sql id="valueID">
        <trim suffixOverrides=",">
            <if test="sid != null">
                #{sid},
            </if>
            <if test="sname != null">
                #{sname},
            </if>
            <if test="ssal != null">
                #{ssal},
            </if>
        </trim>
    </sql>

    <!--
        動態增加數據:要增加的 字段和對應的值 都不確定;
            字段和值引用上面定義的 SQL片段,用 <include/> 標籤;
    -->
    <insert id="insertBySynSQL" parameterType="com.mybatis.demo.Student">
        insert into students( <include refid="columnID"/>) values( <include refid="valueID"/> );
    </insert>
</mapper>

修改 StudentDao.java 測試類爲:

package com.mybatis.demo;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 持久層:測試動態 SQL
 */
public class StudentDao {

    /**
     * 動態 SQL ---> 查詢
     *  查詢條件不確定,需要根據情況動態產生 SQL 語法,這種情況叫做動態 SQL。
     */
    public int findAllBySynSQL(Integer id, String name, Double sal) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            // 封裝參數
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("pid", id);
            map.put("pname", name);
            map.put("psal", sal);

            // 執行 StudentMapper.xml 配置文件中的查詢 SQL 語句:
            List<Student> list = sqlSession.selectList("studentNamespace.findAllBySynSQL", map);
            for(Student student : list) {
                System.out.println(student);
            }

            return 0;
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }finally {
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    /**
     * 動態 SQL ---> 更新
     *  更新字段不確定;
     */
    public int updateBySynSQL(Integer id, String name, Double sal) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            // 封裝參數
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("pid", id);
            map.put("pname", name);
            map.put("psal", sal);
            return sqlSession.update("studentNamespace.updateBySynSQL", map);
        }catch (Exception e){
            sqlSession.rollback(); // 回滾
            e.printStackTrace();
            throw e;
        }finally {
            sqlSession.commit(); // 提交
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    /**
     * 動態 SQL ---> 刪除(數組版本)
     *  需要刪除數據的 id 不確定;
     *  int... 表示參數可以接收無限個 int 型的參數
     */
    public int deleteBySynSQLArray(int... ids) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            return sqlSession.delete("studentNamespace.deleteBySynSQLArray", ids);
        }catch (Exception e){
            sqlSession.rollback(); // 回滾
            e.printStackTrace();
            throw e;
        }finally {
            sqlSession.commit(); // 提交
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    /**
     * 動態 SQL ---> 刪除(List 版本)
     *  需要刪除數據的 id 不確定;
     */
    public int deleteBySynSQLList(List<Integer> ids) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            return sqlSession.delete("studentNamespace.deleteBySynSQLList", ids);
        }catch (Exception e){
            sqlSession.rollback(); // 回滾
            e.printStackTrace();
            throw e;
        }finally {
            sqlSession.commit(); // 提交
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    /**
     * 動態 SQL ---> 增加數據
     *  需要增加的 字段和值 不確定;
     */
    public int insertBySynSQL(Student student) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            return sqlSession.delete("studentNamespace.insertBySynSQL", student);
        }catch (Exception e){
            sqlSession.rollback(); // 回滾
            e.printStackTrace();
            throw e;
        }finally {
            sqlSession.commit(); // 提交
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    public static void main(String[] args) throws Exception{
        StudentDao dao = new StudentDao();
        // 動態查詢:根據傳入的條件 動態查詢不同的數據
//        System.out.println("*********** 根據 id 查詢 **********");
//        int ret = dao.findAllBySynSQL(1, null, null);
//        System.out.println("*********** 根據 name 查詢 **********");
//        ret = dao.findAllBySynSQL(null, "呵呵", null);
//        System.out.println("*********** 根據 sal 查詢 **********");
//        ret = dao.findAllBySynSQL(null, null, 8000D);
//        System.out.println("*********** 根據 id 和 sal 查詢 **********");
//        ret = dao.findAllBySynSQL(4, null, 9000D);

        // 動態更新:根據傳入的數據 動態更新對應的字段
//        dao.updateBySynSQL(2, "張三", null); // 更新 2 號學生的姓名
//        dao.updateBySynSQL(3, null, 6600D);  // 更新 3 號學生的薪水
//        dao.updateBySynSQL(4, "王五", 8800D);// 更新 4 號學生的 姓名和薪水

        // 動態刪除:根據傳入的 id 動態刪除數據
//        dao.deleteBySynSQLArray(2, 3, 4); // 數組版本
//        List<Integer> list = new ArrayList<>();
//        list.add(1);
//        list.add(3);
//        list.add(4);
//        dao.deleteBySynSQLList(list); // list 集合版本

        // 動態增加數據:根據傳入的數據不同 動態增加數據
        dao.insertBySynSQL(new Student(5, "張三", 5500D)); // 所有字段都增加數據
        dao.insertBySynSQL(new Student(6, "李四", null)); // name 字段增加數據,sal 字段不增加
        dao.insertBySynSQL(new Student(7, null, 6600D)); // name 字段不增加數據,sal 字段增加
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章