zoukankan      html  css  js  c++  java
  • Mybatis入门之mapper映射(案例Demo包括分页实现)

    动态sql相关

    mybatis支持强大的动态生成sql功能,提供了一些标签实现动态sql拼接, 更加灵活。

    mapper.xml的常用标签(参考:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html):

    标签 描述

    <mapper>

    映射文件的根节点,包含所有关于映射的配置

    <resultMap>

    定义返回集合的属性形式,适合用于返回自定义属性组合时的情况

    <constructor>

    <resultMap>的子节点,用于以构造函数的形式生成返回属性

    <idArg>

    <constructor>的子标签,表示实体主键
    <sql> 可以重用的 SQL 块,也可以被其他语句引用,与<include>标签结合使用,id必须唯一
    <include> 表示引用一个<sql>语句体,refid属性指定<sql>标签的id
    <insert>、<select>、<update>、<delete> 分别对应C(create)R(read)U(update)D(delete)

    1.if标签的使用,此种方式需要使用注解传参(不使用注解的话test表达式里面参数应该用value表示)

       //1.动态sql之if
       Book queryOneByBookId(@Param("bookId")Integer bookId);
       <if test="null!=bookId and ''!=bookId">
          and id = #{bookId}
        </if>

    2.trim标签的使用,包含去除前后缀的操作,可以与if结合使用

    <insert id="insertSelective" parameterType="com.star.model.Book" >
        insert into t_book_vue
        <!--
        prefix:代表前缀(
        suffix:代表后缀)
        suffixOverrides:去除末尾的后缀,
        prefixOverrides:去除开头的前缀
         -->
        <trim prefix="(" suffix=")" suffixOverrides=",">
          <if test="id != null" >
            id,
          </if>
          <if test="bookname != null" >
            bookname,
          </if>
          <if test="price != null" >
            price,
          </if>
          <if test="booktype != null" >
            booktype,
          </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
          <if test="id != null" >
            #{id,jdbcType=INTEGER},
          </if>
          <if test="bookname != null" >
            #{bookname,jdbcType=VARCHAR},
          </if>
          <if test="price != null" >
            #{price,jdbcType=REAL},
          </if>
          <if test="booktype != null" >
            #{booktype,jdbcType=VARCHAR},
          </if>
        </trim>
    </insert>

    3.foreach标签的使用,可以循环遍历标签体的内容

      <!-- foreach用法 -->
      <select id="queryBookByForeach" resultType="com.star.model.Book">
        <include refid="base_query_list"/>
        and id in
        <!--
          conllection:代表要循环的参数
          item: 每一项的别名自定义
          open:开头前缀
          close: 结尾后缀
          separator:每项之间插入字符
        -->
        <foreach collection="list" item="id" open="(" close=")" separator=",">
          #{id}
        </foreach>
        <include refid="base_order"/>
      </select>

    4.choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似

      <!--
        id:唯一
        parameterType:参数类型
        resultType:返回类型
       -->
      <select id="dynamicChooseTest" parameterType="com.star.model.Book" resultMap="BaseResultMap">
        <include refid="base_query_list"/>
        <!-- 满足表达式拼接标签体sql语句 -->
        <choose>
          <when test="bookname != null">
            and bookname like concat('%',#{bookname},'%')
          </when>
          <when test="booktype != null">
            and booktype = #{booktype}
          </when>
          <otherwise>
            and 2 = 2
          </otherwise>
        </choose>
        <include refid="base_order"/>
      </select>

    5.where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or 条件)

      <!--
        id唯一
        where标签跟在表名的后面,与if标签结合使用
      -->
      <select id="dynamicWhereTest" parameterType="com.star.model.Book" resultMap="BaseResultMap">
        select * from t_book_vue
        <where>
          <if test="bookname != null">
            bookname = #{bookname}
          </if>
          <if test="booktype != null">
            and booktype = #{booktype}
          </if>
        </where>
      </select>

    6.set主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段

      <!--
        set标签与where标签大同小异
      -->
      <update id="dynamicSetTest" parameterType="com.star.model.Book">
        update t_book_vue
        <set>
          <if test="bookname != null">
            bookname = #{bookname},
          </if>
          <if test="booktype != null">
            booktype = #{booktype},
          </if>
        </set>
        where id = #{id}
      </update>

    分页查询实现

    mybatis其实本身自带分页的实现,但是分页功能很弱(基于内存,查出所有记录在按偏移量offset和边界limit取结果),大数据情况下不适合使用,所以我们借助其他的分页工具实现。

    1.导入分页插件,这个插件使用拦截器实现分页

           <dependency>
             <groupId>com.github.pagehelper</groupId>
             <artifactId>pagehelper</artifactId>
             <version>5.1.2</version>
           </dependency>

    2.将pagehelper插件配置到mybatis.cfg.xml中:

           <!--要注意plugins的位置,要在别名配置之后 
          配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 -->
           <plugin interceptor="com.github.pagehelper.PageInterceptor">
           </plugin>

    3.准备一个包含常用操作的pageBean对象:

    package com.star.util;
    
    import java.io.Serializable;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    public class PageBean implements Serializable {
    
        private static final long serialVersionUID = 2422581023658455731L;
    
        //页码
        private int page=1;
        //每页显示记录数
        private int rows=10;
        //总记录数
        private int total=0;
        //是否分页
        private boolean isPagination=true;
        //上一次的请求路径
        private String url;
        //获取所有的请求参数
        private Map<String,String[]> map;
        
        public PageBean() {
            super();
        }
        
        //设置请求参数
        public void setRequest(HttpServletRequest req) {
            String page=req.getParameter("page");
            String rows=req.getParameter("rows");
            String pagination=req.getParameter("pagination");
            this.setPage(page);
            this.setRows(rows);
            this.setPagination(pagination);
            this.url=req.getContextPath()+req.getServletPath();
            this.map=req.getParameterMap();
        }
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public Map<String, String[]> getMap() {
            return map;
        }
    
        public void setMap(Map<String, String[]> map) {
            this.map = map;
        }
    
        public int getPage() {
            return page;
        }
    
        public void setPage(int page) {
            this.page = page;
        }
        
        public void setPage(String page) {
            if(null!=page&&!"".equals(page.trim()))
                this.page = Integer.parseInt(page);
        }
    
        public int getRows() {
            return rows;
        }
    
        public void setRows(int rows) {
            this.rows = rows;
        }
        
        public void setRows(String rows) {
            if(null!=rows&&!"".equals(rows.trim()))
                this.rows = Integer.parseInt(rows);
        }
    
        public int getTotal() {
            return total;
        }
    
        public void setTotal(int total) {
            this.total = total;
        }
        
        public void setTotal(String total) {
            this.total = Integer.parseInt(total);
        }
    
        public boolean isPagination() {
            return isPagination;
        }
        
        public void setPagination(boolean isPagination) {
            this.isPagination = isPagination;
        }
        
        public void setPagination(String isPagination) {
            if(null!=isPagination&&!"".equals(isPagination.trim()))
                this.isPagination = Boolean.parseBoolean(isPagination);
        }
        
        /**
         * 获取分页起始标记位置
         * @return
         */
        public int getStartIndex() {
            //(当前页码-1)*显示记录数
            return (this.getPage()-1)*this.rows;
        }
        
        /**
         * 末页
         * @return
         */
        public int getMaxPage() {
            int totalpage=this.total/this.rows;
            if(this.total%this.rows!=0)
                totalpage++;
            return totalpage;
        }
        
        /**
         * 下一页
         * @return
         */
        public int getNextPage() {
            int nextPage=this.page+1;
            if(this.page>=this.getMaxPage())
                nextPage=this.getMaxPage();
            return nextPage;
        }
        
        /**
         * 上一页
         * @return
         */
        public int getPreivousPage() {
            int previousPage=this.page-1;
            if(previousPage<1)
                previousPage=1;
            return previousPage;
        }
    
        @Override
        public String toString() {
            return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", isPagination=" + isPagination
                    + "]";
        }
    }

    4.后面会给源码,这里给具体的实现:

            //分页实现
            PageBean pageBean = new PageBean();
            pageBean.setPage(2);
            pageBean.setRows(5);
            
            //给分页插件填充页码和行数
            if(null!=pageBean&&pageBean.isPagination())
               PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
    
            //查询实现
            List<Book> books = bookService.queryBookPager(new Book(), pageBean);
            System.out.println(books.getClass());
            //判断分页
            if(null!=pageBean&&pageBean.isPagination()&&null!=books){
                PageInfo<Book> pageInfo = new PageInfo<>(books);
                System.out.println("总记录数:"+pageInfo.getTotal());
                System.out.println("当前页码:"+pageInfo.getPageNum());
                System.out.println("显示条数:"+pageInfo.getPageSize());
                List<Book> list = pageInfo.getList();
                list.forEach(System.out::println);
            }
        

    5.junit单元测试成功如下:

    完整源码地址

    https://www.cnblogs.com/StarChen20/p/13944051.html

  • 相关阅读:
    mysql的一些不常用语句
    redis的使用1
    linux理论知识点(用于考试)
    服务器负载均衡数据同步的实现
    解决com.ibatis.sqlmap.client.SqlMapException: There is no statement named in this SqlMap
    cvc-complex-type.2.3: Element 'beans' cannot have character [children]
    Oracle11g服务详细介绍及哪些服务是必须开启的
    Oracle
    oracle 帐号scott被锁定 如何解锁
    记录
  • 原文地址:https://www.cnblogs.com/StarChen20/p/13938179.html
Copyright © 2011-2022 走看看