Mybatis之动态sql和分页

1.mybatis动态sql

    1.1 if:if判断

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

    1.2 trim   mybatis中trim是动态拼接;java中表示去除前后空格
     prefix:前缀
     suffix:后缀
     suffixOverride:去除后缀指定的字符
     prefixOverrides:去除前缀指定的字符

<insert id="insertSelective" parameterType="com.zking.mybatis01.model.book" >
    insert into t_book
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <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>

    1.3 foreach:循环(三种方式)

第一种:

<select id="queryBookForEach" resultType="com.zking.mybatis01.model.book">
    select  <include refid="Base_Column_List"/> from t_book where 1=1
    <foreach collection="ids" item="id" separator="," open=" and book_id in(" close=")">
      #{id}
    </foreach>
  </select>

 第二种:

第三种:


    1.4 其他

 choose:

choose(判断参数) - 按顺序将实体类 User 第一个不为空的属性作为:where条件,choose标签在mybatis的xml文件中, 一般与when标签结合使用, 主要用于条件查询,根据不同的情况来进行页面查询,choose的执行原理如下: 如果有一个when满足,那么choose结束, choose会按照when标签的顺序来执行,如果when执行的结果都会false,那么会执行otherwise标签里的语句

 <select id="queryChooseTest" resultType="com.zking.mybatis01.model.book">
    select <include refid="Base_Column_List"/> from t_book where 1=1
    <choose>
      <when test="value!=null and ''!=value">
        and book_id = #{value}
      </when>
      <otherwise>
        and book_id=1
      </otherwise>
    </choose>
  </select>

set:

set用于更新的sql语句中

在update时,多条件更新,每个属性后面要加逗号“,”,这个时候可能会出现多一个“,”的情况,此时我们就可以使用set去掉后边的“,”,除此之外我们使用前面说的trim也可实现当前的操作,修改方法,假如实体类属性为空就不修改此属性所对于的字段

<update id="updateByPrimaryKeySelective" parameterType="mybatis01.model.Book" >
    update t_book
    <set >
      <if test="bookName != null" >
        book_name = #{bookName,jdbcType=VARCHAR},
      </if>
      <if test="bookNamePinyin != null" >
        book_name_pinyin = #{bookNamePinyin,jdbcType=VARCHAR},
      </if>
      <if test="bookPrice != null" >
        book_price = #{bookPrice,jdbcType=REAL},
      </if>
      <if test="bookType != null" >
        book_type = #{bookType,jdbcType=VARCHAR},
      </if>
    </set>
    where book_id = #{bookId,jdbcType=INTEGER}
  </update>

where 

用于管理 where 子句. 有如下功能:
1) 如果没有条件, 不会生成 where 关键字
2) 如果有条件, 会自动添加 where 关键字
3) 如果第一个条件中有 and, 自动去除之

<select id="queryBookWhere" resultType="mybatis01.model.Book">
    select <include refid="Base_Column_List"/> from t_book
    <where>
      <if test="bookType!=null and bookType!=''">
        and book_Type=#{bookType}
      </if>
      <if test="bookName!=null and bookName!=''">
        and book_name=#{bookName}
      </if>
    </where>
  </select>

2.模糊查询(3种方式)

<select id="queryBooklike"  resultType="mybatis01.model.Book">
    select <include refid="Base_Column_List"/> from t_book where 1=1
    <if test="null!=bookType and ''!=bookType">
      and book_type like #{bookType}
    </if>
    <if test="null!=bookName and ''!=bookName">
      and book_name like '%${bookName}%'
    </if>
    <if test="null!=bookId and ''!=bookId">
      and book_Id like  concat('%',#{bookId},'%')
    </if>
 
  </select>


    2.1 参数中直接加入%%

    2.2 使用${...}代替#{...}(不建议使用该方式,有SQL注入风险)
          参数类型为字符串,#会在前后加单引号['],$则直接插入值

          注:
          1) mybatis中使用OGNL表达式传递参数
          2) 优先使用#{...}
          3) ${...}方式存在SQL注入风险

MyBatis中#和$的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
   如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by '111', 
       如果传入的值是id,则解析成的sql为order by "id".

2. $将传入的数据直接显示生成在sql中。
   如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,
       如果传入的值是id,则解析成的sql为order by id.
 
3. #方式能够很大程度防止sql注入。
 
4. $方式无法防止Sql注入。
 
5. $方式一般用于传入数据库对象,例如传入表名.
 
