Mybatis-Plugs为简化代码而生
mybatis增强工具包
[enbatis]
[Mybatis-Plugs]
[2022年8月]
[一阵清风]
目录
1.介绍1
1.1简介1
1.2目的1
1.3特性1
2.快速开始1
2.1创建表1
2.2创建springboot项目1
2.3配置maven3
2.4配置yml4
2.4修改启动类5
3.代码生成器5
3.1配置代码生成器5
3.2使用方法6
3.3建立代码包7
3.4复制代码8
3.5启动项目8
4.CRUD接口8
4.1插入接口9
4.1.1单条插入9
4.1.2批量插入9
4.2删除接口10
4.2.1单个删除10
4.2.2批量删除11
4.3修改接口11
4.3.1单个修改11
4.3.2批量修改12
4.4列表查询接口13
4.5分页查询14
4.6查询单条15
4.7查询数量15
5.条件构造器Wrapper16
5.1eq构造16
5.2ne构造16
5.3like构造16
5.4in构造17
6.登录认证17
6.1创建JWT17
6.2解析JWT20
6.3封装登录实体21
7.拦截器21
7.1介绍21
7.2拦截请求23
7.3放行请求23
8.枚举转换24
8.1定义枚举类24
8.2实体类引用枚举26
8.3增加配置文件26
Mybatis-Plugs
介绍
1.1简介
Mybatis-plugs是基于mybatis开发的一款增强的持久层框架。
只需在springboot项目中引入依赖mybatis-plugs-spring-boot-starter
即可实现mybatis的CRUD简化操作,不用在书写基本的增删改查sql。
1.2目的
Mybatis-plugs为简化代码而生。
1.3特性
不对mybatis做任何修改只做mybatis的扩展增强。
代码自动生成,根据表名可快速生成xxxMapper.java、xxxService.java、xxxServiceImpl.java、xxxController.java、xxxMapper.xml文件。
依赖少,仅仅依赖mybatis-plugs-spring-boot-starter
自动填充创建时间,更新时间,创建人等信息。
内置基于Mybatis物理分页的分页插件。
自动记录sql执行的时间,方便定位慢查询。
代码简洁,方便理解。
内置接口拦截器,通过注解确定是否拦截请求。
快速开始
我们将通过一个简单的Demo来阐述MyBatis-Plugs的强大功能,在此之前,我们假设您已经:
a.拥有Java开发环境、相应IDE以及mysql数据库
b.熟悉SpringBoot
c.熟悉Maven
如果从零开始用MyBatis-Plugs来实现该表的增删改查我们需要做什么呢?
2.1创建表
现有一张sys_user表,其对应的数据库Sql脚本如下:
CREATE TABLE sys_user (
id bigint NOT NULL COMMENT '主键ID',
name varchar(30) COMMENT '姓名',
age int COMMENT '年龄',
phone varchar(11) COMMENT '电话',
PRIMARY KEY (id)
)
2.2创建springboot项目
使用idea创建SpringBoot项目
第一步:
第二步:
第三步:选择LomBok插件
项目基本结构
2.3配置maven
springBoot项目建立好之后,在pom.xml文件加入mybatis-plugs的依赖
mybatis-plugs-spring-boot-starter
当前最新版本mybatis-plugs-spring-boot-starter
com.enbatis
mybatis-plugs-spring-boot-starter
当前最新版本
小提示:
引入mybatis-plugs-spring-boot-starter之后无需再次引入mybatis
2.4配置yml
修改application.properties为application.yml
新增开发环境:application-dev.yml
新增测试环境:application-test.yml
新增生产环境:application-pro.yml
小说明
1.开发环境为我们进行开发所使用的配置
2.测试环境为测试人员进行软件测试所使用的配置
3.生产环境为上线部署所使用的配置
application.yml
spring:
profiles:
active: dev
server:
port: 8080
tips:
spring:
profiles:
active: dev
指定所使用的环境
port:8080
指定项目所启动的端口为8080端口
application-dev.yml
2.4修改启动类
在启动类上加上Mapper扫描的注解
@MapperScan(“com.xxxxx.xxxxx.mapper”)
3.代码生成器
我们通过数据库表可以快速生成
entity,controller,mapper,service,serviceImpl,mapping.xml
生成代码需要连接数据库,所以我们需要进行数据库的连接,只需要通过配置数据库基本信息,利用mybatis-plugs的代码生成类CodeGenerator2即可
3.1配置代码生成器
在启动类的同级目录下,建立生成器类CodeGenerate
import com.enbatis.mybatisplugs.generate.CodeGenerator2;
public class CodeGenerate {
private static String url="jdbc:mysql://127.0.0.1:3306/test" />
输入完成之后点击回车
当输出以下信息表示代码生成成功
去代码生成的位置查看生成的代码
3.3建立代码包
建立代码包:entity、controller、mapper、service、impl以及xml的文件夹
3.4复制代码
将生成的代码复制到对应的文件夹
3.5启动项目
启动项目访问http://localhost:8080/v1/sys_user/list查询所有用户列表
4.CRUD接口
说明:通过封装mybatis的BaseService接口即可快速实现数据库的CRUD操作
泛型T为任意实体对象;参数Serializable为任意类型主键Mybatis-Plugs不推荐使用复合主键约定每一张表都有自己的唯一id主键;对象Wrapper为条件构造器。
4.1插入接口
4.1.1单条插入
/**
*插入一条记录
*@paramentity传入的插入对象
*@returnT
*/
Tinsert(Tentity);
使用方法:在serviceImpl层写代码示例如下
SysUser user = new SysUser();
user.setName("张三");
user.setAge(32);
user.setPhone("13615425135");
super.insert(user);
4.1.2批量插入
/**
*批量插入
*@paramentityList
*@return
*/
intsaveBatch(ListentityList);
使用方法:在serviceImpl层写代码示例如下
List sysUserList = new ArrayList();
for (int i = 0; i <10 ; i++) {
SysUser sysUser = new SysUser();
sysUser.setName("张三"+i);
sysUser.setAge(30+i);
sysUser.setPhone("1361542513"+i);
sysUserList.add(sysUser);
}
super.saveBatch(sysUserList);
4.2删除接口
4.2.1单个删除
/**
*根据id删除一条数据
*@paramid传入的查询ID
*@return删除条数
*/
intdeleteById(Serializableid);
使用方式:在serviceImpl层写代码示例如下
super.deleteById(12000012);
4.2.2批量删除
/**
*批量删除
*@paramwrapper
*@return
*/
intdelete(Wrapperwrapper);
使用方式:在serviceImpl层写代码示例如下
Wrapper wrapper = new Wrapper();
wrapper.eq("age",30);
wrapper.like("name","张三");
super.delete(wrapper);
说明:关于条件构造器会专门讲解。
4.3修改接口
4.3.1单个修改
/**
*根据id更新一条数据
*@parambean传入的更新对象
*@return返回更新条数
*/
intupdateById(Tbean);
使用方式:在serviceImpl层写代码示例如下
SysUser sysUser = new SysUser();
sysUser.setId(1234561114L);
sysUser.setPhone("13615425135");
sysUser.setAge(36);
super.updateById(sysUser);
4.3.2批量修改
/**
*批量修改
*@paramentityList
*@return
*/
intupdateBatchById(ListentityList);
使用方式:在serviceImpl层写代码示例如下
List sysUserList = new ArrayList();
SysUser sysUser = new SysUser();
sysUser.setId(111100001101L);
sysUser.setAge(35);
sysUserList.add(sysUser);
SysUser sysUser2 = new SysUser();
sysUser2.setId(111100001102L);
sysUser2.setAge(32);
sysUserList.add(sysUser);
super.updateBatchById(sysUserList);
4.4列表查询接口
/**
*查询列表数据
*@paramwrapper查询条件
*@return集合
*/
Listlist(Wrapperwrapper);
使用方式:在serviceImpl层写代码示例如下
Wrapper wrapper = new Wrapper();
wrapper.like("name","张三");
List list = super.list(wrapper);
4.5分页查询
/**
*分页查询
*@parampage
*@paramwrapper
*@return
*/
Pagepage(Pagepage,Wrapperwrapper);
使用方式:在controller层写代码示例如下
@PostMapping("/page")
public ResultReturn<Page> getPage(@RequestBody SysUser user){
return success(sysUserService.page( getPage(),new Wrapper(user)));
}
说明:controller需要继承BaseController
4.6查询单条
/**
*根据id获取
*@paramid对象ID
*@return对象
*/
TgetById(Serializableid);
使用方式:在controller层写代码示例如下
@GetMapping("/{id}")
public ResultReturn get(@PathVariable("id") Long id) {
return success(sysUserService.getById(id));
}
4.7查询数量
/**
*查询count
*@paramwrapper查询条件
*@return数量
*/
intselectCount(Wrapperwrapper);
使用方式:在serviceImpl层写代码示例如下
Wrapper wrapper = new Wrapper();
wrapper.like("name","张三");
int count = super.selectCount(wrapper);
5.条件构造器Wrapper
5.1eq构造
如果我们想快速查询数据库表sys_user的姓名为“Tom”如何进行操作呢?
回答:只需service调用list传入条件构造器WrapperWrapper调用eq方法,下面的方法即为查询姓名是Tom的SysUser列表
sysUserService.list(new Wrapper(sysUser).eq("name","Tom"));
5.2ne构造
如果我们想快速查询数据库表sys_user的姓名不是“Tom”如何进行操作呢?
回答:只需service调用list传入条件构造器WrapperWrapper调用ne方法,下面的方法即为查询姓名不是Tom的SysUser列表
sysUserService.list(new Wrapper(sysUser).ne("name","Tom"));
5.3like构造
如果我们想根据姓名模糊查询,怎么操作呢?
回答:只需service调用list传入条件构造器WrapperWrapper调用like方法,下面的方法即为根据姓名“Tom”模糊查询
sysUserService.list(new Wrapper(sysUser).like("name","Tom"));
5.4in构造
如果我们想查询姓名是“Tom”,“Jack”,“June”怎么操作呢?
回答:只需service调用list传入条件构造器WrapperWrapper调用in方法,传入ArrayList即可
List arrayList=new ArrayList();
arrayList.add("Tom");
arrayList.add("Jack");
arrayList.add("June");
sysUserService.list(new Wrapper(sysUser).in("name",arrayList));
扩展:
以上只列出部分条件构造器的方法,我们还有notNull(非空查询)、isNull(空值查询)、setSqlSelect(固定列查询)等等,更多请查看mybatis-plugs
6.登录认证
Mybatis-Plugs内部封装了JWTtoken认证,做登录功能时可直接进行使用。
6.1创建JWT
Mybatis-Plugs提供了JwtUtil工具类来进行token的创建,具体的方法来介绍下:
/**
* 前三个参数为自己用户token的一些信息比如id,权限,名称等。不要将隐私信息放入(大家都可以获取到)
* @param map 需要加密的信息
* @param security 加密字符串
* @param expire 失效时间 毫秒
* @return
*/
public static String createJwt(Map map,String security,long expire) {
//添加构成JWT的参数
JwtBuilder builder = Jwts.builder()
.setHeaderParam("typ", "JWT")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis()+expire))
.setClaims(map)
.signWith(generalKey(security),SignatureAlgorithm.HS256);
//生成JWT
return builder.compact();
}
如果不传失效时间会默认24小时,我们提供了一个重载的方法
/**
* 创建JWT 默认失效时间是24小时
* @param map 需要加密的信息
* @param base64Security 加密字符串
* @return
*/
public static String createJwt(Map map, String base64Security) {
return createJwt(map,base64Security,EXPIRE);
}
具体如何使用?请参照以下代码:
//获取登录用户名
String username =user.getUsername();
String password= MD5Util.generate(user.getPassword());
List list=list(new Wrapper().eq("username",username).eq("password",password));
Optional first= list.stream().filter(dbUser->dbUser.getUsername().equals(username)&&dbUser.getPassword().equals(password)).findFirst();
if (first.isPresent()){
user.setUsername(username);
SysUser sysUser= first.get();
Map userMap = new HashMap();
userMap.put("userId",sysUser.getId()+"");
userMap.put("name",sysUser.getName());
userMap.put("companyId",sysUser.getCompanyId());
userMap.put("username",sysUser.getUsername());
userMap.put("effective", System.currentTimeMillis()+(120*60*1000));
String token= JwtUtil.createJwt(userMap, JwtUtil.LOGIN_BASE);
response.addHeader("authorization",token);
Cookie cookie = new Cookie("authorization",token);
cookie.setDomain(domain);
cookie.setPath("/");
response.addCookie(cookie);
SysUser user1= first.get();
SysUserVO vo = new SysUserVO();
BeanUtils.copyProperties(user1,vo);
vo.setAuthorization(token);
vo.setImgHead(sysUser.getAvatarUrl());
return ResultReturn.success(vo);
}
6.2解析JWT
Mybatis-Plugs提供了JwtUtil工具类来进行token的解析,具体的方法来介绍下:
/**
* 解密
* @param jsonWebToken token字符串
* @param security 加密字符串
* @return
*/
public static Claims parseJwt(String jsonWebToken, String security) {
try {
Jws claimsJws = Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(security.getBytes(StandardCharsets.UTF_8)))
.build().parseClaimsJws(jsonWebToken);
return claimsJws.getBody();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
6.3封装登录实体
登录成功之后,可以用token获取到登录实体Account,用来获取登录用户,具体方法如下:
public static Account account(String token,String security){
Claims claims= JwtUtil.parseJwt(token,security);
String userId= (String)claims.get("userId");
String username= (String)claims.get("username");
Integer companyId= (Integer)claims.get("companyId");
Account account = new Account();
account.setId(Long.parseLong(userId));
account.setUsername(username);
if(null!=companyId){
account.setCompanyId(Long.parseLong(Integer.toString(companyId)));
}
return account;
}
其中token是jwt生成的token,security为加密字符串,token可以从head或者cookie里面获取。
具体的使用方式见如下代码:
Account account = JwtUtil.account(request.getHeader("Authorization"),"xxxx");
7.拦截器
7.1介绍
Mybatis-plugs的拦截器有记录请求方法执行时间、过滤非登录用户请求的功能,在controller里面使用注解即可拦截未登录请求。
使用方法:
自定义拦截器并继承类:
com.enbatis.mybatisplugs.commons.Interceptor.Interceptor
实例代码如下:
@Component
public class ReqInterceptor extends Interceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
return super.preHandle(request,response,handler);
}
}
接下来是注册拦截器,新建类WebConfigurer并实现WebMvcConfigurer接口,代码如下:
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
@Autowired
private ReqInterceptor interceptor;
/**
* @Description 这个方法是用来配置静态资源的,比如html,js,css,等等
* @Param [registry]
* @return void
**/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}
/**
* @Description 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
* @Date 9:34 2022/2/7
* @Param [registry]
* @return void
**/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// addPathPatterns("/**") 表示拦截所有的请求,
registry.addInterceptor(interceptor).addPathPatterns("/**");
}
}
配置完成即可实现Mybatis-Plugs拦截器的功能。
7.2拦截请求
Controller方法不加任何注解或者加注解@Login(handler=Handler.INTERCEPT)即可起到拦截请求的功能,如果用户未登录就访问接口,系统会抛出未登录的信息。
7.3放行请求
有一部分请求是不需要登录就直接能访问的,比如说注册接口,登录接口等等,这时候使用注解@Login(handler=Handler.PASS)即可放行请求,即不需要登录即可访问,代码示例如下:
注册接口:
@Login(handler = Handler.PASS)
@PostMapping("/register")
public ResultReturn registerUser(@RequestBody SysUserVO sysUser){
sysUser.setCompanyId(0L);
return sysUserService.registerUser(sysUser);
}
登录接口:
@Login(handler = Handler.PASS)
@PostMapping("/login")
public ResultReturn login(@RequestBody SysUserVO vo){
return sysUserService.login(vo,request,response);
}
8.枚举转换
有时候数据库里面存的是数字类型,但是在实体类里面我们要使用枚举类,这种情况Mybatils-Plugs提供了比较方便快捷的方式来实现需求。
8.1定义枚举类
先自定义枚举类并实现com.enbatis.mybatisplugs.enums.BaseEnum接口,代码如下:
import com.enbatis.mybatisplugs.enums.BaseEnum;
public enum StatusEnum implements BaseEnum {
ORDERED(0,"已下单"),
PAYED(1,"已付款"),
DELIVER(2,"代发货"),
DELIVERED(3,"已发货"),
RECEIVED(4,"已收货"),
OK(5,"订单完成");
private final Integer value;
private final String description;
StatusEnum(Integer value, String description) {
this.value = value;
this.description = description;
}
public StatusEnum getEnumByValue(Long value) {
StatusEnum[] enums = StatusEnum.values();
for (StatusEnum e : enums) {
if (e.getValue().equals(value)) {
return e;
}
}
return null;
}
@Override
public Integer getValue() {
return value;
}
@Override
public String getDescription() {
return description;
}
}
8.2实体类引用枚举
需要在实体类里面将字段更改为枚举类型,如下:
/**
* 订单状态(
*/
private StatusEnum status;
8.3增加配置文件
需要在配置文件里面添加对枚举转换的类:
com.enbatis.mybatisplugs.plugin.parser.AutoEnumTypeHandler
代码如下:
mybatis:
mapper-locations: classpath:/mapping/*.xml
type-aliases-package: com.panpan.housesale.entity
configuration:
map-underscore-to-camel-case: true
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
default-enum-type-handler: com.enbatis.mybatisplugs.plugin.parser.AutoEnumTypeHandler
通过这三个步骤的操作,就可以实现,数据库字段类型与枚举类型的匹配。