mybatis-plus 3.0 的基本使用

本文详细介绍了mybatis-plus 3.0的使用,从环境搭建到CRUD操作,再到条件构造器Wrapper、代码生成器、插件扩展、SQL注入器和公共字段填充的配置和应用,提供了全面的实践指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mybatis-plus 的使用

3.0版本

1、mybatis-plus环境搭建

Emp类

package study.bean;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.util.Date;

public class Emp {

    private Integer empno;
    private String eName;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;

    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 +
                '}';
    }
}

数据库表sql语句

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;

pom.xml

mybatis和mybatis-spring整合依赖不用手动导入依赖,以免引起版本冲突,mybatis-plus会自动维护

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>study_mybatis_plus</groupId>
    <artifactId>study_mybatis_plus</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.3.1</version>
        </dependency>


        <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>
    </dependencies>

</project>

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>

log4j.properties

# 全局日志配置
log4j.rootLogger=INFO, stdout
# MyBatis 日志配置
log4j.logger.study=DEBUG
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

db.properties

#pom依赖中mysql使用8以上的版本多了一个叫cj的目录
jdbc.driver=com.mysql.cj.jdbc.Driver
#使用虚拟机里的。    需要加上serverTimezone=UTC属性,保证数据库正常连接
jdbc.url=jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

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
https://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="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.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"/>

    <!--整合spring和mybatis-->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
     </bean>
    <!--扫描mapper接口的路径-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="study.dao"></property>
    </bean>
</beans>

测试

import com.alibaba.druid.pool.DruidDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.sql.SQLException;

public class MyTest {

    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

    @Test
    public void test01() throws SQLException {
        DruidDataSource dataSource = context.getBean("dataSource", DruidDataSource.class);

        //获取连接,可以获取:证明db.properties、数据源等配置没问题
        System.out.println(dataSource.getConnection());
    }
}

运行控制台输出:

INFO [main] - {dataSource-1} initedcom.mysql.cj.jdbc.ConnectionImpl@70cf32e3

​ 在集成mybatis-plus的时候非常简单,只需要替换mybatis自己的sqlSessionFactoryBean对象即可

<!--配置sqlSessionFactoryBean
mybatis提供的:org.mybatis.spring.SqlSessionFactoryBean
MP提供的:com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
-->
<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>

2、简单的CRUD操作

在Mybatis中,我们需要编写对应的Dao接口,并在接口中定义相关的方法,然后提供与该接口相同名称的Dao.xml文件,在文件中填写对应的sql语句,才能完成对应的操作

在Mybatis-plus中,我们只需要定义接口,然后继承BaseMapper类即可,此前做的所有操作都是由Mybatis-plus来帮我们完成,不需要创建sql映射文件

EmpDao类

package study.dao;

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

public interface EmpDao extends BaseMapper<Emp> {

}

1、插入操作

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import study.bean.Emp;
import study.dao.EmpDao;

public class MyTest {

    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

    EmpDao empDao = context.getBean("empDao",EmpDao.class);

    @Test
    public void testCommonInsert(){
        Emp emp = new Emp();
        emp.setEmpno(1111);
        emp.seteName("zhangsan");
        //使用MP自带的方法,插入到数据库
        int i = empDao.insert(emp);
        System.out.println(i);
    }
}

运行时会报错。原因在于实体类的名称跟数据库表的名称不匹配,因此在实现的是需要添加**@TableName注解,指定具体的表的名称**

@TableName(value="emp")
public class Emp {//省略其他相同代码}

@TableId的注解,原因就在于定义实体类的时候并没有声明其中的主键是哪个列,以及使用什么样的主键生成策略

@TableName("tbl_emp")
public class Emp {

    /**
     * 在 mybatis-plus2.x版本的时候,如果设置了表自增,那么id必须制定为auto类型,否则插入不成功,3.x不存在此问题
     */
        /*
    @TableId
   		 value : 指定数据库数据库主键列名。
   		 type  : 指定主键策略。
  	 		 IdType.AUTO :数据库id自增。
    */
    @TableId(value = "empno",type = IdType.AUTO)
    private Integer empno;
    