6. 一般能用#的就别用$. 

    2.3 SQL字符串拼接CONCAT

3.查询返回结果集

    resultMap:适合使用返回值是自定义实体类的情况
    resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型

    3.1 使用resultMap返回自定义类型集合
    
    3.2 使用resultType返回List<T>

    3.3 使用resultType返回单个对象

    3.4 使用resultType返回List<Map>,适用于多表查询返回结果集

    3.5 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集

Mapper接口 
 List<Book> queryMap();
Book queryBookByID(Integer bookId);
//Map和List<Map>集合适用于多表联查返回综合数据结果
Map<String,Object> querySingBookByMap(Integer bookId);
List<Map<String,Object>> querySingBookByMaps();
 
 
实现对应Mapper接口的xml
 <select id="queryMap" resultMap="BaseResultMap">
    select <include refid="Base_Column_List"/> from t_book
  </select>
  <select id="queryBookByID" resultType="mybatis01.model.Book">
    select <include refid="Base_Column_List"/> from t_book where 1=1 and book_id=#{value}
  </select>
  <select id="querySingBookByMap" resultType="java.util.Map">
    select <include refid="Base_Column_List"/> from t_book where 1=1 and book_id=#{bookId}
 
  </select>
  <select id="querySingBookByMaps" resultType="java.util.Map">
    select <include refid="Base_Column_List"/> from t_book
  </select>

4.分页查询

   为什么要重写mybatis的分页?
   Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的
   
    4.1 导入分页插件
       <dependency>
         <groupId>com.github.pagehelper</groupId>
         <artifactId>pagehelper</artifactId>
         <version>5.1.2</version>
       </dependency>

    4.2 将pagehelper插件配置到mybatis中
       <!-- 配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 -->
       <plugin interceptor="com.github.pagehelper.PageInterceptor">
       </plugin>

    4.3 在你需要进行分页的Mybatis方法前调用PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个Mybatis查询方法会被进行分页
       //设置分页处理
       if (null != pageBean && pageBean.isPaginate()) {
         PageHelper.startPage(pageBean.getCurPage(), pageBean.getPageRecord());
       }

       
    4.4 获取分页信息(二种方式)
     4.4.1 使用插件后,查询实际返回的是Page<E>,而非List<E>,Page继承了ArrayList,同时还包含分页相关的信息

          Page<Book> page = (Page<Book>)list;
          System.out.println("页码:" + page.getPageNum());
          System.out.println("页大小:" + page.getPageSize());
          System.out.println("总记录:" + page.getTotal());

     4.4.2 使用PageInfo
          PageInfo pageInfo = new PageInfo(list);
          System.out.println("页码:" + pageInfo.getPageNum());
          System.out.println("页大小:" + pageInfo.getPageSize());
          System.out.println("总记录:" + pageInfo.getTotal());

分页测试

PageBean pageBean=new PageBean();
        pageBean.setPage(2);
 
        //判断是否分页
        if (null != pageBean && pageBean.isPagination()) {
            // 参数1:当前页码,参数2:每页条数
            PageHelper.startPage(pageBean.getPage(), pageBean.getRows());
        }
 
 
        List<Book> bookList = bookService.queryBookPager(Book.builder().bookName("西游").build(), pageBean);
        System.out.println(bookList.getClass());
 
        if (null != pageBean && pageBean.isPagination()) {
            PageInfo pageInfo = new PageInfo(bookList);
            System.out.println("页码:" + pageInfo.getPageNum());
            System.out.println("页大小:" + pageInfo.getPageSize());
            System.out.println("总记录:" + pageInfo.getTotal());
            List list = pageInfo.getList();
            list.forEach(System.out::println);
        }

5.特殊字符处理(xml文件中的sql语句中使用)
    >   (&gt;)   
    <   (&lt;)  
    &  (&amp;) 
 空格(&nbsp;)

Mapper接口
示例七:范围查询,转义字符处理

List<Book> queryBookRange(BookVo bookvo);
实现对应Mapper接口的xml
<select id="queryBookRange" resultType="mybatis01.model.Book">
  select <include refid="Base_Column_List"/> from t_book where 1=1
  <if test="null!=min and ''!=min">
    and book_price &gt;  #{min}
  </if>
  <if test="null!=max and ''!=max">
    and book_price &lt; #{max}
  </if>
</select>
最后给一个方便使用对象赋值的一个插件
 
导入lombok插件
 
 <dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.22</version>
  <scope>provided</scope>
</dependency>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值