Mybatis+MySQL动态分页查询数据经典案例

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: Mybatis+MySQL动态分页查询数据经典案例

 最近在用Mybatis做项目的时候遇到了不少问题,今天我就在这和大家分享一下,稀稀拉拉的研究了两天,终于搞好了!

    开发人员:1111

    开发软件:Myeclipse

    用到的框架技术:Mybatis

    数据库:MySql

    主要内容:动态分页查询数据

      好了,现在开始演示,我先把代码贴上来以便大家的理解:

mybatis-config.xml的主要配置内容:

[html] view plain copy print?

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  3. "http://mybatis.org/dtd/mybatis-3-config.dtd">  
  4. <configuration>  
  5.    <typeAliases>  
  6.      
  7.        <!-- 动态查询房屋信息的条件类 -->  
  8.        <typeAlias type="cn.bdqn.mhouse.entity.HouseCondition" alias="houseC"/>  
  9.        <typeAlias type="cn.bdqn.mhouse.util.Page" alias="page"/>  
  10.        <!-- 区县别名 -->  
  11.        <typeAlias type="cn.bdqn.mhouse.entity.District" alias="district"/>  
  12.        <typeAlias type="cn.bdqn.mhouse.dao.IDistrictDao" alias="districtDao"/>  
  13.        <!-- 房屋信息的别名 -->  
  14.        <typeAlias type="cn.bdqn.mhouse.entity.House" alias="house"/>  
  15.        <typeAlias type="cn.bdqn.mhouse.dao.IHouseDao" alias="houseDao"/>  
  16.        <!-- 街道信息的别名 -->  
  17.        <typeAlias type="cn.bdqn.mhouse.entity.Street" alias="street"/>  
  18.        <typeAlias type="cn.bdqn.mhouse.dao.IStreetDao" alias="streetDao"/>  
  19.        <!-- 房屋类型的别名 -->  
  20.        <typeAlias type="cn.bdqn.mhouse.entity.Types" alias="types"/>  
  21.        <typeAlias type="cn.bdqn.mhouse.dao.ITypesDao" alias="typesDao"/>  
  22.        <!-- 用户信息的别名 -->  
  23.        <typeAlias type="cn.bdqn.mhouse.entity.Users" alias="users"/>  
  24.        <typeAlias type="cn.bdqn.mhouse.dao.IUsersDao" alias="usersDao"/>  
  25.    </typeAliases>  
  26.    <environments default="Mysqldevelopment">  
  27.        <!-- oracle的数据库配置  -->  
  28.        <environment id="Oracledevelopment">  
  29.        <transactionManager type="JDBC"/>  
  30.            <dataSource type="POOLED">  
  31.            <property name="driver" value="oracle.jdbc.OracleDriver"/>  
  32.            <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>  
  33.            <property name="username" value="scott"/>  
  34.            <property name="password" value="123"/>  
  35.            </dataSource>  
  36.        </environment>  
  37.        <!-- mysql的数据库配置 -->  
  38.        <environment id="Mysqldevelopment">  
  39.        <transactionManager type="JDBC"/>  
  40.            <dataSource type="POOLED">  
  41.            <property name="driver" value="com.mysql.jdbc.Driver"/>  
  42.            <property name="url" value="jdbc:mysql://192.168.1.128:3306/house"/>  
  43.            <property name="username" value="root"/>  
  44.            <property name="password" value="171268"/>  
  45.            </dataSource>  
  46.        </environment>  
  47.    </environments>  
  48.    <mappers>  
  49.        <mapper resource="cn/bdqn/mhouse/dao/DistrictDaoMapper.xml"/>  
  50.        <mapper resource="cn/bdqn/mhouse/dao/HouseDaoMapper.xml"/>  
  51.        <mapper resource="cn/bdqn/mhouse/dao/StreetDaoMapper.xml"/>  
  52.        <mapper resource="cn/bdqn/mhouse/dao/TypesDaoMapper.xml"/>  
  53.        <mapper resource="cn/bdqn/mhouse/dao/UsersDaoMapper.xml"/>  
  54.    </mappers>  
  55. </configuration>  

       由于分页查询得用到总记录数,所以我写了两个方法来实现的,第一个是动态查询数据总记录数,接下来大家看看impl类和相对应的Mapper.xml配置信息吧,由于dao接口是由impl实现类来实现的,所以在这我就不给大家放dao层接口的代码了:

     动态查询数据的impl代码:

