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
-- 创建库
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','[email protected]',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','[email protected]',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','[email protected]',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','[email protected]',0,35);
CREATE TABLE tbl_user(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
logic_flag INT(11)
)
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plusartifactId>
<version>2.3version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.37version>
dependency>
<dependency>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
<version>0.9.5.2version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>4.3.10.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>4.3.10.RELEASEversion>
dependency>
特别说明: Mybatis 及 Mybatis-Spring 依赖请勿加入项目配置,以免引起版本冲突!!!
@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...
}
import pers.klb.mybatisplus.mp01.beans.Employee;
import com.baomidou.mybatisplus.mapper.BaseMapper;
public interface EmployeeMapper extends BaseMapper<Employee> {
}
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mp
jdbc.username=root
jdbc.password=root
<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"/>
<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>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="pers.klb.mybatisplus.mp01.mapper">property>
bean>
beans>
<configuration>
configuration>
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("[email protected]");
Integer result = employeeMapper.insertAllColumn(employee);
System.out.println("result: " + result);
//获取当前数据在数据库中的主键值
Integer key = employee.getId();
System.out.println("key:" + key);
}
}
集成方法很简单,对于 Spring,我们仅仅需要把 Mybatis 自带的MybatisSqlSessionFactoryBean 替换为 MP 自带的即可:
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
bean>
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 "";
}
作用在实体类上,用于映射数据表名。
value:实体类对应的表名;
resultMap:实体映射结果集。
这个注解只能作用于一个实体类上,若要实体类很多,则可以进行全局配置,在配置文件中增加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>
<property name="globalConfig" ref="globalConfiguration">property>
bean>
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;
}
设置表字段的标识。
value:字段值(驼峰命名方式,该值可无);
exist:是否为数据库表字段,默认 true 存在,false 不存在;
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;
}
表主键标识。
value:指定表中的主键列的列名, 如果实体属性名与列名一致,可以省略不指定.;
type:指定主键策略。
问题:假设我们已存在一张 tbl_employee 表,且已有对应的实体类 Employee,实现tbl_employee 表的 CRUD 操作我们需要做什么呢?
解决方案:
Mybatis:需要编写 EmployeeMapper 接口,并手动编写 CRUD 方法,提供 EmployeeMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句;
Mybatis-Plus:只需要创建 EmployeeMapper 接口, 并继承 BaseMapper 接口即可使用,甚至不需要创建 SQL 映射文件。
// 插入一条记录
Integer insert(T entity);
Integer insertAllColumn(T entity);
// 根据 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);
// 根据 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);
// 根据 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);
1、Mybatis-Plus 通过 EntityWrapper(简称 EW,MP 封装的一个查询条件构造器)或者 Condition(与 EW 类似) 来让用户自由的构建查询条件,简单便捷,没有额外的负担,能够有效提高开发效率
2、实体包装器,主要用于处理 sql 拼接,排序,实体参数查询等
3、注意: 使用的是数据库字段,不是Java属性。
4、条件参数说明:
在通用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);
同样的定义加使用:
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);
Mybatis-Plus: EntityWrapper Condition 条件构造器。
MyBatis MBG : xxxExample→Criteria : QBC( Query By Criteria)。
Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。
ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索。
实体类继承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...
}
@Test
public void testARInsert() {
Employee employee = new Employee();
employee.setLastName("小孔");
employee.setEmail("[email protected]");
employee.setGender(1);
employee.setAge(20);
boolean result = employee.insert();
System.out.println("result:" +result );
}
AR 模式提供了一种更加便捷的方式实现 CRUD 操作,其本质还是调用的 Mybatis 对应的方法,类似于语法糖。
语法糖是指计算机语言中添加的某种语法,这种语法对原本语言的功能并没有影响.可以更方便开发者使用,可以避免出错的机会,让程序可读性更好。
MP 提供了大量的自定义设置,生成的代码完全能够满足各类型的需求。
MP 的代码生成器 和 Mybatis MBG 代码生成器的区别:
1、MP 的代码生成器都是基于 java 代码来生成。MBG 基于 xml 文件进行代码生成;
2、MyBatis 的代码生成器可生成: 实体类、Mapper 接口、Mapper 映射文件;
3、MP 的代码生成器可生成: 实体类(可以选择是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 层、Controller 层.
在 MP 中,我们建议数据库表名 和 表字段名采用驼峰命名方式, 如果采用下划线命名方式 请开启全局下划线开关,如果表名字段名命名方式不一致请注解指定,我们建议最好保持一致。
这么做的原因是为了避免在对应实体类时产生的性能损耗,这样字段不用做映射就能直接和实体类对应。当然如果项目里不用考虑这点性能损耗,那么你采用下滑线也是没问题的,只需要在生成代码时配置dbColumnUnderline 属性就可以。
MP 的代码生成器默认使用的是 Apache 的 Velocity 模板,当然也可以更换为别的模板技术,例如 freemarker。此处不做过多的介绍。
<dependency>
<groupId>org.apache.velocitygroupId>
<artifactId>velocity-engine-coreartifactId>
<version>2.0version>
dependency>
@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 层编写的操作数据库的方法。
Mybatis 通过插件(Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求,完成相关数据的动态改变。
Executor
StatementHandler
ParameterHandler
ResultSetHandler
四大对象的每个对象在创建时,都会执行 interceptorChain.pluginAll()
,会经过每个插件的 plugin()
方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理.
com.baomidou.mybatisplus.plugins.PaginationInterceptor
com.baomidou.mybatisplus.plugins.SqlExplainInterceptor
1、SQL 执行分析拦截器,只支持 MySQL5.6.3 以上版本;
2、该插件的作用是分析 DELETE UPDATE 语句,防止小白或者恶意进行 DELETE UPDATE 全表操作;
3、只建议在开发环境中使用,不建议在生产环境使用;
4、在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句,根据结果集中的 Extra 列来断定当前是否全表操作。
com.baomidou.mybatisplus.plugins.PerformanceInterceptor
1、性能分析拦截器,用于输出每条 SQL 语句及其执行时间;
2、SQL 性能执行分析,开发环境使用 , 超过指定时间,停止运行。有助于发现问题。
com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor
1、常用于这样的需求: 当要更新一条记录的时候,希望这条记录没有被别人更新;
2、乐观锁的实现原理:取出记录时,获取当前 version,更新时,带上这个 version,执行更新时, set version = yourVersion+1 where version = yourVersion,如果 version 不对,就更新失败
3、@Version
用于注解实体字段,必须要有。
在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>
bean>
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor">
bean>
list>
property>
bean>
根据 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;
/**
*
* Mapper 接口
*
*/
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>
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<property name="sqlInjector" ref="mySqlInjector">property>property>
bean>
<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>
<property name="globalConfig" ref="globalConfiguration">property>
bean>
配置步骤:
1、实体类中的删除标志属性加上@TableLogic
注解:
public class User{
private Integer id ;
private String name ;
@TableLogic // 逻辑删除属性
private Integer logicFlag ;
}
2、配置文件:
<bean id="logicSqlInjector" class="com.baomidou.mybatisplus.mapper.LogicSqlInjector">bean>
<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>
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="globalConfig" ref="globalConfiguration">property>
bean>
配置成功后,删除操作就不是真正的删除,底层变成update操作,即把logicFlag
设置为-1,当查询时,就会带上where logicFlag=1
的条件,logicFlag
为-1的数据不会显示,达到逻辑删除的目的。
metaobject
: 元对象. 是 Mybatis 提供的一个用于更加方便,更加优雅的访问对象的属性,给对象的属性设置值 的一个对象. 还会用于包装对象. 支持对 Object 、Map、Collection等对象进行包装
本质上 metaObject
获取对象的属性值或者是给对象的属性设置值,最终是要通过 Reflector 获取到属性的对应方法的 Invoker, 最终 invoke.
在执行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>
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<property name="metaObjectHandler" ref="myMetaObjectHandler">property>property>
bean>
<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>
<property name="globalConfig" ref="globalConfiguration">property>
bean>