超简单的MyBatisPlus快速入门

1、简介

  MyBatis-Plus(简称 简称 MP), 是一个 MyBatis 的增强 工具包,只做增强不做改变. 为简化开发工作、提高生产率而生。
  愿景是成为 Mybatis 最好的搭档,就像 魂斗罗 中的 1P 、2P ,基友搭配,效率翻倍。
在这里插入图片描述
官方地址:http://mp.baomidou.com/
代码发布地址:https://github.com/baomidou/mybatis-plushttps://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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值