[java] view plain copy print?

  1. /**
  2.     * (非 Javadoc)
  3.    * <p>Title: reCount</p>
  4.    * <p>Description(描述):动态查询总计录数</p>
  5.    * @param housec
  6.    * @return
  7.    * @see cn.bdqn.mhouse.dao.IHouseDao#reCount(cn.bdqn.mhouse.entity.HouseCondition)
  8.     */  
  9.    @Override  
  10.    public int reCount(HouseCondition housec) {  
  11.        SqlSession session=MybatisUtil.getSession();  
  12.        Integer count=(Integer)session.selectOne("houseDao.reCount",housec);  
  13.        return count;  
  14.    }  

  代码中的MybatisUtils是mybatis的工具类,动态查询数据方法在Mapper.xml里面的配置详情代码:

[html] view plain copy print?

  1. <!-- 动态查询房屋信息的总记录数 -->  
  2.  
  3. <select id="reCount" parameterType="houseC" resultType="Integer">  
  4. select count(0) from house h  
  5. <where>  
  6.    <if test="priceBegin!=null">  
  7.         and h.price > #{priceBegin}  
  8.    </if>  
  9.    <if test="priceEnd!=null">  
  10.        and h.price   <![CDATA[<]]>  #{priceEnd}  
  11.    </if>  
  12.    <!-- h.street_id是数据库的字段名 -->  
  13.    <if test="street!=null">  
  14.         and h.street_id = #{street.id}  
  15.     </if>  
  16.     <!-- h.type_id是数据库的字段名 -->  
  17.     <if test="types!=null">  
  18.         and h.type_id = #{types.id}    
  19.     </if>  
  20.    <if test="floorageBegin!=null">  
  21.         and h.floorage > #{floorageBegin}    
  22.    </if>  
  23.    <if test="floorageEnd!=null">  
  24.        and h.floorage <![CDATA[<]]>  #{floorageEnd}  
  25.    </if>  
  26. </where>  
  27. </select>  

      然后我把表与表之间的关联映射在放上来供大家看看:

[html] view plain copy print?

  1. <resultMap id="BaseResultMap" type="house" >  
  2.  <id column="ID" property="id" jdbcType="INTEGER" />  
  3.  <result column="TITLE" property="title" jdbcType="VARCHAR" />  
  4.  <result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />  
  5.  <result column="PRICE" property="price" jdbcType="REAL" />  
  6.  <result column="PUBDATE" property="pubdate" jdbcType="DATE" />  
  7.  <result column="FLOORAGE" property="floorage" jdbcType="INTEGER" />  
  8.  <result column="CONTACT" property="contact" jdbcType="VARCHAR" />  
  9.  <!-- 开始映射外键 -->  
  10.  <!-- 映射用户表 -->  
  11.  <association property="users" column="user_id" select="selectUsers"/>  
  12.  <!-- 映射类型表 -->  
  13.  <association property="types" column="type_id" select="selectTypes"/>  
  14.  <!-- 映射街道表 -->  
  15.  <association property="street" column="street_id" select="selectStreet"/>  
  16. </resultMap>  
  17. <!-- 关联用户表 -->  
  18. <resultMap id="usersMapper" type="users" >  
  19.  <id column="ID" property="id" jdbcType="INTEGER" />  
  20.  <result column="NAME" property="name" jdbcType="VARCHAR" />  
  21.  <result column="PASSWORD" property="password" jdbcType="VARCHAR" />  
  22.  <result column="TELEPHONE" property="telephone" jdbcType="VARCHAR" />  
  23.  <result column="USERNAME" property="username" jdbcType="VARCHAR" />  
  24.  <result column="ISADMIN" property="isadmin" jdbcType="VARCHAR" />  
  25. </resultMap>  
  26. <!-- 关联街道表 -->  
  27. <resultMap id="streetMapper" type="street" >  
  28.  <id column="ID" property="id" />  
  29.  <result column="NAME" property="name" jdbcType="VARCHAR" />  
  30. <association property="district" column="district_id" select ="selectDirstrict"/>  
  31. </resultMap>  
  32. <!-- 关联区县表 -->  
  33.    <resultMap id="districtDaoMapper" type="district" >  
  34.   <id column="ID" property="id"/>  
  35.   <result column="NAME" property="name"/>  
  36. </resultMap>  
  37. <!-- 在根据区县id查询一遍区县表 -->  
  38.    <select id="selectDirstrict" resultMap="districtDaoMapper">  
  39.        select * form district where id=#{district_id}    
  40.    </select>  
  41. <!--关联类型表  -->  
  42. <resultMap id="typeMapper" type="types" >  
  43.   <id column="ID" property="id"/>  
  44.   <result column="NAME" property="name" jdbcType="VARCHAR" />  
  45. </resultMap>  
  46.  
  47. <!-- 用户表 -->  
  48. <select id="selectUsers" resultMap="usersMapper">  
  49.    select * from users where id=#{user_id}  
  50. </select>  
  51. <!-- 街道表 -->  
  52. <select id="selectStreet" resultMap="streetMapper">  
  53.    select * from street where id=#{street_id}  
  54. </select>  
  55. <!-- 类型表 -->  
  56.    <select id="selectTypes" resultMap="typeMapper">  
  57.    select * from types where id=#{type_id}  
  58. </select>  
  59. <sql id="Base_Column_List" >  
  60.  ID, USER_ID, TYPE_ID, TITLE, DESCRIPTION, PRICE, PUBDATE, FLOORAGE, CONTACT, STREET_ID  
  61. </sql>  

          上面都有相对应的注释,在这就不多做解释了,

            总记录数现在查询出来了,就开始动态分页查询数据了,首先得用到一个分页类Page,分页类的代码:

