zoukankan      html  css  js  c++  java
  • 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. public class Page {  

    22.     private int pageSize=3;            //页大小  

    23.     private int pageIndex=0;           //当前页号  

    24.     private int totalPageCount=0;      //总页数  

    25.     private int record=0;              //记录总数  

    26.     private Integer nextPage;          //下一页  

    27.     private Integer prePage;           //上一页  

    28.     private List<House> houseList=new ArrayList<House>();     //房屋信息的集合  

    29.       

    30.       

    31.   

    32.     /**     

    33.      * @author Mu Xiongxiong        

    34.      * @created 2017-3-17 下午10:04:41  

    35.      * @return type  

    36.      */  

    37.       

    38.     public List<House> getHouseList() {  

    39.         return houseList;  

    40.     }  

    41.   

    42.     /**      

    43.      * @author Mu Xiongxiong       

    44.      * @created 2017-3-17 下午10:04:41          

    45.      * @param houseList    

    46.      */  

    47.     public void setHouseList(List<House> houseList) {  

    48.         this.houseList = houseList;  

    49.     }  

    50.   

    51.     //得到开始记录数  

    52.     public int getSartRow(){  

    53.         return (pageIndex-1)*pageSize;  

    54.     }  

    55.       

    56.     //得到结束记录数  

    57.     public int getEndRow(){  

    58.         return pageSize;  

    59.     }  

    60.   

    61.     public int getPageSize() {  

    62.         return pageSize;  

    63.     }  

    64.   

    65.     public void setPageSize(int pageSize) {  

    66.         this.pageSize = pageSize;  

    67.     }  

    68.   

    69.     public int getPageIndex() {  

    70.         return pageIndex;  

    71.     }  

    72.   

    73.     //得到当前页  

    74.     public void setPageIndex(int pageIndex) {  

    75.         this.pageIndex = pageIndex;  

    76.         //下一页  

    77.         setNextPage();  

    78.         //上一页  

    79.         setPrePage();  

    80.     }  

    81.   

    82.     public int getTotalPageCount() {  

    83.         return totalPageCount;  

    84.     }  

    85.   

    86.     //总页数  

    87.     public void setTotalPageCount() {  

    88.         int totalP = record % getPageSize() == 0 ? record / getPageSize() :  

    89.             record/ getPageSize() + 1;  

    90.         this.totalPageCount = totalP;  

    91.     }  

    92.   

    93.     public int getRecord() {  

    94.         return record;  

    95.     }  

    96.       

    97.     //总记录数  

    98.     public void setRecord(int record) {  

    99.         this.record = record;  

    100.         //设置总页数  

    101.         setTotalPageCount();  

    102.     }  

    103.   

    104.     public Integer getNextPage() {  

    105.         return nextPage;  

    106.     }  

    107.   

    108.     //设置下一页  

    109.     public void setNextPage() {  

    110.         this.nextPage = this.pageIndex+1;  

    111.           

    112.     }  

    113.   

    114.     public Integer getPrePage() {  

    115.         return prePage;  

    116.     }  

    117.   

    118.     //设置上一页  

    119.     public void setPrePage() {  

    120.         this.prePage =this.pageIndex-1;  

    121.         if(this.prePage<1){  

    122.             this.prePage=1;  

    123.         }  

    124.     }  

    125.       

    126.       

    127.   

    128. }  

         

          现在分页的工具类也出来了,就差分页查询数据了,先看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的博客 这里去看,希望对大家有帮助!

  • 相关阅读:
    BZOJ 1911: [Apio2010]特别行动队
    BZOJ 1096: [ZJOI2007]仓库建设(动态规划+斜率优化)
    BZOJ 2243: [SDOI2011]染色(树链剖分)
    BZOJ 1834: [ZJOI2010]network 网络扩容(网络流+费用流)
    BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分)
    BZOJ 1875: [SDOI2009]HH去散步(矩阵乘法)
    BZOJ 1898: [Zjoi2004]Swamp 沼泽鳄鱼(矩阵乘法)
    BZOJ 2463: [中山市选2009]谁能赢呢?(博弈论)
    BZOJ 2879: [Noi2012]美食节
    BZOJ 1070: [SCOI2007]修车(费用流)
  • 原文地址:https://www.cnblogs.com/a1111/p/14877530.html
Copyright © 2011-2022 走看看