4. mybatis-plus

1 mybatis-plus简介

  1. MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生
  2. 在mybatis-plus中,我们只需要定义DAO接口,然后继承BaseMapper类即可,此前在DAO中定义的方法,以及映射文件,都不需要自己创建,所有操作都由Mybatis-plus自动完成
  3. mybatis-plus同时进行了一些默认设置,默认开启驼峰标识,默认不开启日志,如果需要获取插入的数据的主键的值,直接获取即可,该标识也已经开启
  4. 特性
    1. 无侵入:只做增强不做改变,引入它不会对现有工程产生影响
    2. 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
    3. 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
    4. 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
    5. 支持主键自动生成:支持多达 4 种主键策略,可自由配置,完美解决主键问题
    6. 支持 ActiveRecord 模式:实体类只需继承 Model 类即可进行强大的 CRUD 操作
    7. 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
    8. 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置可以使用
    9. 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
    10. 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
    11. 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
    12. 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

2 mybatis-plus环境搭建

  1. 导入pom依赖
<dependencies>
    <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus -->
    <!--导入次包后,mybatis的所有其他jar都不需要导入了,会帮你关联导入-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus</artifactId>
        <version>3.3.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.21</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.19</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>
  1. mybatis-config.xml
<?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>
        <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
</configuration>
  1. log4j.properties
# 全局日志配置
log4j.rootLogger=INFO, stdout
# MyBatis 日志配置
log4j.logger.com.mashibing=truce
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
  1. db.properties
driverClassname=com.mysql.cj.jdbc.Driver
username=root
password=c50hst
url=jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
  1. spring.xml
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driverClassname}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${username}"></property>
        <property name="password" value="${password}"></property>
    </bean>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--配置事务管理器-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
    <!--1. 使用spring集成mybatis-plus
        2. 与集成mybatis不同,需要替换sqlSessionFactoryBean的具体实现类-->
    <bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="typeAliasesPackage" value="com.mashibing.bean"></property>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.mashibing.dao"></property>
    </bean>
</beans>
  1. Emp.java
package com.mashibing.bean;

import com.baomidou.mybatisplus.annotation.TableName;

import java.util.Date;
//1. mybatis中不存在表名和实体类名不同需要对照的场景,因为在mybatis中,只需要将查询结果和实体类对应,不存在需要将实体类和表对应的场景
@TableName("tbl_emp")
public class Emp {
	
    private Integer empno;
    //2. 如果关闭了驼峰标志,且列名和属性名不一致,就需要手动配置表中列和属性对照关系
    //@TableField(value = "e_name")
    private String eName;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;