[java] view plain copy print?

  1. package cn.bdqn.mhouse.util;  
  2.  
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.  
  6. import cn.bdqn.mhouse.entity.House;  
  7.  
  8. /**
  9. *  
  10. *    
  11. * 项目名称:mhouse    
  12. * 类名称:Page    
  13. * 类描述:   分页的工具类
  14. * 创建人:Mu Xiongxiong  
  15. * 创建时间:2017-3-17 下午1:04:02    
  16. * 修改人:Mu Xiongxiong    
  17. * 修改时间:2017-3-17 下午1:04:02    
  18. * 修改备注:    
  19. * @version    
  20. *
  21. */  
  22. public class Page {  
  23.    private int pageSize=3;            //页大小  
  24.    private int pageIndex=0;           //当前页号  
  25.    private int totalPageCount=0;      //总页数  
  26.    private int record=0;              //记录总数  
  27.    private Integer nextPage;          //下一页  
  28.    private Integer prePage;           //上一页  
  29.    private List<House> houseList=new ArrayList<House>();     //房屋信息的集合  
  30.      
  31.      
  32.  
  33.    /**    
  34.     * @author Mu Xiongxiong        
  35.     * @created 2017-3-17 下午10:04:41  
  36.     * @return type  
  37.     */  
  38.      
  39.    public List<House> getHouseList() {  
  40.        return houseList;  
  41.    }  
  42.  
  43.    /**      
  44.     * @author Mu Xiongxiong      
  45.     * @created 2017-3-17 下午10:04:41          
  46.     * @param houseList    
  47.     */  
  48.    public void setHouseList(List<House> houseList) {  
  49.        this.houseList = houseList;  
  50.    }  
  51.  
  52.    //得到开始记录数  
  53.    public int getSartRow(){  
  54.        return (pageIndex-1)*pageSize;  
  55.    }  
  56.      
  57.    //得到结束记录数  
  58.    public int getEndRow(){  
  59.        return pageSize;  
  60.    }  
  61.  
  62.    public int getPageSize() {  
  63.        return pageSize;  
  64.    }  
  65.  
  66.    public void setPageSize(int pageSize) {  
  67.        this.pageSize = pageSize;  
  68.    }  
  69.  
  70.    public int getPageIndex() {  
  71.        return pageIndex;  
  72.    }  
  73.  
  74.    //得到当前页  
  75.    public void setPageIndex(int pageIndex) {  
  76.        this.pageIndex = pageIndex;  
  77.        //下一页  
  78.        setNextPage();  
  79.        //上一页  
  80.        setPrePage();  
  81.    }  
  82.  
  83.    public int getTotalPageCount() {  
  84.        return totalPageCount;  
  85.    }  
  86.  
  87.    //总页数  
  88.    public void setTotalPageCount() {  
  89.        int totalP = record % getPageSize() == 0 ? record / getPageSize() :  
  90.            record/ getPageSize() + 1;  
  91.        this.totalPageCount = totalP;  
  92.    }  
  93.  
  94.    public int getRecord() {  
  95.        return record;  
  96.    }  
  97.      
  98.    //总记录数  
  99.    public void setRecord(int record) {  
  100.        this.record = record;  
  101.        //设置总页数  
  102.        setTotalPageCount();  
  103.    }  
  104.  
  105.    public Integer getNextPage() {  
  106.        return nextPage;  
  107.    }  
  108.  
  109.    //设置下一页  
  110.    public void setNextPage() {  
  111.        this.nextPage = this.pageIndex+1;  
  112.          
  113.    }  
  114.  
  115.    public Integer getPrePage() {  
  116.        return prePage;  
  117.    }  
  118.  
  119.    //设置上一页  
  120.    public void setPrePage() {  
  121.        this.prePage =this.pageIndex-1;  
  122.        if(this.prePage<1){  
  123.            this.prePage=1;  
  124.        }  
  125.    }  
  126.      
  127.      
  128.  
  129. }  

   

     现在分页的工具类也出来了,就差分页查询数据了,先看impl里面的方法:

