1、简介
MyBatis-Plus(简称 简称 MP), 是一个 MyBatis 的增强 工具包,只做增强不做改变. 为简化开发工作、提高生产率而生。
愿景是成为 Mybatis 最好的搭档,就像 魂斗罗 中的 1P 、2P ,基友搭配,效率翻倍。
官方地址:http://mp.baomidou.com/
代码发布地址:https://github.com/baomidou/mybatis-plus、https://gitee.com/baomidou/mybatis-plus
文档发布地址:http://mp.baomidou.com/#/?id=%E7%AE%80%E4%BB%8B
2、快速入门
2.1 创建数据表
-- 创建库
CREATE DATABASE mp;
-- 使用库
USE mp;
-- 创建表
CREATE TABLE tbl_employee(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
last_name VARCHAR(50),
email VARCHAR(50),
gender CHAR(1),
age INT
);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','tom@qq.com',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','jerry@qq.com.com',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','black@qq.com.com',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','white@qq.com.com',0,35);
CREATE TABLE tbl_user(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
logic_flag INT(11)
)
Maven项目结构如下:
2.2 核心依赖
<!--
MybatisPlus 核心依赖
MybatisPlus 会自动的维护Mybatis 以及MyBatis-spring相关的依赖
-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.3</version>
</dependency>
<!--MySQL驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<!--数据库连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
特别说明: Mybatis 及 Mybatis-Spring 依赖请勿加入项目配置,以免引起版本冲突!!!
2.3 定义实体类
@TableName(value="tbl_employee")
public class Employee {
@TableId(value="id" , type =IdType.AUTO)
private Integer id ;
private String lastName;
private String email ;
private Integer gender;
private Integer age ;
// set\get\toString...
}
2.4 定义Mapper
import pers.klb.mybatisplus.mp01.beans.Employee;
import com.baomidou.mybatisplus.mapper.BaseMapper;
public interface EmployeeMapper extends BaseMapper<Employee> {
}
2.5 配置文件
2.5.1 数据库配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mp
jdbc.username=root
jdbc.password=root
2.5.2 Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 数据源 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 事务管理器 -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 基于注解的事务管理 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
<!-- 配置SqlSessionFactoryBean
Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
-->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 别名处理 -->
<property name="typeAliasesPackage" value="pers.klb.mybatisplus.mp01.beans"></property>
</bean>
<!-- 配置mybatis 扫描mapper接口的路径-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="pers.klb.mybatisplus.mp01.mapper"></property>
</bean>
</beans>
2.5.3 mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
2.6 测试方法
package pers.klb.mybatisplus.test;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pers.klb.mybatisplus.mp01.beans.Employee;
import pers.klb.mybatisplus.mp01.mapper.EmployeeMapper;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
public class Mp01Test {
private ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
private EmployeeMapper employeeMapper = ioc.getBean("employeeMapper", EmployeeMapper.class);
@Test
public void testDataSource() throws Exception {
DataSource ds = ioc.getBean("dataSource", DataSource.class);
System.out.println(ds);
Connection conn = ds.getConnection();
System.out.println("数据源:"+ds);
System.out.println("Connection:" + conn);
}
@Test
public void testCommonInsert() {
//初始化Employee对象
Employee employee = new Employee();
employee.setLastName("KLB");
employee.setEmail("klb@qq.com");
Integer result = employeeMapper.insertAllColumn(employee);
System.out.println("result: " + result);
//获取当前数据在数据库中的主键值
Integer key = employee.getId();
System.out.println("key:" + key);
}
}
3、集成MyBatis-Plus
3.1 集成方法
集成方法很简单,对于 Spring,我们仅仅需要把 Mybatis 自带的MybatisSqlSessionFactoryBean 替换为 MP 自带的即可:
<!-- 配置SqlSessionFactoryBean
Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
-->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!--property标签-->
</bean>
3.2 常用注解
3.2.1 @TableName
1. 源码定义
package com.baomidou.mybatisplus.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableName {
String value() default "";
String resultMap() default "";
}
2. 作用
作用在实体类上,用于映射数据表名。
3. 常用属性
value:实体类对应的表名;
resultMap:实体映射结果集。
4. 补充说明
这个注解只能作用于一个实体类上,若要实体类很多,则可以进行全局配置,在配置文件中增加MybatisPlus的全局策略配置:
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 全局的表前缀策略配置 -->
<property name="tablePrefix" value="tbl_"></property>
</bean>
配置好全局策略,记得在sqlSessionFactoryBean中注册,否则不生效:
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 别名处理 -->
<property name="typeAliasesPackage" value="pers.klb.mybatisplus.mp01.beans"></property>
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
</bean>
3.2.2 @TableField
1. 源码定义
ackage com.baomidou.mybatisplus.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.baomidou.mybatisplus.enums.FieldFill;
import com.baomidou.mybatisplus.enums.FieldStrategy;
import com.baomidou.mybatisplus.mapper.SqlCondition;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableField {
String value() default "";
String el() default "";
boolean exist() default true;
String condition() default SqlCondition.EQUAL;
String update() default "";
FieldStrategy strategy() default FieldStrategy.NOT_NULL;
FieldFill fill() default FieldFill.DEFAULT;
}
2. 作用
设置表字段的标识。
3. 常用属性
value:字段值(驼峰命名方式,该值可无);
exist:是否为数据库表字段,默认 true 存在,false 不存在;
3.2.3 @TableId
1. 源码定义
package com.baomidou.mybatisplus.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.baomidou.mybatisplus.enums.IdType;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableId {
String value() default "";
IdType type() default IdType.NONE;
}
2. 作用
表主键标识。
3. 常用属性
value:指定表中的主键列的列名, 如果实体属性名与列名一致,可以省略不指定.;
type:指定主键策略。
4、通用CRUD
4.1 介绍
问题:假设我们已存在一张 tbl_employee 表,且已有对应的实体类 Employee,实现tbl_employee 表的 CRUD 操作我们需要做什么呢?
解决方案:
Mybatis:需要编写 EmployeeMapper 接口,并手动编写 CRUD 方法,提供 EmployeeMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句;
Mybatis-Plus:只需要创建 EmployeeMapper 接口, 并继承 BaseMapper 接口即可使用,甚至不需要创建 SQL 映射文件。
4.1 Create:插入操作
// 插入一条记录
Integer insert(T entity);
Integer insertAllColumn(T entity);
4.2 Retrieve:查询操作
// 根据 ID 查询
T selectById(Serializable id);
// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
// 根据 entity 条件,查询一条记录
T selectOne(@Param("ew") T entity);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param("ew") Wrapper<T> wrapper);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param("ew") Wrapper<T> wrapper);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> wrapper);
// 根据 Wrapper 条件,查询全部记录
// 注意: 只返回第一个字段的值
List<Object> selectObjs(@Param("ew") Wrapper<T> wrapper);
// 根据 entity 条件,查询全部记录(并翻页)
List<T> selectPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
List<Map<String, Object>> selectMapsPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);
4.3 Update:修改操作
// 根据 ID 修改
Integer updateById(@Param("et") T entity);
Integer updateAllColumnById(@Param("et") T entity);
// 根据 whereEntity 条件,更新记录
Integer update(@Param("et") T entity, @Param("ew") Wrapper<T> wrapper);
// 根据 whereEntity 条件,更新记录
Integer updateForSet(@Param("setStr") String setStr, @Param("ew") Wrapper<T> wrapper);
4.4 Delete:删除操作
// 根据 ID 删除
Integer deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
Integer deleteByMap(@Param("cm") Map<String, Object> columnMap);
// 根据 entity 条件,删除记录
Integer delete(@Param("ew") Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
Integer deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
5、条件构造器
5.1 EntityWrapper
1、Mybatis-Plus 通过 EntityWrapper(简称 EW,MP 封装的一个查询条件构造器)或者 Condition(与 EW 类似) 来让用户自由的构建查询条件,简单便捷,没有额外的负担,能够有效提高开发效率
2、实体包装器,主要用于处理 sql 拼接,排序,实体参数查询等
3、注意: 使用的是数据库字段,不是Java属性。
4、条件参数说明:
5.2 使用Wrapper
在通用CRUD方法当中,有一些方法的参数是Wrapper
类型,也就是条件构造器。
首先定义Wrapper
:
// 分页查询tbl_employee表中,年龄在18~50之间且性别为男且姓名为KLB的所有用户
EntityWrapper<Employee> wrapper = new EntityWrapper<>();
wrapper.between("age", 40, 70).eq("gender", 1).eq("last_name", "KLB");
使用:
List<Employee> emps =employeeMapper.selectPage(new Page<Employee>(1, 2),wrapper);
5.3 使用Condition
同样的定义加使用:
Wrapper condition = Condition.create();
condition.eq("gender", 1).eq("last_name", "MyBatisPlus").between("age", 18, 50);
List<Employee> userListCondition = employeeMapper.selectPage(new Page<Employee>(2,3),condition);
5.4 小结
Mybatis-Plus: EntityWrapper Condition 条件构造器。
MyBatis MBG : xxxExample→Criteria : QBC( Query By Criteria)。
6、活动记录
Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索。
6.1 使用方式
实体类继承com.baomidou.mybatisplus.activerecord.Model
,且实现主键指定方法,即可开启 AR 之旅。
package pers.klb.mybatisplus.mp02.beans;
import java.io.Serializable;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableField;
public class Employee extends Model<Employee> {
private Integer id ;
private String lastName;
private String email ;
private Integer gender;
private Integer age ;
/**
* 指定当前实体类的主键属性
*/
@Override
protected Serializable pkVal() {
return id;
}
// set\get\toString...
}
6.2 测试
@Test
public void testARInsert() {
Employee employee = new Employee();
employee.setLastName("小孔");
employee.setEmail("klb@qq.com");
employee.setGender(1);
employee.setAge(20);
boolean result = employee.insert();
System.out.println("result:" +result );
}
6.3 小结
AR 模式提供了一种更加便捷的方式实现 CRUD 操作,其本质还是调用的 Mybatis 对应的方法,类似于语法糖。
语法糖是指计算机语言中添加的某种语法,这种语法对原本语言的功能并没有影响.可以更方便开发者使用,可以避免出错的机会,让程序可读性更好。
7、代码生成器
7.1 介绍
MP 提供了大量的自定义设置,生成的代码完全能够满足各类型的需求。
MP 的代码生成器 和 Mybatis MBG 代码生成器的区别:
1、MP 的代码生成器都是基于 java 代码来生成。MBG 基于 xml 文件进行代码生成;
2、MyBatis 的代码生成器可生成: 实体类、Mapper 接口、Mapper 映射文件;
3、MP 的代码生成器可生成: 实体类(可以选择是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 层、Controller 层.
在 MP 中,我们建议数据库表名 和 表字段名采用驼峰命名方式, 如果采用下划线命名方式 请开启全局下划线开关,如果表名字段名命名方式不一致请注解指定,我们建议最好保持一致。
这么做的原因是为了避免在对应实体类时产生的性能损耗,这样字段不用做映射就能直接和实体类对应。当然如果项目里不用考虑这点性能损耗,那么你采用下滑线也是没问题的,只需要在生成代码时配置dbColumnUnderline 属性就可以。
7.2 核心依赖
MP 的代码生成器默认使用的是 Apache 的 Velocity 模板,当然也可以更换为别的模板技术,例如 freemarker。此处不做过多的介绍。
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
7.3 示例代码
@Test
public void testGenerator() {
//1. 全局配置
GlobalConfig config = new GlobalConfig();
config.setActiveRecord(true) // 是否支持AR模式
.setAuthor("konglibin") // 作者
.setOutputDir("E:\\IdeaProjects\\MybatisPlusDemo\\mp03\\src\\main\\java") // 生成路径
.setFileOverride(true) // 文件覆盖
.setIdType(IdType.AUTO) // 主键策略
.setServiceName("%sService") // 设置生成的service接口的名字的首字母是否为I
.setBaseResultMap(true)
.setBaseColumnList(true);
//2. 数据源配置
DataSourceConfig dsConfig = new DataSourceConfig();
dsConfig.setDbType(DbType.MYSQL) // 设置数据库类型
.setDriverName("com.mysql.jdbc.Driver")
.setUrl("jdbc:mysql://localhost:3306/mp")
.setUsername("root")
.setPassword("root");
//3. 策略配置
StrategyConfig stConfig = new StrategyConfig();
stConfig.setCapitalMode(true) //全局大写命名
.setDbColumnUnderline(true) // 指定表名 字段名是否使用下划线
.setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
.setTablePrefix("tbl_")
.setInclude("tbl_employee"); // 生成的表
//4. 包名策略配置
PackageConfig pkConfig = new PackageConfig();
pkConfig.setParent("pers.klb.mybatisplus.mp03")
.setMapper("mapper")
.setService("service")
.setController("controller")
.setEntity("beans")
.setXml("mapper");
//5. 整合配置
AutoGenerator ag = new AutoGenerator();
ag.setGlobalConfig(config)
.setDataSource(dsConfig)
.setStrategy(stConfig)
.setPackageInfo(pkConfig);
//6. 执行
ag.execute();
}
运行后,代码生成效果如下:
EmployeeServiceImpl
继承了 ServiceImpl
类,mybatis-plus 通过这种方式为我们注入了 EmployeeMapper
,这样可以使用 service 层默认为我们提供的很多方法,也可以调用我们自己在 dao 层编写的操作数据库的方法。
8、插件拓展
8.1 插件机制
Mybatis 通过插件(Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求,完成相关数据的动态改变。
Executor
StatementHandler
ParameterHandler
ResultSetHandler
8.2 插件原理
四大对象的每个对象在创建时,都会执行 interceptorChain.pluginAll()
,会经过每个插件的 plugin()
方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理.
8.3 常用插件
8.3.1 分页插件
com.baomidou.mybatisplus.plugins.PaginationInterceptor
8.3.2 执行分析插件
com.baomidou.mybatisplus.plugins.SqlExplainInterceptor
1、SQL 执行分析拦截器,只支持 MySQL5.6.3 以上版本;
2、该插件的作用是分析 DELETE UPDATE 语句,防止小白或者恶意进行 DELETE UPDATE 全表操作;
3、只建议在开发环境中使用,不建议在生产环境使用;
4、在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句,根据结果集中的 Extra 列来断定当前是否全表操作。
8.3.3 性能分析插件
com.baomidou.mybatisplus.plugins.PerformanceInterceptor
1、性能分析拦截器,用于输出每条 SQL 语句及其执行时间;
2、SQL 性能执行分析,开发环境使用 , 超过指定时间,停止运行。有助于发现问题。
8.3.4 乐观锁插件
com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor
1、常用于这样的需求: 当要更新一条记录的时候,希望这条记录没有被别人更新;
2、乐观锁的实现原理:取出记录时,获取当前 version,更新时,带上这个 version,执行更新时, set version = yourVersion+1 where version = yourVersion,如果 version 不对,就更新失败
3、@Version
用于注解实体字段,必须要有。
8.4 插件的使用
在Spring整合Mybatis配置文件中:
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 插件注册 -->
<property name="plugins">
<list>
<!-- 注册分页插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
<!-- 注册执行分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<property name="stopProceed" value="true"></property>
</bean>
<!-- 注册性能分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<property name="format" value="true"></property>
<!-- <property name="maxTime" value="5"></property> -->
</bean>
<!-- 注册乐观锁插件 -->
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor">
</bean>
</list>
</property>
</bean>
9、自定义全局操作
9.1 AutoSqlInjector
根据 MybatisPlus 的 AutoSqlInjector
可以自定义各种你想要的 sql ,注入到全局中,相当于自定义 Mybatisplus 自动注入的方法。
也就是说,如果MP自带的SQL语句不够你使用,可以通过这个AutoSqlInjector
来添加需要的SQL语句。
使用过程:
1、自定义Mapper,里面添加自己需要的方法:
package pers.klb.mybatisplus.mp05.mapper;
import pers.klb.mybatisplus.mp05.beans.Employee;
import com.baomidou.mybatisplus.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*/
public interface EmployeeMapper extends BaseMapper<Employee> {
int deleteAll();
}
2、定义AutoSqlInjector
的实现类:
package pers.klb.mybatisplus.mp05.injector;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.Configuration;
import com.baomidou.mybatisplus.entity.TableInfo;
import com.baomidou.mybatisplus.mapper.AutoSqlInjector;
/**
* 自定义全局操作
*/
public class MySqlInjector extends AutoSqlInjector {
/**
* 扩展inject 方法,完成自定义全局操作
*/
@Override
public void inject(
Configuration configuration,
MapperBuilderAssistant builderAssistant,
Class<?> mapperClass,
Class<?> modelClass,
TableInfo table) {
//将EmployeeMapper中定义的deleteAll, 处理成对应的MappedStatement对象,加入到configuration对象中。
//注入的SQL语句
String sql = "delete from " + table.getTableName();
//注入的方法名 一定要与EmployeeMapper接口中的方法名一致
String method = "deleteAll";
//构造SqlSource对象
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
//构造一个删除的MappedStatement
this.addDeleteMappedStatement(mapperClass, method, sqlSource);
}
}
3、在配置文件中注册自定义的AutoSqlInjector
:
<!-- 定义自定义注入器 -->
<bean id="mySqlInjector" class="pers.klb.mybatisplus.mp05.injector.MySqlInjector"></bean>
<!-- 定义MybatisPlus的全局策略配置-->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--注入自定义全局操作 -->
<property name="sqlInjector" ref="mySqlInjector"></property></property>
</bean>
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 别名处理 -->
<property name="typeAliasesPackage" value="pers.klb.mybatisplus.mp05.beans"></property>
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
</bean>
9.2 逻辑删除
配置步骤:
1、实体类中的删除标志属性加上@TableLogic
注解:
public class User{
private Integer id ;
private String name ;
@TableLogic // 逻辑删除属性
private Integer logicFlag ;
}
2、配置文件:
<!-- 创建逻辑删除bean -->
<bean id="logicSqlInjector" class="com.baomidou.mybatisplus.mapper.LogicSqlInjector"></bean>
<!-- 定义MybatisPlus的全局策略配置-->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 注入逻辑删除-->
<property name="sqlInjector" ref="logicSqlInjector"></property>
<!-- 注入逻辑删除全局值-->
<property name="logicDeleteValue" value="-1"></property>
<property name="logicNotDeleteValue" value="1"></property>
</bean>
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
</bean>
配置成功后,删除操作就不是真正的删除,底层变成update操作,即把logicFlag
设置为-1,当查询时,就会带上where logicFlag=1
的条件,logicFlag
为-1的数据不会显示,达到逻辑删除的目的。
9.3 公共字段自动填充
9.3.1 元对象
metaobject
: 元对象. 是 Mybatis 提供的一个用于更加方便,更加优雅的访问对象的属性,给对象的属性设置值 的一个对象. 还会用于包装对象. 支持对 Object 、Map、Collection等对象进行包装
本质上 metaObject
获取对象的属性值或者是给对象的属性设置值,最终是要通过 Reflector 获取到属性的对应方法的 Invoker, 最终 invoke.
9.3.2 字段自动填充
在执行insert、update等操作时,有些字段没有赋值,我们想让它自动填充,可以配置MetaObjectHandler
来实现。
首先在实体类需要填充的字段加上@TableField
注解,并设置属性:
public class User extends Parent {
private Integer id ;
@TableField(fill=FieldFill.INSERT_UPDATE)
private String name ;
private Integer logicFlag ;
// 。。。
}
FieldFill
是一个枚举类型:
public enum FieldFill {
DEFAULT(0, "默认不处理"),
INSERT(1, "插入填充字段"),
UPDATE(2, "更新填充字段"),
INSERT_UPDATE(3, "插入和更新填充字段");
// ...
}
定义一个公共字段填充处理器:
package pers.klb.mybatisplus.mp05.metaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import com.baomidou.mybatisplus.mapper.MetaObjectHandler;
/**
* 自定义公共字段填充处理器
*/
public class MyMetaObjectHandler extends MetaObjectHandler {
/**
* 插入操作 自动填充
*/
@Override
public void insertFill(MetaObject metaObject) {
//获取到需要被填充的字段的值
Object fieldValue = getFieldValByName("name", metaObject);
if(fieldValue == null) {
System.out.println("*******插入操作 满足填充条件*********");
setFieldValByName("name", "klb", metaObject);
}
}
/**
* 修改操作 自动填充
*/
@Override
public void updateFill(MetaObject metaObject) {
Object fieldValue = getFieldValByName("name", metaObject);
if(fieldValue == null) {
System.out.println("*******修改操作 满足填充条件*********");
setFieldValByName("name", "klb", metaObject);
}
}
}
配置文件:
<!-- 公共字段填充 处理器 -->
<bean id="myMetaObjectHandler" class="pers.klb.mybatisplus.mp05.metaObjectHandler.MyMetaObjectHandler"></bean>
<!-- 定义MybatisPlus的全局策略配置-->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 注入公共字段填充处理器-->
<property name="metaObjectHandler" ref="myMetaObjectHandler"></property></property>
</bean>
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 别名处理 -->
<property name="typeAliasesPackage" value="pers.klb.mybatisplus.mp05.beans"></property>
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
</bean>