在此之前請參考文章:
1、Spring Boot整合Mybatis框架在擴展文件編寫自己的sql語句
2悍缠、Mybatis單表分頁查詢
有兩張數(shù)據(jù)庫表user和user_info,他們是一對一關(guān)系,user_info以user_id關(guān)聯(lián)user表的id
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`username` varchar(20) DEFAULT NULL COMMENT '用戶名',
`password` varchar(100) DEFAULT NULL COMMENT '密碼',
`age` int(3) DEFAULT NULL COMMENT '年齡',
`sex` varchar(1) DEFAULT NULL COMMENT '性別',
`add_time` datetime DEFAULT NULL COMMENT '添加時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
CREATE TABLE `user_info` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL COMMENT '用戶id秸仙,關(guān)聯(lián)user表',
`phone` varchar(20) DEFAULT NULL COMMENT '手機號',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
以user_info為主表關(guān)聯(lián)user表進(jìn)行查詢的語句如下:
SELECT
*
FROM
user_info uf
LEFT JOIN `user` u ON u.id = uf.user_id
WHERE
1 = 1
AND u.sex = '男'
下文將介紹兩種方式實現(xiàn)該語句的分頁查詢功能。
首先編寫dao層相關(guān)代碼
UserInfoMapperExt.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.beibei.doc.dao.user.ext.UserInfoMapperExt" >
<resultMap id="ExtResultMap" extends="com.beibei.doc.dao.user.UserInfoMapper.BaseResultMap" type="com.beibei.doc.model.user.UserInfo" >
</resultMap>
<!-- 排序和分頁參數(shù) -->
<sql id="sort_limit">
<if test="orderBy != null">
order by ${orderBy}
</if>
<if test="limit != null">
limit ${start} , ${limit}
</if>
</sql>
<!-- 需要查詢的字段 -->
<sql id="UserInfo_Column_List" >
*
</sql>
<!-- 查詢的表及查詢條件設(shè)置 -->
<sql id="UserInfo_From_Where" >
FROM
user_info uf
LEFT JOIN `user` u ON u.id = uf.user_id
WHERE
1 = 1
<if test="map.sex != null">
AND u.sex = '${map.sex}'
</if>
</sql>
<!-- 用戶信息分頁查詢 -->
<select id="selectUserInfoListPage" resultType="java.util.Map" parameterType="com.beibei.doc.util.Page">
SELECT
<include refid="UserInfo_Column_List"></include>
<include refid="UserInfo_From_Where"></include>
<include refid="sort_limit"></include>
</select>
<!-- 用戶信息數(shù)量查詢 -->
<select id="selectUserInfoListPageTotal" resultType="java.lang.Integer" parameterType="com.beibei.doc.util.Page">
SELECT
count(*)
<include refid="UserInfo_From_Where"></include>
</select>
</mapper>
UserInfoMapperExt.java文件
package com.beibei.doc.dao.user.ext;
import com.beibei.doc.dao.base.BaseMapperExt;
import com.beibei.doc.model.user.UserInfo;
import com.beibei.doc.model.user.UserInfoExample;
import com.beibei.doc.util.Page;
public interface UserInfoMapperExt extends BaseMapperExt<UserInfo, UserInfoExample> {
}
注意:
1桩盲、其中UserInfoMapperExt.xml文件有兩個select寂纪,id分別是selectUserInfoListPage、selectUserInfoListPageTotal赌结,前者是帶條件聯(lián)表查詢數(shù)據(jù)的sql語句捞蛋,后者是和前者完全一樣的條件查詢數(shù)量的語句,其名稱一定要遵循前者名稱+Total的方式命名柬姚。
parameterType一定要設(shè)置為類com.beibei.doc.util.Page拟杉,這個類源碼請去看文章
Mybatis單表分頁查詢(http://www.reibang.com/p/67b3bfab7da3)
2、UserInfoMapperExt.java文件繼承BaseMapperExt.java量承。
有了dao層搬设,就可以分別用兩種方式實現(xiàn)聯(lián)表分頁查詢了。
方式一:
1宴合、在UserInfoMapperExt.java文件中定義兩個方法焕梅,與UserInfoMapperExt.xml文件中的selectUserInfoListPage、selectUserInfoListPageTotal一一對應(yīng)卦洽,這樣子就可以通過這兩個方法直接執(zhí)行這兩個sql語句了贞言。
需要注意的是方法的返回值要與sql語句中定義的resultType相對應(yīng),如resultType="java.util.Map"對應(yīng)的是List<Map<String, Object>>阀蒂,因為selectUserInfoListPage查詢返回值是多條數(shù)據(jù)该窗,所以是一個list弟蚀。
至于list的泛型可以是map,也可以是任意定義的一個類酗失,這個類中的字段要與sql查詢結(jié)果集的字段對應(yīng)义钉,如果存在查詢結(jié)果中沒有的字段,需要在其getter方法上加注釋@Transient规肴,查詢結(jié)果集中有捶闸,類中沒有的字段則無影響。
里面引用的的Page.java類請參考文章
Mybatis單表分頁查詢 http://www.reibang.com/p/67b3bfab7da3
/**
* 用戶信息分頁查詢
* @param page
* @return
*/
public List<Map<String, Object>> selectUserInfoListPage(Page<UserInfo, UserInfoExample> page);
/**
* 用戶信息數(shù)量查詢
* @param page
* @return
*/
public Integer selectUserInfoListPageTotal(Page<UserInfo, UserInfoExample> page);
2拖刃、service層代碼編寫
創(chuàng)建UserInfoService.java删壮,繼承基類接口類BaseService.java
package com.beibei.doc.service.user;
import java.util.Map;
import com.beibei.doc.model.user.UserInfo;
import com.beibei.doc.model.user.UserInfoExample;
import com.beibei.doc.service.base.BaseService;
import com.beibei.doc.util.RespData;
public interface UserInfoService extends BaseService<UserInfo, UserInfoExample> {
public RespData selectUserInfoListPage(Map<String, Object> param);
}
創(chuàng)建其實現(xiàn)類UserInfoServiceImpl.java,在里面實現(xiàn)分頁查詢方法selectUserInfoListPage兑牡,
package com.beibei.doc.service.user.impl;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.beibei.doc.dao.user.ext.UserInfoMapperExt;
import com.beibei.doc.model.user.UserInfo;
import com.beibei.doc.model.user.UserInfoExample;
import com.beibei.doc.service.base.impl.BaseServiceImpl;
import com.beibei.doc.service.user.UserInfoService;
import com.beibei.doc.util.Page;
import com.beibei.doc.util.RespData;
@Service
public class UserInfoServiceImpl extends BaseServiceImpl<UserInfo, UserInfoExample> implements UserInfoService {
@Autowired
private UserInfoMapperExt userInfoMapperExt;
@Override
public RespData selectUserInfoListPage(Map<String, Object> param) {
RespData data = new RespData();
Page<UserInfo, UserInfoExample> page = new Page<>(param);
page.setMap(param);
Integer total = userInfoMapperExt.selectUserInfoListPageTotal(page);
page.setTotal(total);
List<Map<String, Object>> list = userInfoMapperExt.selectUserInfoListPage(page);
page.setList(list);
data.setData(page.getPageData());
return data;
}
}
到這里分頁功能就實現(xiàn)了央碟,在調(diào)用該方法時候參數(shù)param中要有 下一頁頁碼nextPage 和 每頁數(shù)量limit 兩個key的值,如果需要性別過濾均函,把sex的key值也放入param對象亿虽,然后調(diào)用page.setMap(param);來設(shè)置參數(shù),可以仔細(xì)研究UserInfoMapperExt.xml文件中的代碼片段
<!-- 查詢的表及查詢條件設(shè)置 -->
<sql id="UserInfo_From_Where" >
FROM
user_info uf
LEFT JOIN `user` u ON u.id = uf.user_id
WHERE
1 = 1
<if test="map.sex != null">
AND u.sex = '${map.sex}'
</if>
</sql>
方式二:
我的項目是和Spring Boot整合起來的苞也,請先參考文章
Spring Boot一步步整合Mybatis框架(http://www.reibang.com/p/04aaa872ba30)
1洛勉、在配置類DataBaseConfig.java中加入SqlSessionTemplate的bean聲明
@Bean
public SqlSessionTemplate sqlSessionTemplate(){
return new SqlSessionTemplate(this.sqlSessionFactory());
}
如果是配置文件的應(yīng)該是這樣子吧。
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" />
</bean>
2墩朦、在BaseService.java中定義方法
/**
* <pre>
* 關(guān)聯(lián)表分頁查詢接口
* 說明:該方式查詢實際上是通過sqlSessionTemplate對象來
* 調(diào)用在 MapperExt.xml 文件中定義的查詢sql語句, 因此要指定調(diào)用的select的id
* 以及該select所在的MapperExt.xml文件所對應(yīng)的接口類(該類全名稱作為該MapperExt.xmll文件的命名空間),
* 務(wù)必保證能夠正確拼接出完整的引用路徑坯认。
* 比如一個聯(lián)表查詢的sql: com.beibei.doc.dao.user.ext.UserInfoMapperExt.selectUserInfoListPage
* 傳入?yún)?shù)是 selectId="selectUserInfoListPage", clazz=UserInfoMapperExt.class
* </pre>
* @param selectId 擴展文件MapperExt.xml中定義的查詢語句id
* @param page 分頁對象
* @param clazz 對應(yīng)的MapperExt接口類
* @return
*/
public Page<M, E> selectByParamListPage(String selectId, Page<M, E> page, Class<? extends BaseMapperExt<M, E>> clazz);
在BaseServiceImpl.java中實現(xiàn)上面定義的方法,并且添加自動注入的SqlSessionTemplate對象屬性
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Override
public Page<M, E> selectByParamListPage(String selectId, Page<M, E> page, Class<? extends BaseMapperExt<M, E>> clazz) {
String ext = clazz.toString().replace("interface ", "");
Integer total = sqlSessionTemplate.selectOne(ext + "." + selectId + "Total", page);
page.setTotal(total);
List<?> list = sqlSessionTemplate.selectList(ext + "." + selectId, page);
page.setList(list);
return page;
}
3氓涣、調(diào)用該方法
Page<UserInfo, UserInfoExample> page = new Page<>(param);
page = userInfoService.selectByParamListPage("selectUserInfoListPage", page, UserInfoMapperExt.class);
data.setData(page.getPageData());//獲取分頁查詢結(jié)果
總結(jié)
對比上面兩種方式可以發(fā)現(xiàn)方式一要在MapperExt.xml中定義和select的id相同的方法牛哺,比較麻煩。方式二則可以直接用select的id來調(diào)用BaseService中的selectByParamListPage方法就可以了劳吠,比較方便簡潔引润。