SSM框架阶段 - MyBatisPlus3.0

概述

  • MyBatis-Plus(简称 MP),是一个 MyBatis 的增强工具包,只做增强不做改变.,为简化开发工作、提高生产率而生
  • Mybatis-Plus 的集成非常简单,对于 Spring,我们仅仅需要把 Mybatis 自带的MybatisSqlSessionFactoryBean 替换为 MP 自带的即可
  • CRUD指在做计算处理时的增加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写

	
	
	
	
	

CRUD实现方式

  • 基于 Mybatis
    • 需要编写 xxxMapper 接口,并手动编写 CRUD 方法
    • 提供 xxxMapper.xml 映射文件,并手动编写每个方法对应的 SQL 语句
  • 基于 MP
    • 只需要创建 xxxMapper 接口,并继承 BaseMapper 接口,这就是使用 MP需要完成的所有操作,甚至不需要创建 SQL 映射文件
  • 重要对象
    • Configuration: MyBatis 或者 MP 全局配置对象
    • MappedStatement:一个 MappedStatement 对象对应 Mapper 配置文件中的一个select/update/insert/delete 节点,主要描述的是一条 SQL 语句,MP 在启动就会挨个分析 xxxMapper 中的方法,并且将对应的 SQL 语句处理好,保存到 configuration 对象中的mappedStatements 中
    • SqlMethod : 枚举对象 ,MP 支持的 SQL 方法
    • TableInfo:数据库表反射信息 ,可以获取到数据库表相关的信息
    • SqlSource: SQL 语句处理对象
    • MapperBuilderAssistant: 用于缓存、SQL 参数、查询方剂结果集处理等,通过 MapperBuilderAssistant 将每一个 mappedStatement添加到 configuration 中的 mappedstatements 中
  • 全局策略配置(spring 的配置文件applicationContext.xml中)


		
		
		
		
				
		
		
		

	


		
		
		
		
		
		
		

注解

  • @TableName:表名注解
    • value:实体类中指明表名,默认实体类名要与表名一致
    • resultMap:xml 中 resultMap 的 id
  • @TableId:主键注解
    • value:实体类中指明主键列列名,若与表一致则可省略
    • type:主键类型(策略)
  • @TableField:字段注解(非主键)
    • value:实体类中指明数据库字段名
    • el:映射为原生 #{ … } 逻辑,相当于写在 xml 里的 #{ … } 部分
    • exist:是否为数据库表字段,默认为true
    • condition:字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的
    • update:字段 update set 部分注入(该属性优先级高于 el 属性)
    • jdbcType:JDBC类型
    • typeHandler:类型处理器
    • numericScale:指定小数点后保留的位数
  • @Version:乐观锁注解
  • @EnumValue:通枚举类注解(注解在枚举字段上)

代码生成器

  • MP 的代码生成器都是基于 java 代码来生成,Mybatis MBG代码生成器基于 xml 文件进行代码生成
  • MyBatis 的代码生成器可生成: 实体类、Mapper 接口、Mapper 映射文件,MP 的代码生成器可生成: 实体类(可以选择是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 层、Controller 层
  • 添加代码生成器依赖

    com.baomidou
    mybatis-plus-generator
    3.3.1.tmp

  • 添加 模板引擎 依赖

    org.apache.velocity
    velocity-engine-core
    2.2



    org.freemarker
    freemarker
    2.3.30


    com.ibeetl
    beetl
    3.1.1.RELEASE

  • 编写生成类
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

public class MyTest {
    
	@Test
    public void testGenerator() {

        //1、此处默认有两个对应的实现类,不要导错包.import com.baomidou.mybatisplus.generator.config.GlobalConfig;
        GlobalConfig globalConfig = new GlobalConfig();
        //设置全局的配置
        globalConfig.setActiveRecord(true)  //是否支持AR模式
                .setAuthor("lian")  //设置作者
                .setOutputDir("D:\\Git\\study_mybatis_plus\\1\\src\\main\\java")  //设置生成路径
                .setFileOverride(true)  //设置文件覆盖
                .setIdType(IdType.AUTO) //设置主键生成策略
                .setServiceName("%sService")  //设置生成的serivce接口的名字。 默认的名字首字母为I。 %sService :去掉I
                .setBaseResultMap(true)   //设置基本的结果集映射
                .setBaseColumnList(true);  //设置基本的列集合


        //2、设置数据源的配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver")
                .setUrl("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC")
                .setUsername("root")
                .setPassword("123456");


        // 3、进行策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true)//设置全局大写命名
                .setNaming(NamingStrategy.underline_to_camel)//数据库表映射到实体的命名策略
                .setTablePrefix("tbl_")//设置表名前缀
                .setInclude("tbl_emp");//生成的表


        // 4、进行包名的策略配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("study2")
                .setMapper("mapper")
                .setService("service")
                .setController("controller")
                .setEntity("beans")
                .setXml("mapper");  //和mapper接口放一起


        //5、整合配置
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator
                .setGlobalConfig(globalConfig)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig);

        //6、执行
        autoGenerator.execute();
    }
//可以在Controller层可以直接实现调用,这些调用的实现最核心的功能就在于ServiceImpl类,这个类中自动完成mapper的注入,同时提供了一系列CRUD的方法
}

