目录
新.
● 解决方案分析
2. 解决方案: MyBatis 提供的动态 SQL 机制
- //根据age查询结果
- public List
findMonsterByAge(@Param(value = "age") Integer age);
-
- <select id="findMonsterByAge" resultType="Monster" parameterType="Integer">
- SELECT * FROM `monster` WHERE 1 = 1
- <if test="age >= 0">
- AND age > #{age}
- if>
- select>
- public void findMonsterByAge() {
- List
monsters = - monsterMapper.findMonsterByAge(10);
- for (Monster monster : monsters) {
- System.out.println("monster--" + monster);
- }
- if (sqlSession != null) {
- sqlSession.close();
- }
- System.out.println("操作成功~");
- }
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除(去掉多余的“AND” 或 “OR)。
- //根据id和名字来查询结果
- public List
findMonsterByIdAndName(Monster monster);
-
- <select id="findMonsterByIdAndName" parameterType="Monster" resultType="Monster">
- SELECT * FROM `monster`
- <where>
- <if test="id >= 0">
- AND `id` > #{id}
- if>
- <if test="name != null and name != ''">
- AND `name` = #{name}
- if>
- where>
- select>
- public void findMonsterByIdAndName() {
- Monster monster = new Monster();
- monster.setId(1);
- monster.setName("牛魔王-100");
-
- List
monsters = monsterMapper.findMonsterByIdAndName(monster); - for (Monster m : monsters) {
- System.out.println("m--" + m);
- }
-
- if (sqlSession != null) {
- sqlSession.close();
- }
- System.out.println("操作成功~");
- }
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句(choose=switch;when=case;otherwise=default)。
- //测试choose标签的使用
- public List
findMonsterByIdOrName_choose(Map map) ;
-
- <select id="findMonsterByIdOrName_choose" parameterType="map" resultType="Monster">
- SELECT * FROM `monster`
- <choose>
- <when test="name != null and name != ''">
- WHERE `name` = #{name}
- when>
- <when test="id > 0">
- WHERE `id` > #{id}
- when>
- <otherwise>
- WHERE `salary` > 100
- otherwise>
- choose>
- select>
- public void findMonsterByIdOrName_choose() {
-
- Map
map = new HashMap<>(); - //map.put("name", "牛魔王-100");
- map.put("id", -1);
-
- List
monsters = monsterMapper.findMonsterByIdOrName_choose(map); - for (Monster monster : monsters) {
- System.out.println("monster--" + monster);
- }
-
- if (sqlSession != null) {
- sqlSession.close();
- }
- System.out.println("操作成功~");
- }
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
提示 :你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
● 需求:查询 monster_id 为 20, 22, 34 的妖怪
- //测试foreach的标签使用
- public List
findMonsterById_forEach(Map map) ;
-
- <select id="findMonsterById_forEach" parameterType="map" resultType="Monster">
- SELECT * FROM `monster`
-
- <if test="ids != null and ids !=''">
- <where>
- id IN
- <foreach collection="ids" item="id" open="(" separator="," close=")">
- #{id}
- foreach>
- where>
- if>
- select>
- public void findMonsterById_forEach() {
-
- Map
map = new HashMap<>(); - map.put("ids", Arrays.asList(10, 12, 14));
-
- List
monsters = - monsterMapper.findMonsterById_forEach(map);
-
- for (Monster monster : monsters) {
- System.out.println("monster--" + monster);
- }
-
-
- if (sqlSession != null) {
- sqlSession.close();
- }
- System.out.println("操作成功~");
-
- }
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能
理解:就是trim prefix="WHERE" prefixOverrides="and|or|hong" 若子句的开头为 “AND” 或 “OR 或"hong" , 就去除,而这个where就是带上where的功能
- //trim标签的使用
- public List
findMonsterByName_Trim(Map map) ;
-
- <select id="findMonsterByName_Trim" parameterType="map" resultType="Monster">
- SELECT * FROM `monster`
-
- <trim prefix="WHERE" prefixOverrides="and|or|hong">
- <if test="name != null and name != ''">
- AND `name` = #{name}
- if>
- <if test="age != null and age != ''">
- AND `age` > #{age}
- if>
- trim>
- select>
set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
● 需求: 请对指定 id 的妖怪进行 修改,如果没有设置新的属性,则保持原来的值
- //测试Set标签
- public void updateMonster_set(Map
map) ;
-
- <update id="updateMonster_set" parameterType="map">
- UPDATE `monster`
- <set>
- <if test="age != null and age != ''">
- `age` = #{age} ,
- if>
- <if test="email != null and email != ''">
- `email` = #{email} ,
- if>
- <if test="name != null and name != ''">
- `name` = #{name} ,
- if>
- <if test="birthday != null and birthday != ''">
- `birthday` = #{birthday} ,
- if>
- <if test="salary != null and salary != ''">
- `salary` = #{salary} ,
- if>
- <if test="gender != null and gender != ''">
- `gender` = #{gender} ,
- if>
- set>
- WHERE id = #{id}
- update>
- public void updateMonster_set() {
- Map
map = new HashMap<>(); - map.put("id", 3);
- map.put("name", "牛魔王5-100");
-
- monsterMapper.updateMonster_set(map);
-
- //修改需要有commit
- if (sqlSession != null) {
- sqlSession.commit();
- sqlSession.close();
- }
- System.out.println("操作成功~");
- }
像这个例子我们就可以看出来set是利用if的判断,如果我们在测试文件中没有改变,那么就是空,这个时候就会还是原来的值,相反当我们进行改变的时候,不为空,那么相应的字段的值就会发生改变------>这个例子就是把name字段进行了改变,其他的字段没有发生变化