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 字段增加
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章