[java] view plain copy print?

  1. /**
  2. * (非 Javadoc)
  3. * <p>Title: getHouseInfoByDymanic</p>
  4. * <p>Description:‘动态分页查询房屋信息</p>
  5. * @param housec
  6. * @param pageIndex
  7. * @return
  8. * @see cn.bdqn.mhouse.dao.IHouseDao#getHouseInfoByDymanic(cn.bdqn.mhouse.entity.HouseCondition, int)
  9. */  
  10. @Override  
  11. public Page getHouseInfoByDymanic(HouseCondition housec,int pageIndex) {  
  12.    Page page=new Page();  
  13.    page.setPageIndex(pageIndex);      //当前页  
  14.    int reCount=reCount(housec);        
  15.    page.setRecord(reCount);           //总记录数  
  16.    List<House> houseList=new ArrayList<House>();  
  17.    HashMap parMap=new HashMap();  
  18.    parMap.put("priceBegin",housec.getPriceBegin());  
  19.    parMap.put("priceEnd",housec.getPriceEnd());  
  20.    if(housec.getStreet()!=null){  
  21.    parMap.put("street",housec.getStreet());  
  22.    }  
  23.    if(housec.getTypes()!=null){  
  24.        parMap.put("types",housec.getTypes());  
  25.    }  
  26.    parMap.put("floorageBegin", housec.getFloorageBegin());  
  27.    parMap.put("floorageEnd",housec.getFloorageEnd());  
  28.    parMap.put("stratRow",page.getSartRow());  
  29.    parMap.put("endRow",page.getEndRow());  
  30.    SqlSession session=MybatisUtil.getSession();  
  31.    try {  
  32.        houseList=session.selectList("houseDao.getHouseInfoByDymanic",parMap);  
  33.        page.setHouseList(houseList);  
  34.    } catch (Exception e) {  
  35.        e.printStackTrace();  
  36.    }finally{  
  37.        MybatisUtil.closeSession();  
  38.    }  
  39.    return page;  
  40. }  

       对应的Mapper.xml配置信息:

[html] view plain copy print?

  1. <!-- 分页动态查询房屋信息 -->  
  2. <select id="getHouseInfoByDymanic" parameterType="hashmap" resultMap="BaseResultMap">  
  3.        select * from house h  
  4. <where>  
  5.    <if test="priceBegin!=null">  
  6.         and h.price > #{priceBegin}  
  7.    </if>  
  8.    <if test="priceEnd!=null">  
  9.        and h.price   <![CDATA[<]]>  #{priceEnd}  
  10.    </if>  
  11.    <if test="street!=null">  
  12.         and h.street_id = #{street.id}  
  13.     </if>  
  14.    <if test="types!=null||!types==null">  
  15.         and h.type_id = #{types.id}    
  16.     </if>  
  17.    <if test="floorageBegin!=null">  
  18.         and h.floorage > #{floorageBegin}    
  19.    </if>  
  20.    <if test="floorageEnd!=null">  
  21.        and h.floorage <![CDATA[<]]>  #{floorageEnd}  
  22.    </if>  
  23. </where>  
  24.        limit #{stratRow},#{endRow}  
  25. </select>  

   最后我写了test测试,看看能不能正常执行:test测试类的方法如下:

