Mybatis聯(lián)表分頁查詢

在此之前請參考文章:
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方法就可以了劳吠,比較方便簡潔引润。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市痒玩,隨后出現(xiàn)的幾起案子淳附,更是在濱河造成了極大的恐慌,老刑警劉巖蠢古,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奴曙,死亡現(xiàn)場離奇詭異,居然都是意外死亡草讶,警方通過查閱死者的電腦和手機洽糟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坤溃,你說我怎么就攤上這事拍霜。” “怎么了薪介?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵祠饺,是天一觀的道長。 經(jīng)常有香客問我汁政,道長道偷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任烂完,我火速辦了婚禮试疙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抠蚣。我一直安慰自己,他們只是感情好履澳,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布嘶窄。 她就那樣靜靜地躺著,像睡著了一般距贷。 火紅的嫁衣襯著肌膚如雪柄冲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天忠蝗,我揣著相機與錄音现横,去河邊找鬼。 笑死阁最,一個胖子當(dāng)著我的面吹牛戒祠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播速种,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼姜盈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了配阵?” 一聲冷哼從身側(cè)響起馏颂,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棋傍,沒想到半個月后救拉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡瘫拣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年亿絮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡壹无,死狀恐怖葱绒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斗锭,我是刑警寧澤地淀,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站岖是,受9級特大地震影響帮毁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜豺撑,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一烈疚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧聪轿,春花似錦爷肝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至音瓷,卻和暖如春对嚼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绳慎。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工纵竖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人杏愤。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓靡砌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親声邦。 傳聞我的和親對象是個殘疾皇子乏奥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL亥曹、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,523評論 0 4
  • 1 引言# 本文主要講解JDBC怎么演變到Mybatis的漸變過程邓了,重點講解了為什么要將JDBC封裝成Mybait...
    七寸知架構(gòu)閱讀 76,473評論 36 980
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法媳瞪,內(nèi)部類的語法骗炉,繼承相關(guān)的語法,異常的語法蛇受,線程的語...
    子非魚_t_閱讀 31,643評論 18 399
  • 心中很不能平靜句葵。 地獄老師的課上,已有打碎器材的前科的我,這次做了成功的血涂片乍丈,還在同桌的顯微鏡上剂碴。 老師過來發(fā)現(xiàn)...
    DrChang閱讀 249評論 0 1
  • 一、不得因為喪事收受任何人的一文錢轻专,但老朋友的不在此列忆矛; 二、趕快收殮请垛,埋掉拉倒催训; 三、不要做任何關(guān)于紀(jì)念的事情宗收;...
    椿樹閱讀 773評論 0 0