其中 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 字段增加
}
}