当前位置 博文首页 > 文章内容

    Mybatis-09-动态Sql

    作者: 栏目:未分类 时间:2020-09-19 10:00:23

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    • 定义

      根据不同的条件生成不同的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>