CRUD 接口

Service CRUD 接口说明:
封装IService接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆
泛型 T 为任意实体对象
建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类
对象 Wrapper 为 条件构造器

  • Service CRUD 接口
    • Save方法
      • boolean save(T entity); //插入一条记录(选择字段,策略插入)
      • boolean saveBatch(Collection entityList); //插入集合
      • boolean saveBatch(Collection entityList, int batchSize); //按批次数量插入集合
    • SaveOrUpdate方法
      • boolean saveOrUpdate(T entity); //TableId 注解存在则更新记录,不存在则插入记录
      • boolean saveOrUpdate(T entity, Wrapper updateWrapper); //根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
      • boolean saveOrUpdateBatch(Collection entityList); //批量修改插入
      • boolean saveOrUpdateBatch(Collection entityList, int batchSize); //批量修改插入
    • Remove方法
      • boolean remove(Wrapper queryWrapper); //根据 entity 条件,删除记录
      • boolean removeById(Serializable id); //根据 ID 删除
      • boolean removeByMap(Map columnMap); //根据 columnMap 条件,删除记录
      • boolean removeByIds(Collection idList); //删除(根据ID 批量删除)
    • Update方法
      • boolean update(Wrapper updateWrapper); //根据 UpdateWrapper 条件,更新记录 需要设置sqlset
      • boolean update(T entity, Wrapper updateWrapper); //根据 whereEntity 条件,更新记录
      • boolean updateById(T entity); //根据 ID 选择修改
      • boolean updateBatchById(Collection entityList); //根据ID 批量更新
      • boolean updateBatchById(Collection entityList, int batchSize); //根据ID 批量更新
    • Get方法
      • T getById(Serializable id); //根据 ID 查询
      • T getOne(Wrapper queryWrapper); //根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last(“LIMIT 1”)
      • T getOne(Wrapper queryWrapper, boolean throwEx); //根据 Wrapper,查询一条记录
      • Map getMap(Wrapper queryWrapper); //根据 Wrapper,查询一条记录
      • V getObj(Wrapper queryWrapper, Function mapper); //根据 Wrapper,查询一条记录
    • List方法
      • List list(); //查询所有
      • List list(Wrapper queryWrapper); //查询列表
      • Collection listByIds(Collection idList); //查询(根据ID 批量查询)
      • Collection listByMap(Map columnMap); //查询(根据 columnMap 条件)
      • List> listMaps(); //查询所有列表
      • List> listMaps(Wrapper queryWrapper); //查询列表
      • List listObjs(); //查询全部记录
      • List listObjs(Function mapper); //查询全部记录
      • List listObjs(Wrapper queryWrapper); //根据 Wrapper 条件,查询全部记录
      • List listObjs(Wrapper queryWrapper, Function mapper); //根据 Wrapper 条件,查询全部记录
    • Page方法
      • IPage page(IPage page); //无条件分页查询
      • IPage page(IPage page, Wrapper queryWrapper); //条件分页查询
      • IPage> pageMaps(IPage page); //无条件分页查询
      • IPage> pageMaps(IPage page, Wrapper queryWrapper); //条件分页查询
    • Count方法
      • int count(); //查询总记录数
      • int count(Wrapper queryWrapper); //根据 Wrapper 条件,查询总记录数
    • Chain方法
      • QueryChainWrapper query(); //链式查询 例:query().eq(“column”, value).one();
      • LambdaQueryChainWrapper lambdaQuery(); //链式查询 lambda 式 例:lambdaQuery().eq(Entity::getId, value).list();
      • UpdateChainWrapper update(); //链式更改
      • LambdaUpdateChainWrapper lambdaUpdate(); //链式更改 lambda 式

