欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Mybatis-Plus

时间:2023-07-04
Mybatis-Plus

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
官网:https://mybatis.plus/

文档: https://mp.baomidou.com/ (点击上面指南中的快速入门)如果需要更多了解 可进入这个官网进行学习

文档中有的资源我会用 * 表示 ,不会在这里说明

1 通用CRUD *

继承baseMapper就可以获取到各种各样的单表操作

baseMapper接口文件

package com.baomidou.mybatisplus.core.mapper;import com.baomidou.mybatisplus.core.conditions.Wrapper;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;import com.baomidou.mybatisplus.core.toolkit.Constants;import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;import org.apache.ibatis.annotations.Param;import java.io.Serializable;import java.util.Collection;import java.util.List;import java.util.Map;public interface baseMapper extends Mapper { int insert(T entity); int deleteById(Serializable id); int deleteById(T entity); int deleteByMap(@Param(Constants.COLUMN_MAP) Map columnMap); int delete(@Param(Constants.WRAPPER) Wrapper queryWrapper); int deleteBatchIds(@Param(Constants.COLLECTION) Collection<?> idList); int updateById(@Param(Constants.ENTITY) T entity); int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper updateWrapper); T selectById(Serializable id); List selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); List selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap); default T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper) { List ts = this.selectList(queryWrapper); if (CollectionUtils.isNotEmpty(ts)) { if (ts.size() != 1) { throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records"); } return ts.get(0); } return null; } default boolean exists(Wrapper queryWrapper) { Long count = this.selectCount(queryWrapper); return null != count && count > 0; } Long selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper); List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); List> selectMaps(@Param(Constants.WRAPPER) Wrapper queryWrapper); List selectObjs(@Param(Constants.WRAPPER) Wrapper queryWrapper);

> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper queryWrapper);

>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper queryWrapper);}

2 mybatis-plus配置 *

这个文档里面包含了springboot的配置以及 xml配置

https://baomidou.com/pages/56bac0/#%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE

3 条件构造器 *

https://baomidou.com/pages/56bac0/#%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE

实例

QueryWrapper wrapper = new QueryWrapper<>();//SELECT id,name,age FROM tb_user WHERe name = ? OR age = ?wrapper.eq("name", "李四") .or() .eq("age", 24) .select("id", "name", "age");List users = this.userMapper.selectList(wrapper);for (User user : users) { System.out.println(user);}

4、插件 4.1、mybatis的插件机制

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法
调用包括:

Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)ParameterHandler (getParameterObject, setParameters)ResultSetHandler (handleResultSets, handleOutputParameters)StatementHandler (prepare, parameterize, batch, update, query)

我们看到了可以拦截Executor接口的部分方法,比如update,query,commit,rollback等方法,还有其他接口的
一些方法等。
总体概括为:

拦截执行器的方法拦截参数的处理拦截结果集的处理拦截Sql语法构建的处理

拦截器示例