[java] view plain copy print?

  1.    /**
  2.     *  
  3.    * @Title: reCount
  4.    * @Description: 该方法的主要作用:分页查询房屋信息
  5.    * @param   设定文件  
  6.    * @return  返回类型:void    
  7.    * @throws
  8.     */  
  9.    @Test  
  10.    public void getHouseInfoByDymanic(){  
  11.        Page page=new Page();  
  12. //      houseC.setPriceBegin(50);                      //起始价格  
  13. //      houseC.setPriceEnd(4000);                      //结束价格  
  14. //      houseC.setFloorageBegin(10);                   //起始面积  
  15. //      houseC.setFloorageEnd(6000);                   //最终面积  
  16.        types.setId(1003);                             //房屋类型  
  17.        houseC.setTypes(types);  
  18.        street.setId(1003);                            //所在的街道  
  19. //      //street.setDistrict(district);  
  20.        houseC.setStreet(street);  
  21.        int pageIndex=3;  
  22.        page=houseDao.getHouseInfoByDymanic(houseC, pageIndex);  
  23.        System.out.println("当前页是:"+page.getPageIndex());  
  24.        System.out.println("下一页是:"+page.getNextPage());  
  25.        System.out.println("上一页是:"+page.getPrePage());  
  26.        System.out.println("总记录数:"+page.getRecord());  
  27.        System.out.println("总页数是:"+page.getTotalPageCount());  
  28.        System.out.println("页大小是:"+page.getPageSize());  
  29.        List<House> houselist=page.getHouseList();  
  30.        for (House house : houselist) {  
  31.            System.out.println("房屋标题:"+house.getTitle());  
  32.        }  
  33.    }
         执行完成之后,分页的信息,上一页,下一页,总页数等等都可以正常显示出来,但是,只有数据库里面的数据没有显示出来(调试如图所示):

    集合里面是空的!!!

      出现错误之后我就开始解决,于是写了个测试查询全部的房屋信息的方法,测试了一遍之后,果然不出所料,查出来的都是null,更为奇怪的是:数据库中有34条记录,而程序运行后查询出来的是34个null,对没错,就是34个null,一个也不多,一个也不少!!!

     但是还很纳闷,于是各种假设各种调试,还是不行,当我吧问题发在csdn上面问的时候,忽然想起来了,原来是映射的resultType错了,我查询的是house,应该映射的是house实体类的权限定名,我写的是Page的全限定名,我写成page也不足为奇,因为我的返回类型就是page,   哎 ,就这个错,我弄了两小时才解决掉!!!实现是累的不行了!

     这个问题解决了之后,我就继续测试其他的功能,现在是数据数来了,但是正儿八经最主要的测试还没进行呢,汗,于是我就开始测试动态查询数据,一步一步的测试的时候,错又来了,我把错误信息贴上来大家看看:

org.apache.ibatis.exceptions.PersistenceException:

### Error querying database.  Cause: org.apache.ibatis.reflection.ReflectionException:There is no getter for property named 'id' in 'class java.lang.Integer'

### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.lang.Integer'

,嘴里骂了一句之后,拿起水杯干了一杯普利斯,挽起袖子就开始调试!我就不信还解决不了你了,

          慢慢的。。。慢慢的,时间过来20分钟之后终于找出来了,原来是类型错了!我给大家看看错误代码和正确代码:

      错误代码:

    大家注意红色框中的代码,我取的是对象,而后面赋值的却是id,怪不得报错!!!

      正确的代码如下:

    还是老规矩,看红框中的代码,去掉getId()就可以正常运行了!!!

     还有其他的好多细节错误来着,这里就不具体详细说了,要想查看完整的分页动态查询代码,请移步到 1111的博客 这里去看,希望对大家有帮助!

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
21 1
|
1月前
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
15 1
|
18天前
|
Java 关系型数据库 MySQL
【mybatis-plus】自定义多数据源,动态切换数据源事务失效问题
【mybatis-plus】自定义多数据源,动态切换数据源事务失效问题
【mybatis-plus】自定义多数据源,动态切换数据源事务失效问题
|
24天前
|
存储 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT *、分页查询的优化、合理使用连接、子查询的优化)(上)
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT *、分页查询的优化、合理使用连接、子查询的优化)(上)
|
29天前
|
Java 数据库连接 mybatis
mybatis plus字段为null或空字符串把原来的数据也更新了,只需要注解
mybatis plus字段为null或空字符串把原来的数据也更新了,只需要注解
19 0
|
4天前
|
SQL 存储 关系型数据库
MySQL Cluster集群安装及使用
MySQL Cluster集群安装及使用
|
19天前
|
关系型数据库 MySQL 数据库
mysql卸载、下载、安装(window版本)
mysql卸载、下载、安装(window版本)
|
8天前
|
关系型数据库 MySQL 数据库
《MySQL 简易速速上手小册》第1章:MySQL 基础和安装(2024 最新版)
《MySQL 简易速速上手小册》第1章:MySQL 基础和安装(2024 最新版)
33 4
|
1月前
|
Ubuntu 关系型数据库 MySQL
Ubuntu 中apt 安装MySQL数据库
Ubuntu 中apt 安装MySQL数据库
69 0
|
2天前
|
关系型数据库 MySQL 数据安全/隐私保护
安装mysql和远程连接
安装mysql和远程连接
10 0