Service CRUD 接口说明:
通用 CRUD 封装BaseMapper接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器
泛型 T 为任意实体对象
参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键
对象 Wrapper 为 条件构造器

  • Mapper CRUD 接口
    • Insert方法
      • 支持主键自增的数据库插入数据获取主键值,主键自动与实体类主键属性映射,使用get方法即可获取
      • int insert(T entity); //插入一条记录,根据实体类每个属性进行非空判断,只有字段不为空,才会写入sql语句中
    • Delete方法
      • int delete(@Param(Constants.WRAPPER) Wrapper wrapper); //根据 entity 条件,删除记录
      • int deleteBatchIds(@Param(Constants.COLLECTION) Collection idList); //删除(根据ID 批量删除)
      • int deleteById(Serializable id); //根据 ID 删除
      • int deleteByMap(@Param(Constants.COLUMN_MAP) Map columnMap); //根据 columnMap 条件,删除记录
    • update方法
      • int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper updateWrapper); //根据 whereEntity 条件,更新记录,updateWrapper实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
      • int updateById(@Param(Constants.ENTITY) T entity); //根据 ID 修改,根据实体类每个属性进行非空判断
    • Select方法
      • T selectById(Serializable id); //根据 ID 查询
      • T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper); //根据 entity 条件,查询一条记录
      • List selectBatchIds(@Param(Constants.COLLECTION) Collection idList); //查询(根据ID 批量查询)
      • List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); //根据 entity 条件,查询全部记录
      • List selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap); //查询(根据 columnMap 条件)
      • List> selectMaps(@Param(Constants.WRAPPER) Wrapper queryWrapper); //根据 Wrapper 条件,查询全部记录
      • List selectObjs(@Param(Constants.WRAPPER) Wrapper queryWrapper); //根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
      • IPage selectPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper); //根据 entity 条件,查询全部记录(并翻页)
      • IPage> selectMapsPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper); //根据 Wrapper 条件,查询全部记录(并翻页)
      • Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper); //根据 Wrapper 条件,查询总记录数

条件构造器