package cn.itcast.mp.plugins;import org.apache.ibatis.executor.Executor;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.*;import java.util.Properties;@Intercepts({@Signature( type= Executor.class, method = "update", args = {MappedStatement.class,Object.class})})public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { //拦截方法,具体业务逻辑编写的位置 return invocation.proceed(); } @Override public Object plugin(Object target) { //创建target对象的代理对象,目的是将当前拦截器加入到该对象中 return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { //属性设置 }}

注入到spring容器

@Beanpublic MyInterceptor myInterceptor(){return new MyInterceptor();}

mybatis-config.xml配置

<?xml version="1.0" encoding="UTF-8" ?>

4.2 执行分析插件

在MP中提供了对SQL执行的分析的插件,可用作阻断全表更新、删除的操作,注意:该插件仅适用于开发环境,不适用于生产环境

SpringBoot配置:

@Beanpublic SqlExplainInterceptor sqlExplainInterceptor(){ SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();List sqlParserList = new ArrayList<>();// 攻击 SQL 阻断解析器、加入解析链 sqlParserList.add(new BlockAttackSqlParser());sqlExplainInterceptor.setSqlParserList(sqlParserList);return sqlExplainInterceptor;}

测试

@Testpublic void testUpdate(){ User user = new User(); user.setAge(20); int result = this.userMapper.update(user, null); System.out.println("result = " + result);}

4.3、性能分析插件

性能分析拦截器,用于输出每条 SQL 语句及其执行时间,可以设置最大执行时间,超过时间会抛出异常。
该插件只用于开发环境,不建议生产环境使用。

<?xml version="1.0" encoding="UTF-8" ?>

执行结果

Time:11 ms - ID:cn.itcast.mp.mapper.UserMapper.selectByIdExecute SQL: SELECT id, user_name, password, name, age, email FROM tb_user WHERe id=7

可以看到,执行时间为11ms。如果将maxTime设置为1,那么,该操作会抛出异常。

Caused by: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: The SQLexecution time is too large, please optimize !at com.baomidou.mybatisplus.core.toolkit.ExceptionUtils.mpe(ExceptionUtils.java:49)at com.baomidou.mybatisplus.core.toolkit.Assert.isTrue(Assert.java:38)................

4.4、乐观锁插件 *

地址

https://baomidou.com/pages/0d93c0/#optimisticlockerinnerinterceptor

5、Sql 注入器 *

我们已经知道,在MP中,通过AbstractSqlInjector将baseMapper中的方法注入到了Mybatis容器,这样这些方法才可以正常执行。
那么,如果我们需要扩充baseMapper中的方法,又该如何实现呢?
下面我们以扩展findAll方法为例进行学习。

5.1、编写MybaseMapper

package cn.itcast.mp.mapper;import com.baomidou.mybatisplus.core.mapper.baseMapper;import java.util.List;public interface MybaseMapper extends baseMapper {List findAll();}

其他的Mapper都可以继承该Mapper,这样实现了统一的扩展

package cn.itcast.mp.mapper;import cn.itcast.mp.pojo.User;public interface UserMapper extends MybaseMapper {User findById(Long id);}

5.2、编写MySqlInjector

如果直接继承AbstractSqlInjector的话,原有的baseMapper中的方法将失效,所以我们选择继承DefaultSqlInjector
进行扩展。

package cn.itcast.mp.sqlInjector;import com.baomidou.mybatisplus.core.injector.AbstractMethod;import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;import java.util.List;public class MySqlInjector extends DefaultSqlInjector { @Override public List getMethodList() { List methodList = super.getMethodList(); methodList.add(new FindAll()); // 再扩充自定义的方法 list.add(new FindAll()); return methodList; }}

5.3、编写FindAll

package cn.itcast.mp.sqlInjector;import com.baomidou.mybatisplus.core.enums.SqlMethod;import com.baomidou.mybatisplus.core.injector.AbstractMethod;import com.baomidou.mybatisplus.core.metadata.TableInfo;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.SqlSource;public class FindAll extends AbstractMethod { @Override public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) { String sqlMethod = "findAll"; String sql = "select * from " + tableInfo.getTableName(); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatement(mapperClass, sqlMethod, sqlSource, modelClass, tableInfo); }}

5.4、注册到Spring容器

@Beanpublic MySqlInjector mySqlInjector(){return new MySqlInjector();}

5.5、测试

@Testpublic void testFindAll(){ List users = this.userMapper.findAll(); for (User user : users) { System.out.println(user); }}

输入的SQL

[main] [cn.itcast.mp.mapper.UserMapper.findAll]-[DEBUG] ==> Preparing: select * fromtb_user[main] [cn.itcast.mp.mapper.UserMapper.findAll]-[DEBUG] ==> Parameters:[main] [cn.itcast.mp.mapper.UserMapper.findAll]-[DEBUG] <== Total: 10

6、自动填充功能 *

有些时候我们可能会有这样的需求,插入或者更新数据时,希望有些字段可以自动填充数据,比如密码、version
等。在MP中提供了这样的功能,可以实现自动填充。

6.1、添加@TableField注解

@TableField(fill = FieldFill.INSERT) //插入数据时进行填充private String password;

为password添加自动填充功能,在新增数据时有效。
FieldFill提供了多种模式选择:

public enum FieldFill { DEFAULT, INSERT, UPDATe, INSERT_UPDATE}

6.2、编写MymetaObjectHandler

package cn.itcast.mp.handler;import com.baomidou.mybatisplus.core.handlers.metaObjectHandler;import org.apache.ibatis.reflection.metaObject;import org.springframework.stereotype.Component;@Componentpublic class MymetaObjectHandler implements metaObjectHandler { @Override public void insertFill(metaObject metaObject) { Object password = getFieldValByName("password", metaObject); if(null == password){ //字段为空,可以进行填充 setFieldValByName("password", "123456", metaObject); } } @Override public void updateFill(metaObject metaObject) { }}

6.3、测试

@Testpublic void testInsert(){ User user = new User(); user.setName("关羽"); user.setUserName("guanyu"); user.setAge(30); user.setEmail("guanyu@itast.cn"); user.setVersion(1); int result = this.userMapper.insert(user); System.out.println("result = " + result);}

7、 逻辑删除 *

开发系统时,有时候在实现功能时,删除操作需要实现逻辑删除,所谓逻辑删除就是将数据标记为删除,而并非真正
的物理删除(非DELETE操作),查询时需要携带状态条件,确保被标记的数据不被查询到。这样做的目的就是避免
数据被真正的删除。

MP就提供了这样的功能,方便我们使用,接下来我们一起学习下。

7.1、修改表结构

为tb_user表增加deleted字段,用于表示数据是否被删除,1代表删除,0代表未删除。

ALTER TABLE `tb_user`ADD COLUMN `deleted` int(1) NULL DEFAULT 0 COMMENT '1代表删除,0代表未删除' AFTER`version`;

同时,也修改User实体,增加deleted属性并且添加@TableLogic注解:

@TableLogicprivate Integer deleted;

7.2、配置

application.properties:

逻辑已删除值(默认为 1)

mybatis-plus.global-config.db-config.logic-delete-value=1

逻辑未删除值(默认为 0)

mybatis-plus.global-config.db-config.logic-not-delete-value=0

7.3、测试

@Testpublic void testDeleteById(){this.userMapper.deleteById(2L);}

执行的SQL:

[main] [cn.itcast.mp.mapper.UserMapper.deleteById]-[DEBUG] ==> Preparing: UPDATEtb_user SET deleted=1 WHERe id=? AND deleted=0[main] [cn.itcast.mp.mapper.UserMapper.deleteById]-[DEBUG] ==> Parameters: 2(Long)[main] [cn.itcast.mp.mapper.UserMapper.deleteById]-[DEBUG] <== Updates: 1

测试查询

@Testpublic void testSelectById(){ User user = this.userMapper.selectById(2L); System.out.println(user);}

执行的sql

[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] ==> Preparing: SELECTid,user_name,password,name,age,email,version,deleted FROM tb_user WHERe id=? ANDdeleted=0[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] ==> Parameters: 2(Long)[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] <== Total: 0

8、 通用枚举 *

解决了繁琐的配置,让 mybatis 优雅的使用枚举属性!

8.1、修改表结构

ALTER TABLE `tb_user`ADD COLUMN `sex` int(1) NULL DEFAULT 1 COMMENT '1-男,2-女' AFTER `deleted`;

8.2、定义枚举

package cn.itcast.mp.enums;import com.baomidou.mybatisplus.core.enums.IEnum;import com.fasterxml.jackson.annotation.JsonValue;public enum SexEnum implements IEnum { MAN(1,"男"), WOMAN(2,"女"); private int value; private String desc; SexEnum(int value, String desc) { this.value = value; this.desc = desc; } @Override public Integer getValue() { return this.value; } @Override public String toString() { return this.desc; }}

8.3、配置

枚举包扫描

mybatis-plus.type-enums-package=cn.itcast.mp.enums

8.4、修改实体

private SexEnum sex;

8.5 测试

@Testpublic void testInsert(){ User user = new User(); user.setName("貂蝉"); user.setUserName("diaochan"); user.setAge(20); user.setEmail("diaochan@itast.cn"); user.setVersion(1); user.setSex(SexEnum.WOMAN); int result = this.userMapper.insert(user); System.out.println("result = " + result);}

sql

[main] [cn.itcast.mp.mapper.UserMapper.insert]-[DEBUG] ==> Preparing: INSERT INTOtb_user ( user_name, password, name, age, email, version, sex ) VALUES ( ?, ?, ?, ?, ?,?, ? )[main] [cn.itcast.mp.mapper.UserMapper.insert]-[DEBUG] ==> Parameters:diaochan(String), 123456(String), 貂蝉(String), 20(Integer), diaochan@itast.cn(String),1(Integer), 2(Integer)[main] [cn.itcast.mp.mapper.UserMapper.insert]-[DEBUG] <== Updates: 1

查询测试

@Testpublic void testSelectById(){ User user = this.userMapper.selectById(2L); System.out.println(user);}

sql

[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] ==> Preparing: SELECTid,user_name,password,name,age,email,version,deleted,sex FROM tb_user WHERe id=? AND deleted=0[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] ==> Parameters: 2(Long)[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] <== Total: 1User(id=2, userName=lisi, password=123456, name=李四, age=30, email=test2@itcast.cn,address=null, version=2, deleted=0, sex=女)

9 代码生成器 * 10.Mybatis整合MP

文档: https://mp.baomidou.com/ (点击上面指南中的快速入门)如果需要更多了解 可进入这个官网进行学习

带有 * 的表示 官网里有更详细的资料

[DEBUG] <== Updates: 1

查询测试```java@Testpublic void testSelectById(){ User user = this.userMapper.selectById(2L); System.out.println(user);}

sql

[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] ==> Preparing: SELECTid,user_name,password,name,age,email,version,deleted,sex FROM tb_user WHERe id=? AND deleted=0[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] ==> Parameters: 2(Long)[main] [cn.itcast.mp.mapper.UserMapper.selectById]-[DEBUG] <== Total: 1User(id=2, userName=lisi, password=123456, name=李四, age=30, email=test2@itcast.cn,address=null, version=2, deleted=0, sex=女)

9 代码生成器 * 10.Mybatis整合MP

文档: https://mp.baomidou.com/ (点击上面指南中的快速入门)如果需要更多了解 可进入这个官网进行学习

带有 * 的表示 官网里有更详细的资料

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。