文章目录
概述
通用Mapper: https://gitee.com/free/Mapper/wikis/Home
分页插件 pagehelper: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
整合官方指导:https://github.com/abel533/MyBatis-Spring-Boot
不过版本较低,我们这里升级下Spring Boot等框架的版本,同时整合下阿里巴巴的Druid连接池 。
项目结构如下
整合 MyBatis
参考上篇博文 Spring Boot2.x-07Spring Boot2.1.2整合Mybatis
整合 通用Mapper2.1.4及 PageHelper1.2.10
添加依赖
既然是spring boot项目,肯定是添加xxx-starter了. 非Spring Boot项目可以添加单独的jar包。
<!--通用Mapper插件 文档地址:https://gitee.com/free/Mapper/wikis/Home 同pagehelper
同一个作者刘增辉大神开源 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!-- 分页插件 pagehelper 文档地址:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
通用mapper 编写
package com.artisan.common;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
*
* @author yangshangwei
*
* @param <T> 通用mapper 创建CommonMapper接口继承Mapper
*
*
* 通用 Mapper 是一个可以实现任意 MyBatis 通用方法的框架,项目提供了常规的增删改查操作以及 Example 相关的单表操作。
* 通用 Mapper 是为了解决 MyBatis 使用中 90% 的基本操作.
* PageHelper则提供通用的分页查询功能,使用它们可以很方便的进行开发,可以节省开发人员大量的时间
*
* 通用Mapper的GIT地址: https://gitee.com/free/Mapper
分页插件的GIT地址: https://github.com/pagehelper/Mybatis-PageHelper
*
*/
public interface CommonMapper<T> extends Mapper<T>, MySqlMapper<T> {
}
application.yml增加配置
#mappers 多个接口时逗号隔开
mapper:
mappers: com.artisan.common.CommonMapper # 通用dao ,是个类,不是包名
not-empty: false # 设置以后,会去判断 insert 和 update 中字符串类型!=''
identity: MYSQL
#pagehelper
pagehelper:
# 配置使用哪种数据库语言,不配置的话pageHelper也会自动检测,这里使用的mysql。
helper-dialect: mysql
# 分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询
reasonable: true
# 支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页
supportMethodsArguments: true
# 为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值,默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。
params: count=countSql
集成验证测试
注意看注释,就不一一说明了。
package com.artisan.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import com.artisan.common.CommonMapper;
import com.artisan.model.Artisan;
/**
*
* @author yangshangwei
*
* 增加@Mapper这个注解之后,Spring 启动时会自动扫描该接口,这样就可以在需要使用时直接注入 Mapper 了
*
* 使用通用mapper,在Mapper接口层继承刚才的CommonMapper接口,这样单表的增删改查就实现了,无须xml
*
* 当然了,可以使用内置通用mapper
*
* 也可以使用xml 或者注解
*/
@Mapper
public interface ArtisanMapper extends CommonMapper<Artisan>{
//自己来编写xml,不适用内置的方法
List<Artisan> selectAllArtisansByXml();
//自己来注解,不适用内置的方法
@Select("select id,name,sex from artisan")
List<Artisan> selectAllArtisansByAnno();
}
接口中的两个方法是为了演示使用xml或者注解添加的方法,其实接口继承CommonMapper<Artisan>
就可以通过CommonMapper内置的方法实现对单表的CRUD了。
接下来我们来验证下继承CommonMapper内置的方法实现对单表的CRUD
service层
package com.artisan.service;
import java.util.List;
import com.artisan.model.Artisan;
public interface ArtisanService {
List<Artisan> getAllArtisanList();
List<Artisan> getArtisanListByPage(int pageNum , int pageSize);
}
实现类
package com.artisan.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.artisan.mapper.ArtisanMapper;
import com.artisan.model.Artisan;
import com.artisan.service.ArtisanService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class ArtisanServiceImpl implements ArtisanService {
@Autowired
private ArtisanMapper artisanMapper;
/**
* 调用 通用mapper提供的方法
*/
@Override
public List<Artisan> getAllArtisanList() {
return artisanMapper.selectAll();
}
@Override
public List<Artisan> getArtisanListByPage(int pageNum, int pageSize) {
// 分页插件的使用 第一个参数是当前页 第二个参数是每页显示的条数
// 引用分页插件以后,Mybatis分页会变得特别简单,
// 需要注意的是,在你需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,
// 紧跟在这个方法后的第一个MyBatis 查询方法会被进行分页
PageHelper.startPage(pageNum, pageSize).setOrderBy("id desc");
List<Artisan> artisanList = artisanMapper.selectAll();
// 需要注意的是查询语句必须紧跟这一句,且只能使用一次,意思就是如果还有一个分页查询需要再定义一次PageHelper.startPage(pageNum, pageSize)
// 用PageInfo对结果进行包装,返回
// PageInfo page = new PageInfo(artisanList);
// PageInfo<Artisan> pageInfo = new PageInfo<Artisan>(artisanList);
final PageInfo<Artisan> pageInfo = PageHelper.startPage(pageNum, pageSize).setOrderBy("id desc")
.doSelectPageInfo(() -> this.artisanMapper.selectAll());
log.info("[lambda写法] - [分页信息] - [{}]", pageInfo.toString());
PageHelper.startPage(pageNum, pageSize).setOrderBy("id desc");
final PageInfo<Artisan> artisanPageInfo = new PageInfo<>(this.artisanMapper.selectAll());
log.info("[普通写法] - [{}]", artisanPageInfo);
return artisanList;
}
}
控制层
package com.artisan.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.artisan.model.Artisan;
import com.artisan.result.CodeMsg;
import com.artisan.result.Result;
import com.artisan.service.ArtisanService;
@RestController
public class ArtisanController {
@Autowired
private ArtisanService artisanService;
// 正常情况
@GetMapping("/artisans")
public Result<List<Artisan>> selectAllArtisan() {
return Result.success(artisanService.getAllArtisanList());
}
// 模拟异常情况
@GetMapping("/artisansError")
public Result<List<Artisan>> selectAllArtisanError() {
return Result.error(CodeMsg.SERVER_ERROR);
}
// 分页 http://localhost:8089/artisansPage?pageNum=2&pageSize=3
@GetMapping("/artisansPage")
public Result<List<Artisan>> selectPageArtisan(int pageNum, int pageSize) {
return Result.success(artisanService.getArtisanListByPage(pageNum, pageSize));
}
}
启动spring boot ,访问 http://localhost:8089/artisans (port在配置文件中指定为8089)
http://localhost:8089/artisansPage?pageNum=2&pageSize=3
当然了,也可以继续使用xml或者注解来使用mybatis ,
mapper映射文件(xml方式时使用,注解就用不到了)
整合Druid (纯配置文件)
添加依赖
<!--阿里巴巴数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
application.yml增加配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver # JDBC连接Mysql6以上com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/artisan?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000 # 配置获取连接等待超时的时间
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
validation-query: SELECT 1 FROM DUAL
test-while-idle: true # 当连接空闲时,是否执行连接测试
test-on-borrow: false # 当从连接池借用连接时,是否测试该连接
test-on-return: false # 在连接归还到连接池时是否测试该连接
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 ,不能用log4j,不然报错:Failed to bind properties under 'spring.datasource.druid' to javax.sql.DataSource:
filters: stat,wall,slf4j
use-global-data-source-stat: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 配置监控服务器
stat-view-servlet:
login-username: artisan
login-password: artisan
reset-enable: false
url-pattern: /druid/*
# 添加IP白名单
#allow:
# 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
#deny:
web-stat-filter:
# 添加过滤规则
url-pattern: /*
# 忽略过滤格式
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
集成验证测试
项目启动的时候也可以看到初始化信息
监测页面:http://ip:port/druid/index.html
因为这里配置了用户名和密码,先访问 http://localhost:8089/druid/login.html
访问几次数据,然后就可以看到了
代码
见github: https://github.com/yangshangwei/springbootMybatisCommonMapperAndPageheper