Mybatis-09-动态Sql

  • 定义

    根据不同的条件生成不同的sql语句,本质还是sql语句,只是我们可以在sql层面执行逻辑代码

  • 环境搭建

    • blog表

      id
      title
      author
      creat_time
      views
    • 实体类:Blog

      @Data
      public class Blog {
      ?
         private String id;
         private String title;
         private String author;
         private Date creatTime;
         private int views;
      }
    • 配置文件

      <configuration>
      ?
         <settings>
             <setting name="logImpl" value="STDOUT_LOGGING"/>
             <!--开启驼峰命名-->
             <setting name="mapUnderscoreToCamelCase" value="true"/>
         </settings>
      ?
         <environments default="development">
             <environment id="development">
                 <transactionManager type="JDBC"/>
                 <dataSource type="POOLED">
                     <property name="driver" value="com.mysql.jdbc.Driver"/>
                     <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                     <property name="username" value="root"/>
                     <property name="password" value="root"/>
                 </dataSource>
             </environment>
         </environments>
      ?
         <mappers>
             <mapper class="com.hmx.mapper.BlogMapper"/>
         </mappers>
      ?
      </configuration>
  • if

    • 这条语句提供了可选的查找文本功能

    • 传入哪个就按哪个查找,如果不传入,就按select里的原始sql语句查找

    • 测试

      • 接口类

        public interface BlogMapper {
           List<Blog> queryBlogIf(Map map);
        }
      • 接口类的实现类

        <mapper namespace="com.hmx.mapper.BlogMapper">
        ?
           <select id="queryBlogIf" parameterType="map" resultType="Blog">
              select * from blog
               <!--
        where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句
        而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
        -->
               <where>
                   <!--
        test里面是判断条件
        表达式为true,把if中的语句拼接到select中的sql上
        表达式为false,忽略此语句
        -->
                   <if test="title != null">
                      and title = #{title}
                   </if>
                   <if test="author !=null" >
                      and author = #{author}
                   </if>
               </where>
           </select>
        ?
        </mapper>
      • 测试实现

        public static void queryBlogIf() {
        ?
           SqlSession sqlSession = MybatisUtils.getSqlSession();
        ?
           BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
           HashMap map = new HashMap();
           //查询title为"Mybatis如此简单"的记录
           map.put("title", "Mybatis如此简单");
           
           //查询author为"Andy"的记录
           //map.put("author","Andy");
        ?
           List<Blog> blogs = blogMapper.queryBlogIf(map);
           for (Blog blog : blogs) {
               System.out.println(blog);
          }
        ?
           sqlSession.close();
        }
  • choose,when,otherwise

    • 从多个条件中选择一个使用

    • 传入了哪个就按哪个查找,第一个when优先级最高,都没有传入,就按otherwise里的查找

    • 测试

      • 接口类

        public interface BlogMapper {
           List<Blog> queryBlogChoose(Map map);
        }
      • 接口的实现类

        <mapper namespace="com.hmx.mapper.BlogMapper">
        ?
           <select id="queryBlogChoose" parameterType="map" resultType="Blog">
              select * from blog
               <where>
                   <choose>
                       <when test="title != null">
                          title = #{title}
                       </when>
                       <when test="author !=null">
                          and author = #{author}
                       </when>
                       <otherwise>
                          and views = #{views}
                       </otherwise>
                   </choose>
               </where>
           </select>
        ?
        </mapper>
      • 测试实现

        public static void queryBlogChoose() {
        
            SqlSession sqlSession = MybatisUtils.getSqlSession();
        
            BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
            
            HashMap hashMap = new HashMap();
            hashMap.put("title", "Mybatis如此简单");
            //hashMap.put("author","洪梦霞");
            //hashMap.put("views","888");
            
            List<Blog> blogs = blogMapper.queryBlogChoose(hashMap);
            for (Blog blog : blogs) {
                System.out.println(blog);
            }
        
            sqlSession.close();
        }
  • trim,where,set

    • where

      • where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句,

        而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

      • 加入trim定制where元素的功能

        <!--拼接sql语句时会加上WHERE,并且删除多余的AND和OR-->
        <trim prefix="WHERE" prefixOverrides="AND |OR ">
          ...
        </trim>
    • set

      • set 元素可以用于动态包含需要更新的列,忽略其它不更新的列,它会动态地在行首插入 SET 关键字,并会删掉额外的逗号,在update语句中会用到

      • 加入trim定制set元素的功能

        <!--拼接sql语句时会加上SET,并且删除多余的","-->
        <trim prefix="SET" suffixOverrides=",">
          ...
        </trim>
  • foreach

    • 对集合进行遍历(尤其是在构建 IN 条件语句的时候)

    • 测试:select * from blog where 1 = 1 and (id = 1 or id = 2 or id = 3)

      • 接口类

        public interface BlogMapper {
            List<Blog> queryBlogForEach(Map map);
        }
      • 接口的实现类

        <mapper namespace="com.hmx.mapper.BlogMapper">
            
            <select id="queryBlogForEach" parameterType="map" resultType="Blog">
                select * from blog
                <where>
                    <!--
                        从collection这个集合中遍历,是map中存在的集合
                        遍历出的每一项叫做item中的值
                        index为下标
                        开始为open里的值
                        结束为close里的值
                        separator为分隔符
                    -->
                    <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                        id = #{id}
                    </foreach>
                </where>
            </select>
        
        </mapper>
      • 测试

        public static void queryBlogForEach() {
        ?
           SqlSession sqlSession = MybatisUtils.getSqlSession();
        ?
           BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
           HashMap map = new HashMap();
           
           ArrayList<Integer> ids = new ArrayList<Integer>();
           ids.add(1);
           ids.add(2);
           ids.add(3);
           map.put("ids", ids);
           
           List<Blog> blogs = blogMapper.queryBlogForEach(map);
           for (Blog blog : blogs) {
               System.out.println(blog);
          }
        ?
           sqlSession.close();
        }
  • sql片段

    • 将一些公共的功能抽取出来,方便复用

    • 注意:

      • 最好基于单表来定义SQL片段

      • 不要存在where标签

    • 使用步骤

      • 1、使用sql标签抽取公共的部分

        <sql id="if-title-author">
           <if test="title != null">
              title = #{title}
           </if>
           <if test="author !=null" >
              and author = #{author}
           </if>
        </sql>
      • 2、include标签引用

        <include refid="if-title-author"></include>

Mybatis-09-动态Sql

上一篇:Oracle字符集检查和修改


下一篇:对我来说数据库图形化管理工具用这个足够了