    public Emp() {
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String geteName() {
        return eName;
    }

    public void seteName(String eName) {
        this.eName = eName;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Double getComm() {
        return comm;
    }

    public void setComm(Double comm) {
        this.comm = comm;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + eName + '\'' +
                ", job='" + job + '\'' +
                ", mgr=" + mgr +
                ", hiredate=" + hiredate +
                ", sal=" + sal +
                ", comm=" + comm +
                ", deptno=" + deptno +
                '}';
    }
}
  1. 建立tbl_emp表
CREATE TABLE `tbl_emp` (
  `EMPNO` int(4) NOT NULL AUTO_INCREMENT,
  `E_NAME` varchar(10) DEFAULT NULL,
  `JOB` varchar(9) DEFAULT NULL,
  `MGR` int(4) DEFAULT NULL,
  `HIREDATE` date DEFAULT NULL,
  `SAL` double(7,2) DEFAULT NULL,
  `COMM` double(7,2) DEFAULT NULL,
  `DEPTNO` int(4) DEFAULT NULL,
  PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  1. ​EmpDao.java
package com.mashibing.dao;

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

//1. 在mybatis操作的时候,我们需要自己定义接口中实现的方法,并添加与之对应的EmpDao.xml文件,编写对应的sql语句
//2. 在mybatis-plus操作的时候,我们只需要继承BaseMapper接口即可,其中的泛型T表示我们要实际操作的实体类对象,而实体类与表的对应关系,在实体类中使用@TableName("tbl_emp")定义
public interface EmpDao extends BaseMapper<Emp> {
}

3 mybatis自带的增删改查

  1. mybatis自带了一些增删改查方法,如果需要自己定义语句,和mybatis中方式一模一样
3.1 插入
  1. MyTest.java
import com.mashibing.bean.Emp;
import com.mashibing.dao.EmpDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;

public class MyTest {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    private EmpDao empDao = context.getBean("empDao", EmpDao.class);
    @Test
    public void testInsert() {
        Emp emp = new Emp();
        emp.seteName("zhangsan");
        emp.setJob("Teacher");
        emp.setMgr(100);
        emp.setSal(1000.0);
        emp.setComm(500.0);
        emp.setHiredate(new Date());
        emp.setDeptno(10);
        int insert = empDao.insert(emp);
        System.out.println(insert);
    }
}
  1. 上述代码运行通过之后,控制台会打印警告信息,提示没有@TableId的注解,原因就在于定义实体类的时候并没有声明其中的主键是哪个列,以及使用什么样的主键生成策略
public class Emp {
	...
	//1. 在mybatis—plus2.x版本中,如果设置了主键自增,那么id必须指定为auto类型,否则插入不成功,3.x不存在此问题
    @TableId(value = "empno",type = IdType.AUTO)
    private Integer empno;
    ...
}

  1. 插入时,mybatis-plus会根据传入的实体类中非空属性的个数来动态的调整sql语句插入的字段数量
Emp emp = new Emp();
emp.seteName("zhangsan");
emp.setJob("Teacher");
emp.setMgr(100);
//        emp.setSal(1000.0);
//        emp.setComm(500.0);
//        emp.setHiredate(new Date());
//        emp.setDeptno(10);
//1. 打印出执行的语句为:INSERT INTO tbl_emp ( e_name, job, mgr ) VALUES ( ?, ?, ? ) 
int insert = empDao.insert(emp);
System.out.println(insert);
System.out.println(emp.getEmpno());
3.2 修改
  1. MyTest.java
Emp emp = new Emp();
emp.setEmpno(1);
emp.seteName("lisi");
emp.setJob("student");
emp.setMgr(100);
//1. 使用该方法时,必须在实体类中指定主键
//2. 同时emp对象中,必须主键对应的属性必须部位null
//3. 打印语句为:UPDATE tbl_emp SET e_name=?, job=?, mgr=? WHERE empno=? ,不会更新对象中属性为null对应的列
int update = empDao.updateById(emp);
System.out.println(update);
3.3 删除操作
  1. MyTest.java
//1. 根据id删除数据
int i = empDao.deleteById(1);
System.out.println(i);

//2. 根据一组id删除数据
int i1 = empDao.deleteBatchIds(Arrays.asList(2, 3, 4));
System.out.println(i1);

//3. 根据条件删除数据
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.in("empno", Arrays.asList(5, 6, 7));
//queryWrapper为空时,会删除所有数据,queryWrapper是包装类,表示查询条件
//delete操作使用时,需要使用QueryWrapper,修改操作需要加条件时使用UpdateWrapper
int delete = empDao.delete(queryWrapper);
System.out.println(delete);

//4. 将条件封装在map对象中
Map<String, Object> map = new HashMap<>();
map.put("empno", 9);
int i2 = empDao.deleteByMap(map);
System.out.println(i2);
3.4 查询操作
  1. MyTest.java
//1. 根据id查询对象
Emp emp = empDao.selectById(1);
System.out.println(emp);

//2. 根据QueryWrapper查询单个对象,返回的结果集有且仅能有一个对象
QueryWrapper<Emp> queryWrapper = new QueryWrapper<Emp>();
queryWrapper.eq("empno", 2).eq("e_name", "zhangsan");
Emp emp1 = empDao.selectOne(queryWrapper);
System.out.println(emp1);

//3. 通过多个id值进行查询
List<Emp> list = empDao.selectBatchIds(Arrays.asList(1, 2, 3));
for (Emp emp2 : list) {
    System.out.println(emp2);
}

//4. 通过map封装进行条件查询
Map<String, Object> map = new HashMap<String, Object>();
map.put("e_name", "zhangsan");
map.put("sal", 1000.0);
List<Emp> emps = empDao.selectByMap(map);
for (Emp emp3 : emps) {
    System.out.println(emp3);
}

//5. 分页查询,需要在spring.xml的sqlSessionFactoryBean中添加分页插件
//        <property name="plugins">
//            <array>
//                <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></bean>
//            </array>
//        </property>
//1. Page第一个参数是需要查询的页数,第二个参数为每页条数
//2. 执行语句为:SELECT empno,e_name,job,mgr,hiredate,sal,comm,deptno FROM tbl_emp LIMIT ?,?
Page<Emp> empPage = empDao.selectPage(new Page<Emp>(2, 5), null);
List<Emp> records = empPage.getRecords();
System.out.println(records);

//6. 根据条件返回查询结果总数
QueryWrapper<Emp> queryWrapper1 = new QueryWrapper<Emp>();
queryWrapper1.eq("e_name", "zhangsan");
Integer integer = empDao.selectCount(queryWrapper1);
System.out.println(integer);

//7. 根据条件查询所有结果返回list集合
List<Emp> emps1 = empDao.selectList(null);
for (Emp emp2 : emps) {
    System.out.println(emp2);
}

//8. 根据条件查询结果封装成map的list结构
List<Map<String, Object>> maps = empDao.selectMaps(null);
System.out.println(maps);

4 Mybatis-plus的相关配置

  1. mybatis一般在mybatis-config.xml中添加标签,来设置全局的默认策略,在MP中也具备相同的功能,同时也可以在spring.xml文件中进行全局配置
  2. 具体参数含义在https://mp.baomidou.com/config/中说明
  3. spring.xml
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <!--1. configLocation:指定MyBatis配置文件位置
		2. configuration:MyBatis全局策略配置,可以直接将mybatis-config.xml中内容在此处配置
		3. globalConfig:MyBatis-Plus带来的额外的全局策略配置
		4. configLocation与configuration,二者不能同时使用,选其中一个进行配置即可
	-->
    <property name="configuration" ref="configuration"/> <!--  非必须  -->
    <property name="globalConfig" ref="globalConfig"/> <!--  非必须  -->
    ......
</bean>

<bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
    <property name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl"></property>
    ......
</bean>

<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
    <property name="dbConfig" ref="dbConfig"/> 
    <!--1. 可以取消mybatis启动时,最开始打印的banner格式的字符串-->
    <property name="banner" value="false"/>
    <!--2. 插件也可以写在此处-->
    <property name="plugins">
        <array>
        	<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"></bean>
        </array>
    </property>
    ......
</bean>

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
    <!--1. 如果你的表的名字都具备相同的前缀,那么可以设置默认的前缀配置策略,此时的话可以将实体类上的@TableName标签省略不写
    	2. 所有实体类和表名对照关系都变为,表名=tbl_实体类名-->
    <property name="tablePrefix" value="tbl_"></property>
    <!--1. 正常情况每个类都需要配置主键生成策略,比较麻烦,可以选择将主键配置策略设置到全局配置中
    	2. -->
    <property name="idType" ref="idType"></property>
    ......
</bean>
<!--需要引入util命名空间-->
<util:constant id="idType" static-field="com.baomidou.mybatisplus.annotation.IdType.AUTO"></util:constant>

5 条件构造器Wrapper

  1. 看官网学习即可,一般建议还是写sql语句即可
  2. UpdateWrapper与QueryWrapper的区别在于一个用于拼接更新的条件,一个用于拼接查询和删除的条件

6 代码生成器

  1. 功能与mybatis逆向工程相同,比mybatis的逆向工程好用
  2. mybatis与mybatis-plus逆向工程区别
    1. MyBatis-plus是根据java代码开生成代码的,而Mybatis是根据XML文件的配置来生成的
    2. MyBatis-plus能够生成实体类、Mapper接口、Mapper映射文件,Service层,Controller层,而Mybatis只能生成实体类,Mapper接口,Mapper映射文件
6.1 生成过程
  1. 添加pom依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.1.tmp</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.16</version>
</dependency>
  1. 添加模板引擎依赖,MyBatis-Plus支持 Velocity(默认)、Freemarker、Beetl
<!--三选一即可-->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.2</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>
<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>3.1.1.RELEASE</version>
</dependency>
  1. 每次对maven的pom依赖做修改,编译器版本都会改变,可以加入如下配置防止编译器版本频繁变化
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
  1. 编写生成类
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;

public class MyTest {
    public static void main(String[] args) {
        testGenerator();
    }
    public static void testGenerator() {
        //1. 此处默认有两个对应的实现类不要导错包
        GlobalConfig globalConfig = new GlobalConfig();
        //2. 设置全局的配置
        globalConfig.setActiveRecord(true)//是否支持AR模式
                .setAuthor("lian")//设置作者
                //必须完整路径
                .setOutputDir("/Users/wusihan/IdeaProjects/mybatis-plus-generator/src/main/java")//设置生成路径
                .setFileOverride(true)//设置文件覆盖
                .setIdType(IdType.AUTO) //设置主键生成策略
                .setServiceName("%sService")//设置生成的serivce接口的名字
                .setBaseResultMap(true) //设置基本的结果集映射
                .setBaseColumnList(true);//设置基本的列集合

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

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

        // 进行包名的策略配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.mashibing")
                .setMapper("mapper")
                .setService("service")
                .setController("controller")
                .setEntity("bean")
                .setXml("mapper");

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

        autoGenerator.execute();
    }
}

7 插件扩展

  1. 除了分页插件,其他插件都没什么用
7.1 分页插件
  1. 上面已经介绍
7.2 乐观锁插件
  1. 修改实体类添加version域,在其上使用@Version注解,并在表中添加version字段
  2. 添加插件配置
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"></bean>
  1. 测试类
@Test
public void testOptimisticLocker(){
    Emp emp = new Emp();
    emp.setEmpno(1);
    emp.seteName("zhang");
    emp.setSal(25.0);
    emp.setComm(35.0);
    //1. 如果emp对象的version属性值和数据库中值不同,更新不会成功,但后台不会报错
    //2. 如果version值和表中相同,那么更新成功,数据库中version值自动加1
    emp.setVersion(15);
    //3. 执行的语句实际上是:UPDATE tbl_emp SET e_name=?, sal=?, comm=?, version=? WHERE empno=? AND version=?
    //4. 如果emp中version值和表中该值不同时,更新失败,但不会报错,如果相同,更新成功,表中version自动更新为原值+1
    empDao.updateById(emp);
}
7.3 SQL执行分析插件,避免出现全表更新和删除
  1. 添加插件配置
<bean class="com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor">
    <property name="sqlParserList">
        <list>
            <bean class="com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser"></bean>
        </list>
    </property>
</bean>
  1. 测试类
@Test
public void testSqlExplain(){
    int delete = empDao.delete(null);
    System.out.println(delete);
}
7.4 非法sql检查插件,可以阻断没有where条件的语句
  1. 添加插件配置
<bean class="com.baomidou.mybatisplus.extension.plugins.IllegalSQLInterceptor">
</bean>
  1. 测试类
@Test
public void testSqlIllegal(){
    QueryWrapper<Emp> queryWrapper = new QueryWrapper<>();
    queryWrapper.or();
    List<Emp> list = empDao.selectList(queryWrapper);
    for (Emp emp : list) {
        System.out.println(emp);
    }
}

8 SQL注入器

  1. 可以将配置在xml中的语句使用注入的方式注入到全局中,就不需要再编写sql语句
  2. 没什么用,正常直接写在dao中就行了没必要这么麻烦

9 公共字段填充

  1. 可以不必自己写代码,就为实体类属性提供一个默认值,一般用于对表中时间戳字段的填充一个默认值,因为所有创建时间的方法都一致,防止业务程序中大量冗余代码,效果等同于在表上设置默认值为当前时间戳
9.1 使用流程
  1. 自定义一个MetaObjectHandler
package com.mashibing.fill;

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

public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        //1. 需要写成实体类属性名
        // 起始版本 3.3.0(推荐使用)
        this.strictInsertFill(metaObject, "eName", String.class, "wusihan");
        // 也可以使用(3.3.0 该方法有bug请升级到之后的版本如`3.3.1.8-SNAPSHOT`)
//        this.fillStrategy(metaObject, "createTime", LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "eName", String.class, "wusihan");
//        this.fillStrategy(metaObject, "updateTime", LocalDateTime.now());
    }
}
  1. 修改spring.xml配置文件
...
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
    <property name="metaObjectHandler" ref="myMeta"></property>
</bean>
...
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="globalConfig" ref="globalConfig"></property>
    ...
</bean>
...
  1. 为实体类中需要使用公共字段填充的属性添加注释
//表示更新时,自动为eName填充值wusihan
@TableField(fill= FieldFill.UPDATE)
private String eName;
  1. 测试类
@Test
public void testMeta(){
    //1. 注意如果想以emp对象中传入的empno属性的值,作为数据库中主键empno的值,需要修改生成策略,否则插入会失败
//        @TableId(type= IdType.INPUT)
//        private Integer empno;
    //2. 此时即使emp对象的eName属性值为null,表中e_name字段上中也会赋值为wusihan
    Emp emp = new Emp();
    emp.setEmpno(123);
    int insert = empDao.insert(new Emp());
    System.out.println(insert);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值