AbstractWrapper是QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类,用于生成 sql 的 where 条件,entity 属性也用于生成 sql 的 where 条件
以下参数boolean condition表示该条件是否加入最后生成的sql中
通过链式编程的方式拼接出sql语句

  • AbstractWrapper
    • allEq方法:全部eq(或个别isNull)
      • allEq(Map params) //r为数据库字段名,v为字段值
        • 例:allEq({id:1,name:“老王”,age:null}) → id = 1 and name = ‘老王’ and age is null
      • allEq(Map params, boolean null2IsNull) //null2IsNull : 为true则在map的value为null时调用isNull方法,为false时则忽略value为null的
        • 例:allEq({id:1,name:“老王”,age:null}, false) → id = 1 and name = ‘老王’
      • allEq(BiPredicate filter, Map params) //filter : 过滤函数,是否允许字段传入比对条件中
        • 例:allEq((k,v) -> k.indexOf(“a”) >= 0, {id:1,name:“老王”,age:null}) → name = ‘老王’ and age is null
      • allEq(BiPredicate filter, Map params, boolean null2IsNull)
        • 例:allEq((k,v) -> k.indexOf(“a”) >= 0, {id:1,name:“老王”,age:null}, false) → name = ‘老王’
      • allEq(boolean condition, BiPredicate filter, Map params, boolean null2IsNull)
    • isNull:字段 IS NULL
    • isNotNull:字段 IS NOT NULL
    • eq方法:等于 =
      • eq(R column, Object val)
      • eq(boolean condition, R column, Object val)
    • ne方法:不等于 <>
    • gt方法:大于 >
    • ge方法:大于等于 >=
    • lt方法:小于 <
    • le方法:小于等于 <=
    • between方法:BETWEEN 值1 AND 值2
    • notBetween方法:NOT BETWEEN 值1 AND 值2
    • like方法:LIKE '%值%
      • like(R column, Object val)
        • 例:like(“name”, “王”) → name like ‘%王%’
    • notLike方法:NOT LIKE '%值%
    • likeLeft方法:LIKE ‘%值’
    • likeRight方法:LIKE ‘值%’
    • in方法
      • in(R column, Collection value) //字段 IN (value.get(0), value.get(1), …)
      • in(R column, Object… values) //字段 IN (v0, v1, …)
    • notIn方法:字段 NOT IN …
    • inSql方法
      • inSql(R column, String inValue):字段 IN ( sql语句 )
        • 例:inSql(“id”, “select id from table where id < 3”) → id in (select id from table where id < 3)
    • notInSql方法:字段 NOT IN ( sql语句 )
    • groupBy方法:GROUP BY 字段, …
    • orderByAsc方法:ORDER BY 字段, … ASC
    • orderByDesc方法:ORDER BY 字段, … DESC
    • orderBy方法:ORDER BY 字段, …
    • having方法
      • having(String sqlHaving, Object… params):HAVING ( sql语句 )
        • 例:having(“sum(age) > 10”) → having sum(age) > 10
        • 例:having(“sum(age) > {0}”, 11) → having sum(age) > 11
    • func方法:方便在出现if…else下调用不同方法能不断链
      • func(Consumer consumer)
        • 例:func(i -> if(true) {i.eq(“id”, 1)} else {i.ne(“id”, 1)})
    • or方法
      • or()
        • 例:eq(“id”,1).or().eq(“name”,“老王”) → id = 1 or name = ‘老王’
    • and方法
      • and(Consumer consumer)
        • 例:and(i -> i.eq(“name”, “李白”).ne(“status”, “活着”)) → and (name = ‘李白’ and status <> ‘活着’)
    • nested方法:
      • nested(Consumer consumer)
        • 例:nested(i -> i.eq(“name”, “李白”).ne(“status”, “活着”)) → (name = ‘李白’ and status <> ‘活着’)
    • apply方法
      • apply(String applySql, Object… params):拼接 sql
        • 例:apply(“date_format(dateColumn,‘%Y-%m-%d’) = ‘2008-08-08’”) → date_format(dateColumn,‘%Y-%m-%d’) = ‘2008-08-08’")
    • last方法
      • last(String lastSql):无视优化规则直接拼接到 sql 的最后
      • 只能调用一次,多次调用以最后一次为准 有sql注入的风险
    • exists方法
      • exists(String existsSql):拼接 EXISTS ( sql语句 )
        • exists(“select id from table where age = 1”) → exists (select id from table where age = 1)
    • notExists方法
      • notExists(String notExistsSql):拼接 NOT EXISTS ( sql语句 )
  • QueryWrapper
    • 继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件及 LambdaQueryWrapper, 可以通过 new QueryWrapper().lambda() 方法获取
    • select方法:设置查询字段
      • select(String… sqlSelect)
      • select(Predicate predicate)
      • select(Class entityClass, Predicate predicate)
  • 问题总结
//全表扫描,配置全表扫描阻断器后,会报错
QueryWrapper<SysUserInfo> query = new QueryWrapper<>();
query.eq("user_id", sysUserInfo.getUserId()).eq("state", "1");
SysUserInfo sysUserInfo = new SysUserInfo();
sysUserInfo.setState("5");
userInfoMapper.update(sysUserInfo,query);//query条件自动被忽略,UPDATE sys_user_info SET state=?
//非全表扫描
userInfoMapper.update(null, new UpdateWrapper<SysUserInfo>().lambda()
                .set(SysUserInfo::getState, "5")
                .eq(SysUserInfo::getState, "1")
                .eq(SysUserInfo::getUserId, sysUserInfo.getUserId())
        );

插件扩展

  • MyBatis 允许在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括
    • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
    • ParameterHandler (getParameterObject, setParameters)
    • ResultSetHandler (handleResultSets, handleOutputParameters)
    • StatementHandler (prepare, parameterize, batch, update, query)
  • 插件原理
    • 四大对象的每个对象在创建时,都会执行interceptorChain.pluginAll(),会经过每个插件对象的plugin()方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理
分页插件
  • 在spring.xml的sqlSessionFactoryBean添加如下配置引入插件

        
            
                
                
            
        

  • 测试