    //省略其他相同代码
}

再次运行测试类,即可完成插入操作。

本案例的测试类只是插入了2个字段值,mybatis-plus会根据输入的对象的字段的个数来动态的调整sql语句插入的字段,这是mybatis-plus比较灵活的地方

2、更新操作

    @Test
    public void testCommonUpdate(){
        Emp emp = new Emp();
        emp.setEmpno(1);
        emp.seteName("lisi");
        //updateById会进行非空判断
        int i = empDao.updateById(emp);
        System.out.println(i);
    }

3、删除操作

    @Test
    public void testCommonDelete(){
        //1、根据id删除数据
        int i = empDao.deleteById(1);
        System.out.println();
        System.out.println(i);
        
        // 2、根据一组id删除数据
        int i = empDao.deleteBatchIds(Arrays.asList(1, 2, 3, 4));
        System.out.println();
        System.out.println(i);
        
        // 3、条件封装map删除数据
        Map<String,Object> map = new HashMap<>();
        //第一个参数写列名
        map.put("empno",5);
        int i = empDao.deleteByMap(map);
        System.out.println();
        System.out.println(i);
        
        // 4、根据条件删除数据
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("empno", Arrays.asList(6, 7, 8, 9));
        int i = empDao.delete(queryWrapper);
        System.out.println();
        System.out.println(i);
    }

4、查询操作

    @Test
    public void testselect(){
        // 1、根据id查询对象
        Emp emp = empDao.selectById(10);
        System.out.println();
        System.out.println(emp);

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

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

        // 4、通过map封装进行条件查询
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("empno",10);
        List<Emp> list = empDao.selectByMap(map);
        for (Emp e:list) {
            System.out.println(e);
        }

        //5、分页查询,需要添加分页插件

/* 在mybatis全局配置文件设置
			<property name="plugins">
                  <array>
                      <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></bean>
                  </array>
             </property>*/

            //第一个参数是当前页码,第二个参数x条数据。  Page是MP提供的分页辅助类对象
         Page<Emp> empPage = empDao.selectPage(new Page<>(2, 2), null);
         List<Emp> records = empPage.getRecords();
         System.out.println(records);

        // 6、根据条件返回查询结果总数
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("empno",10);
        Integer i = empDao.selectCount(queryWrapper);
        System.out.println(i);

        // 7、根据条件查询所有结果返回list集合
            //参数要传入Wrapper<T> queryWrapper
        List<Emp> list = empDao.selectList(null);
        for (Emp emp : list) {
            System.out.println(emp);
        }
        
        // 8、根据条件查询结果封装成map的list结构
        //参数要传入Wrapper<T> queryWrapper
        List<Map<String, Object>> mapList = empDao.selectMaps(null);
        System.out.println(mapList);
    }

3、Mybatis-plus的相关配置

Mybatis-plus可以在spring.xml文件中添加配置

https://mp.baomidou.com/config/

spring.xml

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="configuration" ref="configuration"/> <!--  非必须  -->
    <property name="globalConfig" ref="globalConfig"/> <!--  非必须  -->
    ......
</bean>

<bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
    ......
</bean>

<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
    <property name="dbConfig" ref="dbConfig"/> <!--  非必须  -->
    ......
</bean>

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
    ......
</bean>

​ 通过这个配置文件的配置,可以进行回想上述问题的出现,mybatis-plus是如何解决这个问题的呢?

​ 在mybatis-plus中会引入写默认的配置,这个选项的默认配置为true(比如驼峰规则),因此可以完成对应的实现。

1、在spring.xml配置mybatis-plus,并且把驼峰规则禁用

<!--省略其他代码-->

    <!--整合spring和mybatis-->
    <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>

                <!--把MP相关的全局配置注入到sqlSessionFactoryBean-->
        <property name="configuration" ref="configuration"></property>
        <property name="globalConfig" ref="globalConfig"></property>
    </bean>


    <bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
        <property name="mapUnderscoreToCamelCase" value="false"></property>
    </bean>

    <bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        <property name="dbConfig" ref="dbConfig"></property>
    </bean>

    <bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">

    </bean>

运行测试时会报错,原因是:Property ‘configuration’ and ‘configLocation’ can not specified with together

此时,可以把configLocation给注释掉,就是不使用mybatis的配置;在运行测试,会发现报错,原因是驼峰规则被禁用了,再次设置为true即可;除此之外还可以设置@TableField

