Mybatis之动态sql

Mybatis之动态sql

1.搭建环境

参考Mybatis入门

1. 创建一个测试表

create table phone
(
    id         varchar(255) not null
        primary key,
    phone_name  varchar(225) null,
    phone_type  varchar(225) null,
    size_norms  varchar(225) null,
    phone_color varchar(225) null,
    price       double       null
);

2. 实体类

public class Phone {
    private String id;
    private String phoneName;
    private String phoneType;
    private String sizeNorms;
    private String phoneColor;
    private double price;
}

2.动态sql之IF

  1. 接口
public interface PhoneMapper {
    /** 动态sql--if
     * @return
     */
    List<Phone> QueryPhoneIf(Map map);
}
  1. Mapper.xml配置
    <select id="QueryPhoneIf" parameterType="map" resultType="Phone">
        select *from Phone
        <where>
            <if test="phoneName != null">
                and  phone_name =  #{phoneName}
            </if>
            <if test="phone_color != null">
                and phone_color = #{phoneColor}
            </if>
        </where>
    </select>
  1. junit测试
   @Test
   public void QueryPhoneIf(){
       SqlSession   sqlSession = MybatisUntils.getSqlSession();
       PhoneMapper mapper = sqlSession.getMapper(PhoneMapper.class);
       Map map = new HashMap();
       map.put("phoneName","华为荣耀");
       map.put("phoneColor","红色");
       List<Phone> phones = mapper.QueryPhoneIf(map);
       for (Phone phone : phones) {
           System.out.println(phone);
       }
       sqlSession.close();
   }

总结:

  1. if标签的test对应的key==#{key} ==map.(key,value) ,三个key需 一致(这里是使用map集合)

  2. if标签会搜索全部条件

3.动态sql之choose

  1. 接口
    /** 动态sql--Choose
     * @return
     */
    List<Phone> QueryPhoneChoose(Map map);
  1. Mapper.xml配置
  <select id="QueryPhoneChoose" parameterType="map" resultType="Phone">
         select *from Phone
         <where>
             <choose>
                 <when test="phone_name != null">
                      phone_name = #{phone_name}
                 </when>
                 <when test="size_norms != null">
                      size_norms = #{size_norms}
                 </when>
                 <otherwise>
                      phone_color = #{phone_color}
                 </otherwise>
             </choose>
         </where>
    </select>
  1. junit测试
   @Test
   public void  QueryPhoneChoose(){
       SqlSession  sqlSession = MybatisUntils.getSqlSession();
       PhoneMapper mapper = sqlSession.getMapper(PhoneMapper.class);
       Map map = new HashMap();

       map.put("phone_name","华为荣耀");
       map.put("phone_color","红色");
       List<Phone> phones = mapper.QueryPhoneChoose(map);
       for (Phone phone : phones) {
           System.out.println(phone);
       }
       sqlSession.close();
   }

总结:

  1. choose--顾名思义就是选择的意思--相当于java里面的switch

  2. choose存在优先级,当他满足第一个when标签的时候就直接跳出,后面满足的也不执行。

  3. otherwise标签,当when标签都不满足的时候执行.相当于switch的default

  4. choose如果when标签成立,会优先搜索第一个成立的when标签

4.动态sql之Foreach

  1. 接口
    /**动态sql--foreach
     * @return
     */
    List<Phone> QueryPhoneForeach(Map map);
  1. Mapper.xml配置
 <select id="QueryPhoneForeach"  resultType="Phone" parameterType="map">
                select *from phone 
                <where>
                    <foreach collection="names"  open="(" item="name" separator="or" close=")">
                         Phone_name=#{name}
                    </foreach>
                </where>
</select>
  1. junit测试
   @Test
   public  void  QueryByForeach(){
       SqlSession sqlSession = MybatisUntils.getSqlSession();
       PhoneMapper mapper = sqlSession.getMapper(PhoneMapper.class);
       HashMap map = new HashMap();
       List<String> names=new ArrayList<String>();
       names.add("华为");
       names.add("小米");
       names.add("苹果");
       map.put("names",names);
       List<Phone> phones = mapper.QueryPhoneForeach(map);
       for (Phone phone : phones) {
           System.out.println(phone);
       }
       sqlSession.close();
   }

总结:

例如:(select * from phone where (name=#{name1} or name=#{name2} or name=#{name3}))

  1. Foreach解析:collection 存放 name1,name2,name3的容器的名

item 容器的元素名。对应的 Phone_name=#{value} item跟value一致

open where标签后面开始需要的 (

separator 条件之间分隔符

close 条件的结束需要的 )

5.动态sql之where,set,trim

1.where

<select id="QueryPhoneIf"
     resultType="Phone">
  SELECT * FROM Phone
  WHERE
    <if test="phone_name != null">
             phone_name =  #{phone_name}
        </if>
        <if test="phone_color != null">
            and phone_color = #{phone_color}
        </if>
</select>
  1. 如果没有匹配条件不成立

sql语句---> SELECT * FROM Phone where 导致查询失败

  1. 匹配 and phone_color = #{phone_color}这个条件

sql语句---> SELECT * FROM Phone where and phone_color = #{phone_color} 导致查询失败

使用where标签就能在 子句的开头为 “and” 或 “or”,会将它们去除

2.set

    <update id="updatePhoneData" parameterType="map">
        update phone set
            <if test="size_norms !=null">
                size_norms = #{size_norms},
            </if>
            <if test="phone_name !=null">
                phone_name = #{phone_name},
            </if>
            <if test="price !=null">
                price = #{price}
            </if>    
         where id=#{id}
    </update>
  1. 如果只满足第一个匹配条件

sql语句---> update phone set size_norms = #{size_norms}, where id=#{id} 导致更新失败

使用set标签能删除删掉额外的逗号,保证sql语句正确

3.trim

  1. trim 元素可以定制元素的功能

    例如:where元素

    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      ...
    </trim>
    

    set元素

    <trim prefix="SET" suffixOverrides=",">
      ...
    </trim>
    
    • prefixOverrides 前缀值
    • suffixOverride 后缀值

需要了解更多动态sql 可以参考mybatis-动态 SQL

原文地址:https://www.cnblogs.com/sky1023/p/13067235.html