`
mxx_1111
  • 浏览: 61495 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Mybatis+MySQL动态分页查询数据经典案例(含代码以及测试)

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

开发人员:1111

开发软件:Myeclipse

用到的框架技术:Mybatis

数据库:MySql

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


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

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

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<typeAliases>
	
		<!-- 动态查询房屋信息的条件类 -->
		<typeAlias type="cn.bdqn.mhouse.entity.HouseCondition" alias="houseC"/>
		<typeAlias type="cn.bdqn.mhouse.util.Page" alias="page"/>
		<!-- 区县别名 -->
		<typeAlias type="cn.bdqn.mhouse.entity.District" alias="district"/>
		<typeAlias type="cn.bdqn.mhouse.dao.IDistrictDao" alias="districtDao"/>
		<!-- 房屋信息的别名 -->
		<typeAlias type="cn.bdqn.mhouse.entity.House" alias="house"/>
		<typeAlias type="cn.bdqn.mhouse.dao.IHouseDao" alias="houseDao"/>
		<!-- 街道信息的别名 -->
		<typeAlias type="cn.bdqn.mhouse.entity.Street" alias="street"/>
		<typeAlias type="cn.bdqn.mhouse.dao.IStreetDao" alias="streetDao"/>
		<!-- 房屋类型的别名 -->
		<typeAlias type="cn.bdqn.mhouse.entity.Types" alias="types"/>
		<typeAlias type="cn.bdqn.mhouse.dao.ITypesDao" alias="typesDao"/>
		<!-- 用户信息的别名 -->
		<typeAlias type="cn.bdqn.mhouse.entity.Users" alias="users"/>
		<typeAlias type="cn.bdqn.mhouse.dao.IUsersDao" alias="usersDao"/>
	</typeAliases>
	<environments default="Mysqldevelopment">
		<!-- oracle的数据库配置  -->
		<environment id="Oracledevelopment">
		<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
			<property name="driver" value="oracle.jdbc.OracleDriver"/>
			<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
			<property name="username" value="scott"/>
			<property name="password" value="123"/>
			</dataSource>
		</environment>
		<!-- mysql的数据库配置 -->
		<environment id="Mysqldevelopment">
		<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
			<property name="driver" value="com.mysql.jdbc.Driver"/>
			<property name="url" value="jdbc:mysql://192.168.1.128:3306/house"/>
			<property name="username" value="root"/>
			<property name="password" value="171268"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="cn/bdqn/mhouse/dao/DistrictDaoMapper.xml"/>
		<mapper resource="cn/bdqn/mhouse/dao/HouseDaoMapper.xml"/>
		<mapper resource="cn/bdqn/mhouse/dao/StreetDaoMapper.xml"/>
		<mapper resource="cn/bdqn/mhouse/dao/TypesDaoMapper.xml"/>
		<mapper resource="cn/bdqn/mhouse/dao/UsersDaoMapper.xml"/>
	</mappers>
</configuration>

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

动态查询数据的impl代码:

/**
	 * (非 Javadoc)
	* <p>Title: reCount</p>
	* <p>Description(描述):动态查询总计录数</p>
	* @param housec
	* @return
	* @see cn.bdqn.mhouse.dao.IHouseDao#reCount(cn.bdqn.mhouse.entity.HouseCondition)
	 */
	@Override
	public int reCount(HouseCondition housec) {
		SqlSession session=MybatisUtil.getSession();
		Integer count=(Integer)session.selectOne("houseDao.reCount",housec);
		return count;
	}

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

 <!-- 动态查询房屋信息的总记录数 -->
  
  <select id="reCount" parameterType="houseC" resultType="Integer">
	select count(0) from house h
	<where>
		<if test="priceBegin!=null">
			 and h.price > #{priceBegin}
		</if>
		<if test="priceEnd!=null">
			and h.price   <![CDATA[<]]>  #{priceEnd}
		</if>
		<!-- h.street_id是数据库的字段名 -->
		<if test="street!=null">
			 and h.street_id = #{street.id}
		 </if>
		 <!-- h.type_id是数据库的字段名 -->
		 <if test="types!=null">
		 	 and h.type_id = #{types.id}  
		 </if> 
		<if test="floorageBegin!=null">
			 and h.floorage > #{floorageBegin}  
		</if>
		<if test="floorageEnd!=null">
			and h.floorage <![CDATA[<]]>  #{floorageEnd}
		</if>
	</where>
  </select>

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

  <resultMap id="BaseResultMap" type="house" >
    <id column="ID" property="id" jdbcType="INTEGER" />
    <result column="TITLE" property="title" jdbcType="VARCHAR" />
    <result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
    <result column="PRICE" property="price" jdbcType="REAL" />
    <result column="PUBDATE" property="pubdate" jdbcType="DATE" />
    <result column="FLOORAGE" property="floorage" jdbcType="INTEGER" />
    <result column="CONTACT" property="contact" jdbcType="VARCHAR" />
    <!-- 开始映射外键 -->
    <!-- 映射用户表 -->
    <association property="users" column="user_id" select="selectUsers"/>
    <!-- 映射类型表 -->
    <association property="types" column="type_id" select="selectTypes"/>
    <!-- 映射街道表 -->
    <association property="street" column="street_id" select="selectStreet"/>
  </resultMap>
  <!-- 关联用户表 -->
  <resultMap id="usersMapper" type="users" >
    <id column="ID" property="id" jdbcType="INTEGER" />
    <result column="NAME" property="name" jdbcType="VARCHAR" />
    <result column="PASSWORD" property="password" jdbcType="VARCHAR" />
    <result column="TELEPHONE" property="telephone" jdbcType="VARCHAR" />
    <result column="USERNAME" property="username" jdbcType="VARCHAR" />
    <result column="ISADMIN" property="isadmin" jdbcType="VARCHAR" />
  </resultMap>
  <!-- 关联街道表 -->
  <resultMap id="streetMapper" type="street" >
    <id column="ID" property="id" />
    <result column="NAME" property="name" jdbcType="VARCHAR" />
 	<association property="district" column="district_id" select ="selectDirstrict"/>
  </resultMap>
  <!-- 关联区县表 -->
  	<resultMap id="districtDaoMapper" type="district" >
	    <id column="ID" property="id"/>
	    <result column="NAME" property="name"/>
 	 </resultMap>
		 <!-- 在根据区县id查询一遍区县表 -->
		 	<select id="selectDirstrict" resultMap="districtDaoMapper">
		 		select * form district where id=#{district_id}	
		 	</select>
  <!--关联类型表  -->
 	<resultMap id="typeMapper" type="types" >
	    <id column="ID" property="id"/>
	    <result column="NAME" property="name" jdbcType="VARCHAR" />
 	 </resultMap>
 	 
  <!-- 用户表 -->
  <select id="selectUsers" resultMap="usersMapper">
  	select * from users where id=#{user_id}
  </select>
  <!-- 街道表 -->
   <select id="selectStreet" resultMap="streetMapper">
  	select * from street where id=#{street_id}
  </select>
  <!-- 类型表 -->
  	<select id="selectTypes" resultMap="typeMapper">
  	select * from types where id=#{type_id}
  </select>
  <sql id="Base_Column_List" >
    ID, USER_ID, TYPE_ID, TITLE, DESCRIPTION, PRICE, PUBDATE, FLOORAGE, CONTACT, STREET_ID
  </sql>

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

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

package cn.bdqn.mhouse.util;

import java.util.ArrayList;
import java.util.List;

import cn.bdqn.mhouse.entity.House;

/**
 * 
*    
* 项目名称:mhouse   
* 类名称:Page   
* 类描述:   分页的工具类
* 创建人:Mu Xiongxiong  
* 创建时间:2017-3-17 下午1:04:02   
* 修改人:Mu Xiongxiong   
* 修改时间:2017-3-17 下午1:04:02   
* 修改备注:   
* @version    
*
 */
public class Page {
	private int pageSize=3;            //页大小
	private int pageIndex=0;           //当前页号
	private int totalPageCount=0;      //总页数
	private int record=0;              //记录总数
	private Integer nextPage;          //下一页
	private Integer prePage;           //上一页
	private List<House> houseList=new ArrayList<House>();     //房屋信息的集合
	
	

	/**    
	 * @author Mu Xiongxiong       
	 * @created 2017-3-17 下午10:04:41 
	 * @return type 
	 */
	
	public List<House> getHouseList() {
		return houseList;
	}

	/**     
	 * @author Mu Xiongxiong      
	 * @created 2017-3-17 下午10:04:41         
	 * @param houseList   
	 */
	public void setHouseList(List<House> houseList) {
		this.houseList = houseList;
	}

	//得到开始记录数
	public int getSartRow(){
		return (pageIndex-1)*pageSize;
	}
	
	//得到结束记录数
	public int getEndRow(){
		return pageSize;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getPageIndex() {
		return pageIndex;
	}

	//得到当前页
	public void setPageIndex(int pageIndex) {
		this.pageIndex = pageIndex;
		//下一页
		setNextPage();
		//上一页
		setPrePage();
	}

	public int getTotalPageCount() {
		return totalPageCount;
	}

	//总页数
	public void setTotalPageCount() {
		int totalP = record % getPageSize() == 0 ? record / getPageSize() :
			record/ getPageSize() + 1;
		this.totalPageCount = totalP;
	}

	public int getRecord() {
		return record;
	}
	
	//总记录数
	public void setRecord(int record) {
		this.record = record;
		//设置总页数
		setTotalPageCount();
	}

	public Integer getNextPage() {
		return nextPage;
	}

	//设置下一页
	public void setNextPage() {
		this.nextPage = this.pageIndex+1;
		
	}

	public Integer getPrePage() {
		return prePage;
	}

	//设置上一页
	public void setPrePage() {
		this.prePage =this.pageIndex-1;
		if(this.prePage<1){
			this.prePage=1;
		}
	}
	
	

}

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

	/**
	 * (非 Javadoc)
	* <p>Title: getHouseInfoByDymanic</p>
	* <p>Description:‘动态分页查询房屋信息</p>
	* @param housec
	* @param pageIndex
	* @return
	* @see cn.bdqn.mhouse.dao.IHouseDao#getHouseInfoByDymanic(cn.bdqn.mhouse.entity.HouseCondition, int)
	 */
	@Override
	public Page getHouseInfoByDymanic(HouseCondition housec,int pageIndex) {
		Page page=new Page();
		page.setPageIndex(pageIndex);      //当前页
		int reCount=reCount(housec);       
		page.setRecord(reCount);           //总记录数
		List<House> houseList=new ArrayList<House>();
		HashMap parMap=new HashMap();
		parMap.put("priceBegin",housec.getPriceBegin());
		parMap.put("priceEnd",housec.getPriceEnd());
		if(housec.getStreet()!=null){
		parMap.put("street",housec.getStreet());
		}
		if(housec.getTypes()!=null){
			parMap.put("types",housec.getTypes());
		}
		parMap.put("floorageBegin", housec.getFloorageBegin());
		parMap.put("floorageEnd",housec.getFloorageEnd());
		parMap.put("stratRow",page.getSartRow());
		parMap.put("endRow",page.getEndRow());
		SqlSession session=MybatisUtil.getSession();
		try {
			houseList=session.selectList("houseDao.getHouseInfoByDymanic",parMap);
			page.setHouseList(houseList);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			MybatisUtil.closeSession();
		}
		return page;
	}

对应的Mapper.xml配置信息:

 <!-- 分页动态查询房屋信息 -->
  <select id="getHouseInfoByDymanic" parameterType="hashmap" resultType="house">
  		select * from house h
	<where>
		<if test="priceBegin!=null">
			 and h.price > #{priceBegin}
		</if>
		<if test="priceEnd!=null">
			and h.price   <![CDATA[<]]>  #{priceEnd}
		</if>
		<if test="street!=null">
			 and h.street_id = #{street.id}
		 </if>
		<if test="types!=null||!types==null">
		 	 and h.type_id = #{types.id}  
		 </if>
		<if test="floorageBegin!=null">
			 and h.floorage > #{floorageBegin}  
		</if>
		<if test="floorageEnd!=null">
			and h.floorage <![CDATA[<]]>  #{floorageEnd}
		</if>
	</where>
		    limit #{stratRow},#{endRow}
  </select>

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

	/**
	 * 
	* @Title: reCount
	* @Description: 该方法的主要作用:分页查询房屋信息
	* @param   设定文件  
	* @return  返回类型:void   
	* @throws
	 */
	@Test
	public void getHouseInfoByDymanic(){
		Page page=new Page();
//		houseC.setPriceBegin(50);                      //起始价格
//		houseC.setPriceEnd(4000);                      //结束价格
//		houseC.setFloorageBegin(10);                   //起始面积
//		houseC.setFloorageEnd(6000);                   //最终面积
		types.setId(1003);                             //房屋类型
		houseC.setTypes(types);
		street.setId(1003);							   //所在的街道
//		//street.setDistrict(district);
		houseC.setStreet(street);
		int pageIndex=3;
		page=houseDao.getHouseInfoByDymanic(houseC, pageIndex);
		System.out.println("当前页是:"+page.getPageIndex());
		System.out.println("下一页是:"+page.getNextPage());
		System.out.println("上一页是:"+page.getPrePage());
		System.out.println("总记录数:"+page.getRecord());
		System.out.println("总页数是:"+page.getTotalPageCount());
		System.out.println("页大小是:"+page.getPageSize());
		List<House> houselist=page.getHouseList();
		for (House house : houselist) {
			System.out.println("房屋标题:"+house.getTitle());
		}
	}

执行完成之后,分页的信息,上一页,下一页,总页数等等都可以正常显示出来,但是,只有数据库里面的数据没有显示出来(调试如图所示):


集合里面是空的!!!

出现错误之后我就开始解决,于是写了个测试查询全部的房屋信息的方法,测试了一遍之后,果然不出所料,查出来的都是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的博客 这里去看,希望对大家有帮助!

分享到:
评论

相关推荐

    原创经典实例spring+mybatis+分页+百万数据

    总的来说,这个"原创经典实例spring+mybatis+分页+百万数据"涵盖了Spring框架的使用、MyBatis的映射方式、以及大数据量下的分页策略。无论你是初学者还是经验丰富的开发者,都可以从中受益,提升自己的技能水平。...

    基于ssm+mysql的小说阅读网站书城源码数据库.zip

    该源码数据库是针对一个小说阅读网站的书城部分,采用了经典的SSM(Spring、SpringMVC、MyBatis)框架结合MySQL数据库进行开发。这是一个常见的企业级Java Web项目架构,适合于毕业设计或者作为学习Java Web开发的...

    java springboot项目经典案例源码,数据增删改查功能齐全,适合初学参考及二次开发。

    java springboot web项目,数据库mysql,采用mybatis+maven+Thymeleaf等开发技术,管理后台可以添加、修改、删除内容及图片,前端页面展示列表内容、内容分页展示、内容详情展示,适合java及springboot初学者参考...

    【Java Web精品资源】图书馆管理系统项目源码(附程序系统录像及项目使用说明)

    4. **搜索与查询**:设计高效的图书查询接口,可能需要用到分页、模糊查询等,理解JPA或MyBatis的动态SQL。 5. **界面设计**:前端界面通常使用HTML、CSS和JavaScript,可能结合Bootstrap或Vue.js等前端框架,提供...

    一个经典的数据库访问层实现

    在本案例中,我们讨论的是一个经典的数据库访问层实现,这通常涉及到面向对象的设计模式,如工厂模式、单例模式以及数据访问对象(DAO)模式。以下是对这个主题的详细解释: 1. 数据访问对象(DAO)模式:DAO模式是...

    BLOG网站建设

    在SpringMVC中,可以通过查询参数获取当前页码和每页显示的数量,然后配合数据库查询语句(如LIMIT和OFFSET)实现数据分页。 5. **富文本编辑器**: 富文本编辑器如CKEditor或TinyMCE,允许用户在网页上编辑格式化...

    最新尚硅谷全套视频

    - 掌握数据库的基本操作,包括数据查询、更新、删除等。 - 学习使用SQL和PL/SQL进行复杂查询和存储过程编写。 - **尚硅谷JDBC视频教程** - JDBC (Java Database Connectivity) 是Java中用来对关系型数据库进行...

    基于springboot微信小程序的闲置品交易平台源码数据库文档.zip

    该项目适合用于毕业设计或者作为学习Java Web开发、微信小程序开发以及SpringBoot集成实践的案例。 1. **SpringBoot框架**: SpringBoot是Spring框架的一个扩展,旨在简化Spring应用的初始搭建以及开发过程。它...

Global site tag (gtag.js) - Google Analytics