zoukankan      html  css  js  c++  java
  • MyBatis-DynamicSQL 动态SQL

    MyBatis 的动态 SQL 使用 OGNL 表达式

    http://commons.apache.org/proper/commons-ognl/language-guide.html

    在 XML 中的一些特殊字符需要转义,参考 HTML ISO-8859-1 手册

    http://www.w3school.com.cn/tags/html_ref_entities.html

    一、IF

    https://www.cnblogs.com/jhxxb/p/10637219.html

    <select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
        select * from myuser where
        <if test="id != null">
          id = #{id}
        </if>
        <if test="name != null &amp;&amp; name != &quot;&quot;">
          and name like #{name}
        </if>
        <if test="age == 0 or age == 1">
          and age = #{age}
        </if>
    </select>

    入参没有ID属性时会报错,会拼接成 where and,解决:可以在 where 后添加一个恒成立,如 1=1。或者使用 where 标签,会自动去除 SQL 中多出来的 and 或 or

     

    二、WHERE

    <select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
        select * from myuser
        <where>
            <if test="id != null">
              id = #{id}
            </if>
            <if test="name != null and name != ''.toString()">
              and name like #{name}
            </if>
            <if test="age == 0 or age == 1">
              and age = #{age}
            </if>
        </where>
    </select>

    where 标签只能去除第一个 and 或 or,所以不能把条件符号写多个或写在后面

     

    三、SET

    <update id="updateMyUser" parameterType="myUser">
        update myuser
        <!-- 用作更新 -->
        <set>
            <if test="name != null">
              name = #{name},
            </if>
            <if test="age != null">
              age = #{age}
            </if>
        </set>
        where id = #{id}
    </update>

     

    四、TRIM

    <select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
        select * from myuser
        <!-- prefix:替换拼接后字符串的前缀,单独使用则为添加。prefixOverrides:想替换的前缀类容(条件),单独使用则为删除
            suffix:替换拼接后字符串的后缀,单独使用则为添加。suffixOverrides:想替换的后缀类容(条件),单独使用则为删除 -->
        <trim prefix="where" prefixOverrides="AND | OR" suffixOverrides="and">
            <if test="id != null">
                id = #{id} and
            </if>
            <if test="name != null and name.trim() != ''">
                name like #{name}
            </if>
        </trim>
    </select>

    trim 标签可以替代 where 标签

    <!-- 等效于 where 标签 -->
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
        ...
    </trim>

    trim 标签也可以替代 set 标签

    <!-- 等效于 set 标签 -->
    <trim prefix="set" suffixOverrides=",">
      ...
    </trim>

     

    五、CHOOSE

    <select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
        select * from myuser
        <where>
            <!-- 类似于 if-else if-else 分支结构 -->
            <choose>
                <when test="id != null">
                  id = #{id}
                </when>
                <when test="name != null and name.trim() != ''">
                  name like #{name}
                </when>
                <otherwise>
                  age = 22
                </otherwise>
            </choose>
        </where>
    </select>

     

    六、FOREACH

    Map 入参

    <!--public List<MyUser> selectMyUserByArray(Map<String,Object> maps);-->
    <select id="selectMyUserByArray" resultType="myUser">
        select * from myuser where id in
        <!-- collection:指定要遍历的集合或数组(list 和 array 参数都会特殊处理封装在 Map 中,Map 的 key 默认为 list 或 array)
                入参为单个 list 或 array 时 collection 值默认为 list 或 array,若接口方法指定了 @Param 注解,则为 @Param 的值
                入参为多个参数可以封装为 Map,collection 值为 Map 中集合或数组对应的 key 的值(Map 的 key 最好为 String 类型)
            open:给结果拼接一个前缀
            close:给结果拼接一个后缀
            item:集合中每一个元素在迭代时的别名,#{item} 取出变量的值,也就是当前遍历出的元素
            separator:每个元素之间的分隔符
            index:索引
                遍历 list 或 arrays 时,index 是当前索引(下标),item 为索引对应的值
                遍历 map 时 index 表示 map 的 key,item 为 map 的 value -->
        <foreach collection="ids" item="item" index="index" separator="," open="(" close=")">
            #{item}
        </foreach>
    </select>

    测试代码

    public static void main(String[] args) {
        SqlSession session = null;
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            session = sqlSessionFactory.openSession();
    
            MyUserMapper mapper = session.getMapper(MyUserMapper.class);
            Map<String,Object> ids = new HashMap<>(10);
            ids.put("ids",Arrays.asList(7,8,9,10));
            ids.put("b",8);
            System.out.println(mapper.selectMyUserByArray(ids));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }

    List 入参

    <!--public List<MyUser> selectMyUserByArray(List<Integer> ids);-->
    <select id="selectMyUserByArray" resultType="myUser">
        select * from myuser where id in
        <foreach collection="list" item="item" index="index" separator="," open="(" close=")">
          #{item}
        </foreach>
    </select>

    Array 入参

    <!--public List<MyUser> selectMyUserByArray(Integer[] ids);-->
    <select id="selectMyUserByArray" resultType="myUser">
        select * from myuser
        <foreach collection="array" item="item" index="index" separator="," open="where id in (" close=",20)">
          #{item}
        </foreach>
    </select>

     

     

    七、内置参数

    <!-- 不只是方法传递过来的参数可以被用来判断和取值,mybatis 默认还有两个内置参数。
            _parameter:代表整个参数
                单个参数:_parameter 就是这个参数
                多个参数:参数会被封装为一个 map,_parameter 就代表这个 map
            _databaseId:如果配置了 databaseIdProvider 标签,_databaseId 代表当前数据库的别名 -->
    <select id="selectMyUserById" resultType="myUser">
        <if test="_databaseId == 'mysql'">
            select * from myuser
            <if test="_parameter != null">
                where id = #{_parameter}
            </if>
        </if>
        <if test="_databaseId == 'oracle'">
            select * from oracle_myuser
            <if test="_parameter != null">
                where name = #{_parameter.name}
            </if>
        </if>
    </select>

     

    八、BIND

    <select id="selectMyUserByNameLike" resultType="myUser" parameterType="string">
        select * from myuser where name like #{name}
    </select>

    例 SQL 映射想变为模糊查询有几种方式

    1.传入参数时加上 %

    2.改用 ${name} 来取值。name 取值会报错,用 _parameter 取值

    <select id="selectMyUserByNameLike" resultType="myUser">
        select * from myuser where name like '%${_parameter}%'
    </select>

    3.使用 bind 标签

    <select id="selectMyUserByNameLike" resultType="myUser">
      <!-- bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值 -->
        <bind name="_name" value="'%'+_parameter+'%'"/>
        select * from myuser where name like #{_name}
    </select>

     

    九、SQL 复用

    <!-- 抽取可重用的sql片段。方便后面引用,使用 include 标签来引用已经抽取的 sql
        include 中可以自定义一些 property,sql 标签内部就能使用自定义的属性
        include-property:取值用 ${prop}, 使用 #{prop} 不能取出,无法预编译 -->
    <sql id="columnNames">
        <if test="_databaseId=='mysql'">
            ${id},name,age
        </if>
        <if test="_databaseId=='oracle'">
            xxx,xxx,xxx
        </if>
    </sql>
    <select id="selectMyUserByNameLike" resultType="myUser" parameterType="string">
        select
        <include refid="columnNames">
          <property name="id" value="id"/>
        </include>
        from myuser where name like #{name}
    </select>

    可以使用其他语言来写动态 SQL:MyBatis-Velocity、MyBatis-FreeMarker 和自带的 XML

    http://www.mybatis.org/velocity-scripting/

    http://www.mybatis.org/freemarker-scripting/

    https://www.jianshu.com/p/cecc187410be

    MyBatis 动态 SQL 文档

  • 相关阅读:
    rabbitmq channel参数详解
    java中反射知识点总结
    SpringBoot的ApplicationRunner
    ServletContextInitializer添加 servlet filter listener
    如何在Job中获取 IOC applicationcontext
    QRCode.js:使用 JavaScript 生成微信二维码
    SpringBoot整合Quartz
    java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet解决
    javascript简介
    mysql索引
  • 原文地址:https://www.cnblogs.com/jhxxb/p/10493844.html
Copyright © 2011-2022 走看看