    @TableField(value = "e_name")
    private String eName;

2、此时发现日志功能又无法使用了,只需要添加如下配置

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

3、我们在刚刚插入数据的时候发现每个类可能都需要写主键生成策略,这是比较麻烦的,因此可以选择将主键配置策略设置到全局配置中

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
        <property name="idType" ref="idType"></property>
    </bean>
    <util:constant id="idType" static-field="com.baomidou.mybatisplus.annotation.IdType.AUTO"></util:constant>

4、如果表的名字都具备相同的前缀,那么可以设置默认的前缀配置策略,此时的话可以将实体类上的@TableName标签省略不写

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
        <property name="idType" ref="idType"></property>
        <property name="tablePrefix" value="tbl_"></property>
    </bean>
    <util:constant id="idType" static-field="com.baomidou.mybatisplus.annotation.IdType.AUTO"></util:constant>

5、在mybatis-plus中如果需要获取插入的数据的主键的值,那么直接获取即可,原因就在于配置文件中指定了默认的属性为true

mybatis:需要通过useGenerateKeys 以及 keyProperties 来设置

MP:自动将主键值回写到实体类中

    @Test
    public void testCommonInsert(){
        Emp emp = new Emp();
        emp.seteName("lisi");
        int i = empDao.insert(emp);
        //获取刚才新插入对象的id
        Integer empno = emp.getEmpno();
        System.out.println(empno);
    }

4、条件构造器Wrapper

需求:分页查询tbl_emp表中,SAL在7000~9000,工作为IT,且姓名为xx的所有用户

mybatis:sql映射文件中写带条件的sql语句,并基于PageHelper插件完成分页

MP:不用写SQL语句,MP提供了条件构造器QueryWrapper

查询包装器QueryWrapper, 主要用于处理 sql 拼接,排序,实体参数查询等

//实现代码
    @Test
    public void testWrapper() {
        //需求:分页查询tbl_emp表中,SAL在7000~9000,job为IT,且姓名为xx的所有用户
        Page<Emp> empPage = empDao.selectPage(new Page<Emp>(1, 2),
                new QueryWrapper<Emp>()
                        .between("sal", 7000, 9000)
                        .eq("job", "IT")
                        .eq("e_name", "zhangsan")
        );
        System.out.println(empPage.getRecords());
    }

使用QueryWrapper完成带条件的查询

        //查询sal在4000~9000,ename带有老师,或者job带有a的
        List<Emp> list = empDao.selectList(new QueryWrapper<Emp>()
                .between("sal", 4000, 9000)
                .like("e_name", "老师")
                .or() // 部分SQL语句  FROM tbl_emp WHERE (sal BETWEEN ? AND ? AND e_name LIKE ? OR job LIKE ?)
                .like("job", "a")
        );
        System.out.println(list);

使用QueryWrapper完成带条件的修改

        //修改empno为14,e_name为zhangsan老师的job为teacher
        Emp emp = new Emp();
        emp.setJob("teacher");

        int i = empDao.update(emp, new QueryWrapper<Emp>()
                .eq("empno", 14)
                .eq("e_name","zhangsan老师")
        );
        System.out.println();
        System.out.println(i);

带条件的删除

        //删除job为IT,sal6000~70000的记录
        empDao.delete(new QueryWrapper<Emp>()
                .eq("job","it")
                .between("sal",6000,7000)
        );

5、代码生成器

​ 1、MyBatis-plus是根据java代码开生成代码的;而Mybatis是根据XML文件的配置来生成的

​ 2、MyBatis-plus能够生成实体类、Mapper接口、Mapper映射文件,Service层,Controller层;而Mybatis只能生成实体类,Mapper接口,Mapper映射文件

1、添加依赖

添加代码生成器依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.1.tmp</version>
</dependency>

添加 模板引擎 依赖,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>

2、编写生成类

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();
    }
}

​ 生成后需要导入spring-web的依赖。因为之前没导入。

​ 注意,当通过上述代码实现之后,大家发现可以在Controller层可以直接实现调用,这些调用的实现最核心的功能就在于ServiceImpl类,这个类中自动完成mapper的注入,同时提供了一系列CRUD的方法

6、插件扩展

