在此之前请参考文章:
1、Spring Boot整合Mybatis框架在扩展文件编写自己的sql语句
2、Mybatis单表分页查询
有两张数据库表user和user_info,他们是一对一关系,user_info以user_id关联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,关联user表',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
以user_info为主表关联user表进行查询的语句如下:
SELECT
*
FROM
user_info uf
LEFT JOIN `user` u ON u.id = uf.user_id
WHERE
1 = 1
AND u.sex = '男'
下文将介绍两种方式实现该语句的分页查询功能。
首先编写dao层相关代码
UserInfoMapperExt.xml文件
order by ${orderBy}
limit ${start} , ${limit}
*
FROM
user_info uf
LEFT JOIN `user` u ON u.id = uf.user_id
WHERE
1 = 1
AND u.sex = '${map.sex}'
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 {
}
注意:
1、其中UserInfoMapperExt.xml文件有两个select,id分别是selectUserInfoListPage、selectUserInfoListPageTotal,前者是带条件联表查询数据的sql语句,后者是和前者完全一样的条件查询数量的语句,其名称一定要遵循前者名称+Total的方式命名。
parameterType一定要设置为类com.beibei.doc.util.Page,这个类源码请去看文章
Mybatis单表分页查询(http://www.jianshu.com/p/67b3bfab7da3)
2、UserInfoMapperExt.java文件继承BaseMapperExt.java。
有了dao层,就可以分别用两种方式实现联表分页查询了。
方式一:
1、在UserInfoMapperExt.java文件中定义两个方法,与UserInfoMapperExt.xml文件中的selectUserInfoListPage、selectUserInfoListPageTotal一一对应,这样子就可以通过这两个方法直接执行这两个sql语句了。
需要注意的是方法的返回值要与sql语句中定义的resultType相对应,如resultType="java.util.Map"对应的是List
里面引用的的Page.java类请参考文章
Mybatis单表分页查询 http://www.jianshu.com/p/67b3bfab7da3
/**
* 用户信息分页查询
* @param page
* @return
*/
public List
2、service层代码编写
创建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 {
public RespData selectUserInfoListPage(Map param);
}
创建其实现类UserInfoServiceImpl.java,在里面实现分页查询方法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 implements UserInfoService {
@Autowired
private UserInfoMapperExt userInfoMapperExt;
@Override
public RespData selectUserInfoListPage(Map param) {
RespData data = new RespData();
Page page = new Page<>(param);
page.setMap(param);
Integer total = userInfoMapperExt.selectUserInfoListPageTotal(page);
page.setTotal(total);
List
到这里分页功能就实现了,在调用该方法时候参数param中要有 下一页页码nextPage 和 每页数量limit 两个key的值,如果需要性别过滤,把sex的key值也放入param对象,然后调用page.setMap(param);来设置参数,可以仔细研究UserInfoMapperExt.xml文件中的代码片段
FROM
user_info uf
LEFT JOIN `user` u ON u.id = uf.user_id
WHERE
1 = 1
AND u.sex = '${map.sex}'
方式二:
我的项目是和Spring Boot整合起来的,请先参考文章
Spring Boot一步步整合Mybatis框架(http://www.jianshu.com/p/04aaa872ba30)
1、在配置类DataBaseConfig.java中加入SqlSessionTemplate的bean声明
@Bean
public SqlSessionTemplate sqlSessionTemplate(){
return new SqlSessionTemplate(this.sqlSessionFactory());
}
如果是配置文件的应该是这样子吧。
2、在BaseService.java中定义方法
/**
*
* 关联表分页查询接口
* 说明:该方式查询实际上是通过sqlSessionTemplate对象来
* 调用在 MapperExt.xml 文件中定义的查询sql语句, 因此要指定调用的select的id
* 以及该select所在的MapperExt.xml文件所对应的接口类(该类全名称作为该MapperExt.xmll文件的命名空间),
* 务必保证能够正确拼接出完整的引用路径。
* 比如一个联表查询的sql: com.beibei.doc.dao.user.ext.UserInfoMapperExt.selectUserInfoListPage
* 传入参数是 selectId="selectUserInfoListPage", clazz=UserInfoMapperExt.class
*
* @param selectId 扩展文件MapperExt.xml中定义的查询语句id
* @param page 分页对象
* @param clazz 对应的MapperExt接口类
* @return
*/
public Page selectByParamListPage(String selectId, Page page, Class extends BaseMapperExt> clazz);
在BaseServiceImpl.java中实现上面定义的方法,并且添加自动注入的SqlSessionTemplate对象属性
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Override
public Page selectByParamListPage(String selectId, Page page, Class extends BaseMapperExt> 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、调用该方法
Page page = new Page<>(param);
page = userInfoService.selectByParamListPage("selectUserInfoListPage", page, UserInfoMapperExt.class);
data.setData(page.getPageData());//获取分页查询结果
总结
对比上面两种方式可以发现方式一要在MapperExt.xml中定义和select的id相同的方法,比较麻烦。方式二则可以直接用select的id来调用BaseService中的selectByParamListPage方法就可以了,比较方便简洁。