MyBatis动态SQL

1.动态SQL的概念

动态sql是指在进行sql操作的时候,传入的参数对象或者参数值,根据匹配的条件,有可能需要动态的去判断是否为空,循环,拼接等情况;

2.mybatis动态sql

1-if判断:

<!-- 
    BookMapper.xml 
    id:调用的方法名
-->
<select id="queryBookByIf" resultType="com.zking.mybatis01.model.Book">
        <!-- 
            SQL语句;
            <include refid="Base_Column_List"/>:数据库表中所有的字段;
        -->
        select <include refid="Base_Column_List"/> from t_book where 1=1
        <!-- if判断book参数条件 -->
        <if test="null!=bookType and ''!=bookType">
            <!-- #{bookType}:拿到实体类中的参数,book_type:数据库中的字段名!!! -->
            and book_type=#{bookType}
        </if>
</select>

2-trim: mybatis中trim是动态拼接;java中表示去除前后空格

        trim中主要运用SQL语句的动态拼接,所做到的SQL使用的方便性

<!--
    动态拼接的insert
    id:调用的方法名
    prefix:前缀;
    prefixOverrides:去除前缀的指定的字符;
    suffix:后缀;
    suffixOverrides:去除后缀的指定的字符;
   -->
  <insert id="insertSelective" parameterType="com.zking.mybatis01.model.Book" >
    insert into t_book
    <trim prefix="(" suffix=")" suffixOverrides="," prefixOverrides="">
      <if test="bookId != null" >
        book_id,
      </if>
      <if test="bookName != null" >
        book_name,
      </if>
      <if test="bookNamePinyin != null" >
        book_name_pinyin,
      </if>
      <if test="bookPrice != null" >
        book_price,
      </if>
      <if test="bookType != null" >
        book_type,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="bookId != null" >
        #{bookId,jdbcType=INTEGER},
      </if>
      <if test="bookName != null" >
        #{bookName,jdbcType=VARCHAR},
      </if>
      <if test="bookNamePinyin != null" >
        #{bookNamePinyin,jdbcType=VARCHAR},
      </if>
      <if test="bookPrice != null" >
        #{bookPrice,jdbcType=REAL},
      </if>
      <if test="bookType != null" >
        #{bookType,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>

         使用junit测试:

  @Test
    public void demo() {
        //赋值参数
        book.setBookName("傻狗传说");
        book.setBookType("冥想");
        book.setBookPrice(100f);
        //调用方法
        bookService.insertSelective(book);
    }

         控制台看打印结果:通过对象中的属性动态SQL

3-foreach:可以和trim嵌套使用

        定义Bookvo用于foreach循环

public class BookVo extends Book {
    private List<Integer> ids;

    public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }
}

        映射XMLforeach: 和拼接差不多,相当于是循环拼接

<select id="queryBookByForeach" resultType="com.zking.mybatis01.model.Book">
    select <include refid="Base_Column_List"/> from t_book where 1=1 and book_id in
    <!--
      相当于:for(Integer id : ids)
      separator:分隔符;
      open:打开位置;
      close:结束位置;
    -->
    <foreach collection="ids" item="id" separator="," open=" (" close=")">
        #{id}
    </foreach>
</select>

       使用junit测试:  

 @Test
    public void demo() {

        BookVo vo = new BookVo();

        //将数组转为集合
        vo.setIds(Arrays.asList(new Integer[]{100,101,14937}));

        List<Book> books = bookService.queryBookByForeach(vo);

        books.forEach(System.out::println);

    }

         执行的SQL语句:

         返回打印的数据:

 4-where查询条件:

        查询的时候如果第一个条件不存在,则可能会出现将后面 “and xxx” 拼接到sql语句中,造成sql 语法错误。
        使用<where>标签代替sql查询条件的"WHERE"

        修改sql映射文件:<where>标签会根据条件自动消除掉sql语句中前面部分的"AND" 字符

<select id="queryBookByIf" resultType="com.zking.mybatis01.model.Book">
        select <include refid="Base_Column_List"/> from t_book where 1=1
      <where>
        <if test="null!=bookType and ''!=bookType">
          and book_type=#{bookType}
        </if>
      </where>
</select>

5-choose (when, otherwise)标签:

        有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为 true,就会执行 if 标签中的条件。MyBatis 提供了 choose 元素。if标签是与(and)的关系,而 choose 是或(or)的关系。

        choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

<!--  choose(判断参数) - 按顺序将实体类 Book 第一个不为空的属性作为:where条件 -->
  <select id="queryBookByChoose" resultType="com.zking.mybatis01.model.Book">
    select <include refid="Base_Column_List"/> from t_book where 1 = 1
    <choose>
      <when test="bookName != null">
        and book_name = #{bookName}
      </when>
      <when test="bookType != null">
        and book_type = #{bookType}
      </when>
      <!-- otherwise:设置的default,when条件都不成立的时候才会使用 -->
      <otherwise>
        and book_id = 100
      </otherwise>
    </choose>
</select>

         测试:

public void demo() {
        //俩行关键代码段
//      book.setBookName("西游记");
//      book.setBookType("金典");
        List<Book> books = bookService.queryBookByChoose(book);
        books.forEach(System.out::println);

}

         当以上代码段被注释时:

        当以上代码段不被注释时: (有俩个不为null,但是只有一个使用了进去,如果有一个成立,则 choose 结束)

        当when条件成立则不会使用到otherwise的SQL语句,

        当when条件不成立则会使用到otherwise的SQL语句。

        按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。

 6-传参

        单个参数传参:列如void query(Integer id);映射文件中可以用value来取值

        String传参:String是不能用value的,必须使用void query(@Param("bookType") String bookType);:@Param("bookType")方式,并且指明参数名,参数名‘bookType’用于取值

        集合List传参:使用List集合中对象的属性名取值,并非数据库表中的字段名

        多个参数传参:void query(@Param("bookType") String bookType,@Param("bookId") Integer bookId);:和String传参一个道理

                        --- 一般为了方便使用建议用对象或者集合传参 ---

7-select查询返回的结果集:

        resultType:适合使用返回值的数据类型是非自定义的,即jsk的提供的类型

        resultMap:适合使用返回值是自定义实体类的情况,

       映射文件 resultType="java.util.Map":返回Map集合,List<Map,Object>和Map集合适用于多表联查和综合的数据结果

8-原始时代版 分页查询:

        提前准备PageBean.java,分页查询的基本在Mapper类中不需要传入pagebean,由内置插件帮我们完成,到Service类就要pagebean参数了,

      

    @Test
    public void demo() {
        //分页查询
        PageBean pagebean = new PageBean();
        //判断是否分页
        if(null!=pagebean && pagebean.isPagination()){
            //参数1:当前页码;参数2:每页条数;
            PageHelper.startPage(pagebean.getPage(),pagebean.getRows());
        }
        List<Book> books = bookService.queryBookPager(Book.builder().build(), pagebean);
        System.out.println(books.getClass());

        if(null!=pagebean && pagebean.isPagination()){
            PageInfo pageInfo = new PageInfo(books);
            System.out.println("页码:"+pageInfo.getPageNum());
            System.out.println("页大小:" + pageInfo.getPageSize());
            System.out.println("总记录:" + pageInfo.getTotal());
            List list = pageInfo.getList();
            list.forEach(System.out::println);
        }

    }

 

如果想要达到其他分页效果就给PageBean对象属性进行操作 

 

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值