【spring boot】14.spring boot集成mybatis,注解方式OR映射文件方式AND pagehelper分页插件【Mybatis】pagehelper分页插件分页查询无效解决方法
spring boot集成mybatis,集成使用mybatis拖沓了好久,今天终于可以补起来了。
本篇源码中,同时使用了Spring data JPA 和 Mybatis两种方式.
在使用的过程中一定要注意,JPA和Mybatis可以在同一个方法中调用,但是如果要保证事务一致性,千万不要把JPA的操作和Mybatis的操作放在一个事务中
项目GitHub地址:GitHub地址
spring boot 2.0
==================================================================
注意点:
1.mybatis是有自动生成实体、Mapper映射类[实际是接口]、Mapper.xml映射文件的插件,插件名字叫【mybatis generator】,这里没有使用。
2.使用mybatis的话,是有两种实现方式的。
1》注解的方式
2》映射文件的方式
其实,注解的方式类似于JPA 的使用注解@Query()的方式。
整个使用下来,还是建议简单的CRUD操作,使用spring-data-JPA进行操作可以节省大量的代码量。
复杂的查询操作,就可以采用mybatis来完成,通过自己写sql语句提高灵活性,当然使用JPA来操作也可以完成。
3.第二点中的注解和映射文件两种方式 可以一起使用。
==================================================================
下面,分【注解方式】和【映射文件方式】两个大模块进行展示,并
1.pom.xml文件
除了spring boot项目的默认配置之外,再加上mysql的jar和mybatis的jar即可【这里先把mybatis的分页插件pagehelper的jar包加上,留在最后说】【使用这个分页jar包,会导致分页无效,至少在spring boot2.0是无效的】
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper mybatis分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.4</version>
</dependency>
pagehelper分页插件分页查询无效解决方法
修改之后采用的分页jar包【有效的分页】
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter mybatis分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
2.application.properties配置
server.port=9666 #datasource
spring.datasource.continue-on-error=false
spring.datasource.url=jdbc:mysql://localhost:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver #mybatis相关配置
#mybatis映射文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
#mybatis指定entity位置
mybatis.type-aliases-package=com.sxd.swapping.domain
#mybatis展示sql语句执行
logging.level.com.sxd.swapping.dao.mybatis=debug
==========================注解方式======================
3.实体类
package com.sxd.swapping.base; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort; import javax.persistence.*;
import java.util.*;
import java.util.stream.Collectors; /**
* 基础bean
*/
@MappedSuperclass
public class BaseBean { @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;// 主键 自增 @Column(nullable = false, updatable = false)
private Date createDate;// 创建时间 private Date updateDate;// 修改时间 private String updateId; // 修改人 @Column(nullable = false)
private String createId; // 创建人 @Column(nullable = false)
private String uid; //业务主键 @Transient
private Integer pageNum = 0; //分页 页号 @Transient
private Integer pageSize = 10; //分页 页量 public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public Date getCreateDate() {
return createDate;
} public void setCreateDate(Date createDate) {
this.createDate = createDate;
} public Date getUpdateDate() {
return updateDate;
} public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
} public String getUpdateId() {
return updateId;
} public void setUpdateId(String updateId) {
this.updateId = updateId;
} public String getCreateId() {
return createId;
} public void setCreateId(String createId) {
this.createId = createId;
} public String getUid() {
return uid;
} public void setUid(String uid) {
this.uid = uid;
} public Integer getPageNum() {
return pageNum;
} public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
} public Integer getPageSize() {
return pageSize;
} public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
} public void initEntity(){
this.createDate = new Date();
this.createId = UUID.randomUUID().toString();//如果有当前登陆人,则初始化为当前登陆人
this.uid = UUID.randomUUID().toString();
} public void updateEntity(){
this.updateDate = new Date();
this.updateId = UUID.randomUUID().toString();//如果有当前登陆人,则赋值为当前登陆人
} /**
* 分页 工具方法
* @return
*/
public PageRequest page(){
return PageRequest.of(pageNum,this.pageSize);
} /**
* 分页 排序工具方法
*
* 中文字段排序 需要在查询出来后处理 sort无法解决中文排序的问题
* @param map
* @param obj
* @return
* @throws Exception
*/
public PageRequest page(Map<String,Sort.Direction> map,Object obj) throws Exception{
//反射获取实体所有属性
List<String> properties = Arrays.stream(obj.getClass().getDeclaredFields()).map(i->i.getName()).collect(Collectors.toList());
Set<String> keySet = map.keySet();
Sort sort = null;
if (properties.containsAll(keySet)){
for (String str:keySet){
if (sort == null){
sort = Sort.by(map.get(str),str);
}else{
sort = sort.and(Sort.by(map.get(str),str));
}
}
}else{
throw new Exception("排序字段非本实体字段");
}
return PageRequest.of(this.pageNum,this.pageSize,sort);
}
}
package com.sxd.swapping.domain; import com.sxd.swapping.base.BaseBean;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.Serializable;
import java.util.*; @Entity
@Table
@Getter
@Setter
public class HuaYangArea extends BaseBean implements Serializable {
private static final long serialVersionUID = -1851783771574739215L; @Column(nullable = false)
private String areaName; @Column(nullable = false)
private Long areaPerson; public static Specification<HuaYangArea> where(HuaYangArea huaYangArea){ return new Specification<HuaYangArea>() {
@Override
public Predicate toPredicate(Root<HuaYangArea> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//创建查询列表
List<Predicate> predicates = new ArrayList<>(); //字段areaName是否查询
String areaName = huaYangArea.getAreaName();
if (StringUtils.isNotBlank(areaName)){
predicates.add(criteriaBuilder.like(root.get("areaName"),"%"+areaName+"%"));
}
//字段areaPerson是否查询
Long areaPerson = huaYangArea.getAreaPerson();
if (areaPerson != null) {
predicates.add(criteriaBuilder.equal(root.get("areaPerson"),areaPerson));
} return criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
};
} }
4.自己写的mapper映射类[实际是接口],等同于dao层【注意@Mapper注解没有加在这个类上,是因为采用了在启动类上加@MapperScan(“Mapper类所在包路径”)的方式】
启动类代码:
package com.sxd.swapping; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling
@SpringBootApplication
@MapperScan("com.sxd.swapping.dao.mybatis")
public class SwappingApplication { public static void main(String[] args) {
SpringApplication.run(SwappingApplication.class, args);
}
}
【重点是看Mapper层的sql语句怎么写】
package com.sxd.swapping.dao.mybatis; import com.sxd.swapping.domain.HuaYangArea;
import org.apache.ibatis.annotations.*; import java.util.Date;
import java.util.List; public interface HuaYangAreaMapper { /**
* 根据业务主键查询
* @param uid
* @return
*/
@Select("SELECT * FROM hua_yang_area where uid = #{uid}")
@Results({
@Result(property = "areaName",column = "area_name",javaType = String.class),
@Result(property = "areaPerson",column = "area_person",javaType = Long.class),
@Result(property = "createId",column = "create_id",javaType = String.class)
})
HuaYangArea findOne(String uid); /**
* 根据数据库主键 查询
* @param id
* @return
*/
@Select("SELECT * FROM hua_yang_area WHERE id = #{id}")
@Results({
@Result(property = "areaName",column = "area_name",javaType = String.class),
@Result(property = "areaPerson",column = "area_person",javaType = Long.class),
@Result(property = "createId",column = "create_id",javaType = String.class),
@Result(property = "createDate",column = "create_date",javaType = Date.class),
@Result(property = "updateDate",column = "update_date",javaType = Date.class)
})
HuaYangArea selectById(Long id); /**
* 模糊查询 方法1
* @param areaName 不传入值 则查到所有
* @return
*/
@Select("SELECT * FROM hua_yang_area WHERE area_name like '%${areaName}%'")
@Results({
@Result(property = "areaName",column = "area_name",javaType = String.class),
@Result(property = "areaPerson",column = "area_person",javaType = Long.class),
@Result(property = "createId",column = "create_id",javaType = String.class),
@Result(property = "createDate",column = "create_date",javaType = Date.class),
@Result(property = "updateDate",column = "update_date",javaType = Date.class)
})
List<HuaYangArea> selectByNameLike(@Param("areaName") String areaName); /**
* 模糊查询 方法2
* @param areaName 不传入值则 一条也查不到
* @return
*/
@Select("SELECT * FROM hua_yang_area WHERE area_name like CONCAT(CONCAT('%',#{areaName}),'%')")
@Results({
@Result(property = "areaName",column = "area_name",javaType = String.class),
@Result(property = "areaPerson",column = "area_person",javaType = Long.class),
@Result(property = "createId",column = "create_id",javaType = String.class),
@Result(property = "createDate",column = "create_date",javaType = Date.class),
@Result(property = "updateDate",column = "update_date",javaType = Date.class)
})
List<HuaYangArea> selectByNameLike2(String areaName); /**
* 插入 新增
* @param huaYangArea
* @return
*/
@Insert("INSERT INTO hua_yang_area(create_date,create_id,uid,area_name,area_person) VALUES (#{createDate},#{createId},#{uid},#{areaName},#{areaPerson}) ")
void insert(HuaYangArea huaYangArea); /**
* 更新 根据数据库主键更新
* @param huaYangArea
*/
@Update("UPDATE hua_yang_area SET update_date=#{updateDate},update_id=#{updateId},area_name=#{areaName},area_person=#{areaPerson} WHERE id=#{id}")
void update(HuaYangArea huaYangArea); /**
* 删除 根据数据库主键删除
* @param id
*/
@Delete("DELETE FROM hua_yang_area WHERE id=#{id}")
void delete(Long id); }
5.serviceImpl层【service层需要加@service()注解】
package com.sxd.swapping.service.impl; import com.sxd.swapping.dao.jpa.HuaYangAreaDao;
import com.sxd.swapping.dao.mybatis.HuaYangAreaMapper;
import com.sxd.swapping.domain.HuaYangArea;
import com.sxd.swapping.service.HuaYangService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import java.util.List;
import java.util.Map; @Service
public class HuaYangServiceImpl implements HuaYangService { @Autowired
HuaYangAreaMapper huaYangAreaMapper; @Override
public HuaYangArea getByUidWithMyBatis(String uid) {
return huaYangAreaMapper.findOne(uid);
} @Override
public HuaYangArea insertWithMybatis(HuaYangArea huaYangArea) {
huaYangAreaMapper.insert(huaYangArea);
return huaYangAreaMapper.findOne(huaYangArea.getUid());
} @Override
public HuaYangArea updateWithMyBatis(HuaYangArea huaYangArea) {
huaYangAreaMapper.update(huaYangArea);
return huaYangAreaMapper.selectById(huaYangArea.getId());
} @Override
public void deleteWithMyBatis(Long id) {
huaYangAreaMapper.delete(id);
} @Override
public HuaYangArea seleteWithMyBatis(Long id) {
return huaYangAreaMapper.selectById(id);
} @Override
public List<HuaYangArea> selectLikeNameWithMyBatis(String areaName) {
return huaYangAreaMapper.selectByNameLike(areaName);
} @Override
public List<HuaYangArea> selectLikeNameWithMyBatis2(String areaName) {
return huaYangAreaMapper.selectByNameLike2(areaName);
} }
6.统一响应体
package com.sxd.swapping.base; import com.sxd.swapping.util.MyException;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.List; @Getter
@Setter
public class UniVerResponse<T> implements Serializable { private static final long serialVersionUID = 137671534756697880L; /**
* 正确
*/
public static final int SUCCESS_REQUEST = 200;
/**
* 参数错误返回码
*/
public static final int ERROR_PARAMS = 100001; /**
* 业务错误返回码
*/
public static final int ERROR_BUSINESS = 200001;
/**
* 系统异常返回码
*/
public static final int ERROR_SYS_EXCPTION = 500001; private boolean success; private String msg; private int code; private T obj; public void beTrue(T obj){
this.success = true;
this.msg = "successful";
this.code = SUCCESS_REQUEST;
this.obj = obj;
} public void beFalse(String msg,int code,T obj){
this.success = false;
this.msg = msg;
this.code = code;
this.obj = obj;
} /**
* 对象多字段判空检查
* 例如simplCheckField(user,"userId","userName")
* @param obj 被检查的对象
* @param propertys 被检查对象中的字段 可多个
* @throws MyException
*/
public static void checkField(Object obj,String...propertys) throws MyException{ if(obj != null && propertys != null && propertys.length > 0){
//字节码
Class<? extends Object> clazz = obj.getClass(); //遍历所有属性
for (int i = 0; i < propertys.length; i++) {
String property = propertys[i];
//内省机制获取属性信息
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz,property );
if(pd != null){
//获取当前字段的javabean读方法
Method readMethod = pd.getReadMethod();
if(readMethod != null){ Object invoke = null; try {
invoke = readMethod.invoke(obj);
} catch (Exception e) {
throw new MyException("方法 "+ readMethod.getName() +"无法执行",UniVerResponse.ERROR_SYS_EXCPTION);
} if(invoke != null){
//String类型单独处理
Class<?> propertyType = pd.getPropertyType();
if("java.lang.String".equals(propertyType.getName())){ if(StringUtils.isBlank((String)invoke)){
throw new MyException("错误 : [ " + property + " ] 不能为空!",UniVerResponse.ERROR_PARAMS);
} }else if("java.util.List".equals(propertyType.getName())){
List list = (List)invoke;
if(list.size() == 0){
throw new MyException("错误 : [ " + property + " ] 不能为空!",UniVerResponse.ERROR_PARAMS);
}
}
}else{
throw new MyException("错误 : [ " + property + " ] 不能为空!",UniVerResponse.ERROR_PARAMS);
} }else{
//抛出异常
throw new MyException("在 " + clazz +"中 找不到"+"[ " + property + " ] 的 读方法",UniVerResponse.ERROR_SYS_EXCPTION);
} }else{
//抛出异常
throw new MyException("在 " + clazz +"中 找不到"+"[ " + property + " ] 属性",UniVerResponse.ERROR_SYS_EXCPTION);
}
}
}
} /**
* 单一字段判空检查
* 可检查对象的单个属性判空 例如simplCheckField(user,"userId")
* 也可做某个变量的单独判空 例如simplCheckField(userId,"userId")
* @param obj 被检查的对象
* @param property 被检查的对象的字段
* @throws MyException
*/
public static void simplCheckField(Object obj,String property) throws MyException{ if(obj instanceof String){
if(StringUtils.isBlank((String)obj)){
throw new MyException("错误 : [ " + property + " ] 不能为空!",UniVerResponse.ERROR_PARAMS);
}
}else if(obj instanceof List){
List list = (List)obj;
if(list.size() == 0){
throw new MyException("错误 : [ " + property + " ] 不能为空!",UniVerResponse.ERROR_PARAMS);
}
}else{
if(obj == null){
throw new MyException("错误 : [ " + property + " ] 不能为空!",UniVerResponse.ERROR_PARAMS);
}
}
} }
7.controller层调用即可
package com.sxd.swapping.controller; import com.sxd.swapping.base.UniVerResponse;
import com.sxd.swapping.domain.HuaYangArea;
import com.sxd.swapping.service.HuaYangService;
import com.sxd.swapping.util.MyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import java.util.List; @RestController
@RequestMapping("/huayangMybatis")
public class HuaYangApiWithMyBatis { @Autowired
HuaYangService huaYangService; @PostMapping("/insert")
public UniVerResponse<HuaYangArea> insert(@RequestBody HuaYangArea huaYangArea){
UniVerResponse.checkField(huaYangArea,"areaName","areaPerson");
huaYangArea.initEntity();
UniVerResponse<HuaYangArea> response = new UniVerResponse<>();
try {
huaYangArea = huaYangService.insertWithMybatis(huaYangArea);
response.beTrue(huaYangArea);
}catch (Exception e){
throw new MyException("插入失败",UniVerResponse.ERROR_BUSINESS);
} return response;
} @PutMapping("/update")
public UniVerResponse<HuaYangArea> update(@RequestBody HuaYangArea huaYangArea){
UniVerResponse.checkField(huaYangArea,"id","areaName","areaPerson");
huaYangArea.updateEntity();
UniVerResponse<HuaYangArea> response = new UniVerResponse<>();
try {
huaYangArea = huaYangService.updateWithMyBatis(huaYangArea);
response.beTrue(huaYangArea);
}catch (Exception e){
throw new MyException("更新失败",UniVerResponse.ERROR_BUSINESS);
} return response;
} /**
* 不传入值的查询所有
* @param areaName
* @return
*/
@GetMapping("/findByNameLike")
public UniVerResponse<List<HuaYangArea>> findAll1(String areaName){ UniVerResponse<List<HuaYangArea>> response = new UniVerResponse<>();
try {
response.beTrue(huaYangService.selectLikeNameWithMyBatis(areaName));
}catch (Exception e){
e.printStackTrace();
throw new MyException("查询失败",UniVerResponse.ERROR_BUSINESS);
} return response;
} /**
* 不传入值 查不到结果
* @param areaName
* @return
*/
@GetMapping("/findByNameLike2")
public UniVerResponse<List<HuaYangArea>> findAll2(String areaName){ UniVerResponse<List<HuaYangArea>> response = new UniVerResponse<>();
try {
response.beTrue(huaYangService.selectLikeNameWithMyBatis2(areaName));
}catch (Exception e){
e.printStackTrace();
throw new MyException("查询失败",UniVerResponse.ERROR_BUSINESS);
} return response;
} /**
* 根据 业务主键获取
* @param uid
* @return
*/
@GetMapping(value = "/oneHuaYang")
public UniVerResponse<HuaYangArea> findOne(String uid){
UniVerResponse.simplCheckField(uid,"uid"); UniVerResponse<HuaYangArea> response = new UniVerResponse<>();
HuaYangArea huaYangArea = huaYangService.getByUidWithMyBatis(uid);
response.beTrue(huaYangArea); return response;
} /**
* 根据主键删除
* @param id
* @return
*/
@DeleteMapping(value = "/oneHuaYang")
public UniVerResponse<String> deleteOne(Long id ){
UniVerResponse.simplCheckField(id,"id"); UniVerResponse<String> response = new UniVerResponse<>();
huaYangService.deleteWithMyBatis(id);
response.beTrue("删除成功");
return response;
} }
========================================================================================================
整体看下来单独采用Mapper映射类[实际是接口]中使用注解的方式,跟使用JPA很相似,但是没有JPA写起来代码量少
========================================================================================================
==========================映射文件方式======================
8.按照配置文件中的配置,在resources下创建mapper文件夹,并创建HuaYangAreaMapper.java同名的HuaYangAreaMapper.xml映射文件
注意,
<mapper namespace="com.sxd.swapping.dao.mybatis.HuaYangAreaMapper">
标签中 标明本mapper映射文件对应的是哪个Mapper类
<select
id="findByNameAndPersonAndCreateDate"
parameterType="com.sxd.swapping.domain.HuaYangArea"
resultType="com.sxd.swapping.base.HuaYangModelBean"> 每个sql语句是一个单独的标签,
查询有<select>
插入有<insert>
更新有<update>
删除有<delete> 标签基本属性
每一个id对应mapper类中的 一个方法名 parameterType属性标明sql接收的入参是什么类型 resultType属性标明sql操作结果的出参是什么类型 这里分别对应了两个实体类型
select
hy.uid uid,
hy.create_date createDate,
hy.update_date updateDate,
hy.area_name areaName,
hy.area_person areaPerson
from
hua_yang_area AS hy <where>
1=1
<if test="areaName != null">
AND hy.area_name LIKE '%' #{areaName} '%'
</if> <if test="areaPerson != null">
AND hy.area_person >= #{areaPerson}
</if> <if test="createDate != null">
AND <![CDATA[hy.create_date >= #{createDate}]]>
</if> </where> 查询语句
select
数据表字段1 出参实体属性1,
数据表字段2 出参实体属性2
from
数据表名
where
if 入参实体属性1 !=null
数据表字段1 = 入参实体属性1 注意 时间类型的比较 转义字符的 处理
完整代码如下:
<?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.sxd.swapping.dao.mybatis.HuaYangAreaMapper"> <select
id="findByNameAndPersonAndCreateDate"
parameterType="com.sxd.swapping.domain.HuaYangArea"
resultType="com.sxd.swapping.base.HuaYangModelBean"> select
hy.uid uid,
hy.create_date createDate,
hy.update_date updateDate,
hy.area_name areaName,
hy.area_person areaPerson
from
hua_yang_area AS hy <where>
1=1
<if test="areaName != null">
AND hy.area_name LIKE '%' #{areaName} '%'
</if> <if test="areaPerson != null">
AND hy.area_person >= #{areaPerson}
</if> <if test="createDate != null">
AND <![CDATA[hy.create_date >= #{createDate}]]>
</if> </where> </select> </mapper>
9.入参的实体类已经在最上面提供了,出参的Model
package com.sxd.swapping.base; import lombok.Getter;
import lombok.Setter; import java.util.Date; /**
* mybatis 查询返回Model封装
*/
@Getter
@Setter
public class HuaYangModelBean { private String uid; private Date createDate; private Date updateDate; private String areaName; private Long areaPerson; }
10.Mapper映射类[实际是接口]中 就这个方法
11. 分别在service 和controller层调用即可【想看代码 可以看下面分页模块 顺便把这一部分的service层代码 和controller层代码贴出来了】
【这里有一个前台String类型传递给后台Date类型的错误:http://www.cnblogs.com/sxdcgaq8080/p/9055107.html】
==============================================================================================================
映射文件这种方式,就可以很肆意的写SQL了,但是这里考虑到一个问题就是不同数据库的sql语法可能有所不同,所以对于不同数据库的查询,这种方式可移植性就很劣势了。
===============================================================================================================
===========================pagehelper分页插件=====================
最后看一下mybatis分页插件的使用
12.如最上面所说的,分页jar包采用spring boot集成的这个,分页才有效
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter mybatis分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
13.在application.properties增加pagehelper相关的配置
#pagehelper mybatis分页插件
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
pagehelper.returnPageInfo=check
14.映射文件mapper.xml不变更,mapper映射类[实际是接口]依旧是上面的那个方法
15.service层新增一个返回PageInfo<实体>方法
import com.github.pagehelper.PageInfo; List<HuaYangModelBean> findByNameAndPersonAndCreateDateWithMyBatisFile(HuaYangArea huaYangArea); PageInfo<HuaYangModelBean> findByNameAndPersonAndCreateDateWithMyBatisFileAndpagehelper(HuaYangArea huaYangArea);
service的实现
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; @Override
public List<HuaYangModelBean> findByNameAndPersonAndCreateDateWithMyBatisFile(HuaYangArea huaYangArea) {
return huaYangAreaMapper.findByNameAndPersonAndCreateDate(huaYangArea);
} @Override
public PageInfo<HuaYangModelBean> findByNameAndPersonAndCreateDateWithMyBatisFileAndpagehelper(HuaYangArea huaYangArea) {
PageHelper.startPage(huaYangArea.getPageNum(),huaYangArea.getPageSize());
List<HuaYangModelBean> list = huaYangAreaMapper.findByNameAndPersonAndCreateDate(huaYangArea);
PageInfo<HuaYangModelBean> pageInfo = new PageInfo<>(list);
return pageInfo;
}
16.设置分页统一响应体
package com.sxd.swapping.base; import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter; import java.util.ArrayList;
import java.util.List; /**
* 分页 统一响应体
* @param <T>
*/ @Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class PageResponse<T> { private boolean success; private String msg; private int code; private int pageNum; private int pageSize; private long total; private List<T> rows = new ArrayList<T>(); public void beTrue(long total,List<T> rows){
this.success = true;
this.msg = "successful";
this.code = UniVerResponse.SUCCESS_REQUEST;
this.total = total;
this.rows = rows;
} public void beTrue(int pageNum,int pageSize,long total,List<T> rows){
this.success = true;
this.msg = "successful";
this.code = UniVerResponse.SUCCESS_REQUEST;
this.pageNum = pageNum;
this.pageSize = pageSize;
this.total = total;
this.rows = rows;
} public void beFalse(String msg,int code){
this.success = false;
this.msg = msg;
this.code = code;
this.total = 0;
this.rows = null;
}
}
17.controller层调用
/**
* 根据 三个字段 查询
* 使用mybatis映射文件
* @param huaYangArea
* @return
*/
@GetMapping(value = "/findBy3")
public UniVerResponse<List<HuaYangModelBean>> findByNameAndPersonAndCreateDate(HuaYangArea huaYangArea){
UniVerResponse.checkField(huaYangArea,"areaName","areaPerson","createDate");
UniVerResponse<List<HuaYangModelBean>> response = new UniVerResponse<>(); try {
List<HuaYangModelBean> list = huaYangService.findByNameAndPersonAndCreateDateWithMyBatisFile(huaYangArea);
response.beTrue(list);
}catch (Exception e){
throw new MyException("查询错误",UniVerResponse.ERROR_BUSINESS,e);
} return response;
} /**
* 根据三个字段 映射文件 查询
*
* 分页查询
* @param huaYangArea
* @return
*/
@GetMapping(value = "/findBy3Page")
public PageResponse<HuaYangModelBean> findByNameAndPersonAndCreateDatePage(HuaYangArea huaYangArea){
UniVerResponse.checkField(huaYangArea,"areaName","areaPerson","createDate","pageNum","pageSize");
PageResponse<HuaYangModelBean> response = new PageResponse<>(); try {
PageInfo<HuaYangModelBean> pageInfo = huaYangService.findByNameAndPersonAndCreateDateWithMyBatisFileAndpagehelper(huaYangArea);
response.beTrue(pageInfo.getPageNum(),pageInfo.getPageSize(),pageInfo.getTotal(),pageInfo.getList());
}catch (Exception e){
throw new MyException("查询错误",UniVerResponse.ERROR_BUSINESS,e);
} return response;
}
18.测试查询,分页 的pageNum = 0 和pageNum = 1都是返回第一页的数据
满足条件的 总共13条数据,
查询pageNum = 0 pageSize = 10
查询 参数如下:
查询语句打印日志如下:
2018-05-18 14:05:19.469 DEBUG 8188 --- [nio-9666-exec-8] H.findByNameAndPersonAndCreateDate_COUNT : ==> Preparing: select count(0) from (select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ?) tmp_count
2018-05-18 14:05:19.470 DEBUG 8188 --- [nio-9666-exec-8] H.findByNameAndPersonAndCreateDate_COUNT : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp)
2018-05-18 14:05:19.471 DEBUG 8188 --- [nio-9666-exec-8] H.findByNameAndPersonAndCreateDate_COUNT : <== Total: 1
2018-05-18 14:05:19.472 DEBUG 8188 --- [nio-9666-exec-8] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Preparing: select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ? LIMIT ?
2018-05-18 14:05:19.473 DEBUG 8188 --- [nio-9666-exec-8] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp), 10(Integer)
2018-05-18 14:05:19.476 DEBUG 8188 --- [nio-9666-exec-8] s.d.m.H.findByNameAndPersonAndCreateDate : <== Total: 10
查询结果如下:
=============================================================================================================
查询pageNum = 1 pageSize = 10
查询 参数如下:
查询语句日志打印如下:
2018-05-18 14:03:38.142 DEBUG 8188 --- [nio-9666-exec-3] H.findByNameAndPersonAndCreateDate_COUNT : ==> Preparing: select count(0) from (select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ?) tmp_count
2018-05-18 14:03:38.143 DEBUG 8188 --- [nio-9666-exec-3] H.findByNameAndPersonAndCreateDate_COUNT : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp)
2018-05-18 14:03:38.145 DEBUG 8188 --- [nio-9666-exec-3] H.findByNameAndPersonAndCreateDate_COUNT : <== Total: 1
2018-05-18 14:03:38.146 DEBUG 8188 --- [nio-9666-exec-3] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Preparing: select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ? LIMIT ?
2018-05-18 14:03:38.147 DEBUG 8188 --- [nio-9666-exec-3] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp), 10(Integer)
2018-05-18 14:03:38.151 DEBUG 8188 --- [nio-9666-exec-3] s.d.m.H.findByNameAndPersonAndCreateDate : <== Total: 10
结果都是下面这样:
显示pageNum 都是 为1
=============================================================================================================
查询pageNum = 2 pageSize = 10
查询参数如下:
查询语句日志打印如下:
2018-05-18 14:02:31.734 DEBUG 8188 --- [nio-9666-exec-1] H.findByNameAndPersonAndCreateDate_COUNT : ==> Preparing: select count(0) from (select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ?) tmp_count
2018-05-18 14:02:31.753 DEBUG 8188 --- [nio-9666-exec-1] H.findByNameAndPersonAndCreateDate_COUNT : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp)
2018-05-18 14:02:31.766 DEBUG 8188 --- [nio-9666-exec-1] H.findByNameAndPersonAndCreateDate_COUNT : <== Total: 1
2018-05-18 14:02:31.772 DEBUG 8188 --- [nio-9666-exec-1] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Preparing: select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ? LIMIT ?, ?
2018-05-18 14:02:31.772 DEBUG 8188 --- [nio-9666-exec-1] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp), 10(Integer), 10(Integer)
2018-05-18 14:02:31.774 DEBUG 8188 --- [nio-9666-exec-1] s.d.m.H.findByNameAndPersonAndCreateDate : <== Total: 3
查询结果如下:
=============================================================================================================
查询pageNum = 3 pageSize = 10
查询参数如下:
查询语句打印日志如下:
2018-05-18 14:11:52.633 DEBUG 8188 --- [nio-9666-exec-8] H.findByNameAndPersonAndCreateDate_COUNT : ==> Preparing: select count(0) from (select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ?) tmp_count
2018-05-18 14:11:52.634 DEBUG 8188 --- [nio-9666-exec-8] H.findByNameAndPersonAndCreateDate_COUNT : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp)
2018-05-18 14:11:52.636 DEBUG 8188 --- [nio-9666-exec-8] H.findByNameAndPersonAndCreateDate_COUNT : <== Total: 1
2018-05-18 14:11:52.638 DEBUG 8188 --- [nio-9666-exec-8] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Preparing: select hy.uid uid, hy.create_date createDate, hy.update_date updateDate, hy.area_name areaName, hy.area_person areaPerson from hua_yang_area AS hy WHERE 1=1 AND hy.area_name LIKE '%' ? '%' AND hy.area_person >= ? AND hy.create_date >= ? LIMIT ?, ?
2018-05-18 14:11:52.639 DEBUG 8188 --- [nio-9666-exec-8] s.d.m.H.findByNameAndPersonAndCreateDate : ==> Parameters: 华阳(String), 7000(Long), 2018-05-16 00:00:00.0(Timestamp), 10(Integer), 10(Integer)
2018-05-18 14:11:52.641 DEBUG 8188 --- [nio-9666-exec-8] s.d.m.H.findByNameAndPersonAndCreateDate : <== Total: 3
查询结果如下:
==================================================================================
好了 spring boot 2.0+mybatis 暂时告一段落。
【spring boot】14.spring boot集成mybatis,注解方式OR映射文件方式AND pagehelper分页插件【Mybatis】pagehelper分页插件分页查询无效解决方法的更多相关文章
- springboot整合mybatis(映射文件方式和注解方式)
springboot作为一个微服务框架,给我们开发人员提供极大的便利,秉着约定大于配置的原则,通过starter包的形式为我们做了许多默认的配置,在进行数据持久化到关系型数据库时,我们一般都会首选sp ...
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- 深入浅出Mybatis系列七-mapper映射文件配置之insert、update、delete
注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 上篇文章<深入浅出Mybatis系列(六)---objectFactory.p ...
- Spring + Spring MVC + Hibernate项目开发集成(注解)
在自己从事的项目中都是使用xml配置的方式来进行的,随着项目的越来越大,会发现配置文件会相当的庞大,这个不利于项目的进行和后期的维护.于是考虑使用注解的方式来进行项目的开发,前些日子就抽空学习了一下. ...
- spring 事务无效解决方法
(原) spring 事务目前有二种,注解式和声明式,以前都是以公司里的框架写好的,没有学习的机会,今天抽空好好试了下,结果遇到好多问题. 1.注解式 最开始是这么玩的,发现数据进数据库了,没有起作用 ...
- mybatis 使用注解简化xml映射文件
目录 关于mybatis注解 初次简单使用mybatis注解示例 利用注解实现指定映射 使用注解实现表间关联(1对1) 关于mybatis注解 注解在java中特别常见,mybatis中也支持注解. ...
- MyBatis从入门到精通:使用XML方式(映射文件之类的)
2.3节笔记部分: package tk.mybatis.simple; public class Temp { } /* 2.2 使用XML方式 MyBatis使用了Java的动态代理可以直接通过接 ...
- MyBatis - 3.Mapper XML映射文件
SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序): cache – 给定命名空间的缓存配置. cache-ref – 其他命名空间缓存配置的引用. resultMap – 是最复杂也是 ...
- mybatis 映射器(mappers) 配置说明 加载映射文件方式
映射器(mappers) 既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了.但是首先我们需要告诉 MyBatis 到哪里去找到这些语句. Java 在自动查找这 ...
随机推荐
- SOA与WCF
背景: 高校平台马上就要进入编程阶段了,对于没怎么做过正式项目的我们来说,要学的东西实在太多了.一下子面对这么多学习资料时,我们也不能着急,还是踏踏实实,一个一个地去了解,其实他们都没那么神秘.这篇博 ...
- file mmap
do_set_pmd 统计参数只会在这里设置: add_mm_counter(vma->vm_mm, MM_FILEPAGES, HPAGE_PMD_NR); 但是这貌似都是处理大页的情况哪,小 ...
- 【bzoj2238】Mst 最小生成树+树链剖分+线段树
题目描述 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影响,即被删掉的边在下一条询问中依然存在) 输入 第一行两 ...
- 【bzoj4001】[TJOI2015]概率论 生成函数+导数
题目描述 输入 输入一个正整数N,代表有根树的结点数 输出 输出这棵树期望的叶子节点数.要求误差小于1e-9 样例输入 1 样例输出 1.000000000 题解 生成函数+导数 先考虑节点个数为$n ...
- Multiplication Game(博弈论)
Description Alice and Bob are in their class doing drills on multiplication and division. They quick ...
- “echo >”和“echo >>”的区别
> 输出重定向 >> 输出追加重定向 ------------------------------------------------------------------------ ...
- 4.创建OpenStack的node环境脚本
创建OpenStack的node环境脚本 使用source admin-openrc.sh来运行脚本 在任意目录下创建admin-openrc.sh文件 vim ~/admin-openrc.sh e ...
- Hashmap与Hashtable的区别及Hashmap的原理
Hashtable和HashMap有几个主要的不同:线程安全以及速度.仅在你需要完全的线程安全的时候使用Hashtable,而如果你使用Java 5或以上的话,请使用ConcurrentHashMap ...
- 【linux高级程序设计】(第十章)Linux异步信号处理机制 3
信号屏蔽 信号忽略:系统仍然传递该信号,只是相应的进程不做任何处理 信号屏蔽:进程不捕获信号,信号处于未决状态,当不再屏蔽信号时可以捕获之前被屏蔽的信号. 信号集数据结构定义: typedef __s ...
- Netty源码学习(五)ChannelInitializer
0. ChannelInitializer简介 直接用ChannelInitializer的注释吧:A special ChannelInboundHandler which offers an ea ...