插件机制

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()方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理。

1、分页插件

在spring.xml的sqlSessionFactoryBean添加如下配置引入插件

        <!--注册插件-->
        <property name="plugins">
            <array>
                <!--注册分页插件-->
                <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></bean>
            </array>
        </property>
<!--可以把之前在mybatis全局配置文件配置的插件注释,在spring.xml配置插件-->
	@Test
    public void TestPage(){
        Page page = new Page(1,2);
        Page selectPage = empDao.selectPage(page, null);
        List<Emp> records = selectPage.getRecords();
        System.out.println();
        for (Emp e : records){
            System.out.println(e);
        }

        System.out.println("===========================");
        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);
    }

2、乐观锁插件

当要更新一条记录的时候,希望这条记录没有被别人更新

乐观锁实现方式:

取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = yourVersion+1 where version = yourVersion
如果version不对,就更新失败

添加配置:

<!--注册乐观锁插件-->
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"></bean>

修改实体类添加version字段、@Version注解、添加setter、getter方法并在表中添加version字段,案例中表version字段值都设置1

    @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);
    }

在这里插入图片描述

3、SQL执行分析插件

该插件的作用是分析 DELETE、UPDATE 语句,防止小白或者恶意进行 DELETE、UPDATE 全表更新或者删除操作。在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句, 根据结果集中的 Extra 列来断定当前是否全表操作。

SQL 执行分析拦截器,只支持 MySQL5.6.3 以上版本 。

            <!--注册执行分析插件-->
                <!-- 执行分析插件 只建议在开发环境中使用,不建议在生产环境使用 -->
                <bean class="com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor">
                    <property name="sqlParserList">
                        <list>
                            <!-- 禁止全表删除-->
                            <bean   class="com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser"></bean>
                        </list>
                    </property>
                </bean>
@Test
public void testSqlExplain(){
    int delete = empDao.delete(null);  //全表删除
    System.out.println(delete);
}

控制台报错:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of full table deletion
### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of full table deletion

7、SQL注入器

根据MybatisPlus 的 DefaultSqlInjector 和 AbstractMethod 可以自定义各种你想要的 sql ,在加载 mybatis 环境时就注入到全局中,相当于自定义 Mybatisplus 自动注入的方法(像BaseMapper的内置方法)。

步骤:

分别继承 DefaultSqlInjector和 AbstractMethod:

1、在 Mapper 接口中定义相关的 CRUD 方法

2、扩展 AbstractMethod 的 injectMappedStatement 方法,实现 Mapper 接口中方法要注入的 SQL

3、扩展 DefaultSqlInjector ,重写 getMethodList 方法,添加自定义方法

4、修改applicationContext.xml文件,在 MP 全局策略中,配置自定义注入器

EmpDao类

package study.dao;

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

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

}
   @Test
    public void testInjector(){
        int ret = empDao.deleteAll();
        System.out.println(ret);
    }
//测试前需要把SQL执行分析插件注释掉

8、公共字段填充

metaobject: 元对象,是 Mybatis 提供的一个用于更加方便,更加优雅的访问对象的属性,给对象的属性设置值 的一个对象. 还会用于包装对象. 支持对 Object 、 Map、 Collection等对象进行包装。

本质上 metaObject 获取对象的属性值或者是给对象的属性设置值,最终是要通过 Reflector 获取到属性的对应方法的 Invoker, 最终 invoke。

步骤:

  • 注解填充字段 @TableFile(fill = FieldFill.INSERT)
  • 自定义公共字段填充处理器MetaObjectHandler
  • MP 全局注入 自定义公共字段填充处理器

1、添加 @TableFile注解

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String job;

2、自定义公共字段填充处理器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(推荐使用)
    }
}

3、MP 全局注入 自定义公共字段填充处理器

    <bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        <property name="dbConfig" ref="dbConfig"></property>
        <!--自定义公共字段填充-->
        <property name="metaObjectHandler" ref="myMeta"></property>
    </bean>
    <!--注入自定义公共字段填充-->
    <bean id="myMeta" class="study.metaObjectHandler.myMetaObjectHandler"></bean>
    @Test
    public void testMeta(){
        int insert = empDao.insert(new Emp());
        System.out.println(insert);
    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值