Mybatis+MySQL動態分頁查詢資料經典案例(含程式碼以及測試)
開發人員: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" resultMap="BaseResultMap">
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的部落格 這裡去看,希望對大家有幫助!