@Test
public void TestPage(){
    Page page = new Page(1,2);
    Page selectPage = empDao.selectPage(page, null);
    List records = selectPage.getRecords();
    System.out.println();
    for (Emp e : records){
        System.out.println(e);
    }

    System.out.println("获取总条数:"+page.getTotal());
    System.out.println("当前页码:"+page.getCurrent());
    System.out.println("总页码:"+page.getPages());
    System.out.println("每页显示的条数:"+page.getSize());
    System.out.println("是否有上一页:"+page.hasPrevious());
    System.out.println("是否有下一页:"+page.hasNext());

    //还能把查询到的结构封装到page对象中
    page.setRecords(records);
}
乐观锁插件
  • 当要更新一条记录的时候,希望这条记录没有被别人更新
  • 实现方式
    • 取出记录时,获取当前version,更新时,带上这个version,执行更新时, set version = yourVersion+1 where version = yourVersion,如果version不对,就更新失败
  • 添加配置

  • 修改实体类添加version字段、@Version注解、添加setter、getter方法并在表中添加version字段
@Version
private Integer version;

public Integer getVersion() {
    return version;
}

public void setVersion(Integer version) {
    this.version = version;
}
  • 测试
@Test
public void testOptimisticLocker(){
    Emp emp = new Emp();
    emp.setEmpno(1);
    emp.seteName("老王");
    emp.setVersion(1);
    int i = empDao.updateById(emp);
    System.out.println(i);
}
Sql 注入器
  • 根据MybatisPlus 的 DefaultSqlInjector 和 AbstractMethod 可以自定义各种你想要的 sql ,在加载 mybatis 环境时就注入到全局中,相当于自定义 Mybatisplus 自动注入的方法(像BaseMapper的内置方法)
  • 步骤
    • 在 Mapper 接口中定义相关的 CRUD 方法
    • 扩展 AbstractMethod 的 injectMappedStatement 方法,实现 Mapper 接口中方法要注入的 SQL
    • 扩展 DefaultSqlInjector ,重写 getMethodList 方法,添加自定义方法
    • 修改applicationContext.xml文件,在 MP 全局策略中,配置自定义注入器
  • EmpDao类
package study.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import study.bean.Emp;

public interface EmpDao extends BaseMapper {
    int deleteAll();
}
  • deleteAll类
package study.injector;

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;

//这一步实现了mapper中对应方法的sql的功能实现。
public class deleteAll extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) {
        /* 执行 SQL ,动态 SQL 参考类 SqlMethod */
        String sql = "delete from " + tableInfo.getTableName();
        /* mapper 接口方法名一致 */
        String method = "deleteAll";
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addDeleteMappedStatement(mapperClass, method, sqlSource);
    }
}
  • mySqlInjector类
package study.injector;

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(Class mapperClass) {
        List methodList = super.getMethodList(mapperClass);
        //增加自定义方法
        methodList.add(new deleteAll());
        return methodList;
    }

}
  • 测试
@Test
public void testInjector(){
    int ret = empDao.deleteAll();
    System.out.println(ret);
}
公共字段填充
  • metaobject: 元对象,是 Mybatis 提供的一个用于更加方便,更加优雅的访问对象的属性,给对象的属性设置值 的一个对象. 还会用于包装对象. 支持对 Object 、 Map、 Collection等对象进行包装,本质上 metaObject 获取对象的属性值或者是给对象的属性设置值,最终是要通过 Reflector 获取到属性的对应方法的 Invoker, 最终 invoke
  • 步骤
    • 注解填充字段 @TableFile(fill = FieldFill.INSERT)
    • 自定义公共字段填充处理器MetaObjectHandler
    • MP 全局注入 自定义公共字段填充处理器
  • 添加 @TableFile注解
@TableField(fill = FieldFill.INSERT_UPDATE)
private String job;
  • 自定义公共字段填充处理器MetaObjectHandler
package study.metaObjectHandler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;

public class myMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        //获取到需要被填充的字段的值
        this.strictInsertFill(metaObject, "job", String.class, "IT"); // 起始版本 3.3.0(推荐使用)
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "job", String.class,"Teacher"); // 起始版本 3.3.0(推荐使用)
    }
}
  • MP 全局注入 自定义公共字段填充处理器

     
     
     



  • 测试
@Test
public void testMeta(){
    int insert = empDao.insert(new Emp());
    System.out.println(insert);
}

MyBatisPlus官方地址 http://mp.baomidou.com

你可能感兴趣的:(java框架,MyBatis-Plus)