MyBatis Plus 笔记

第一部分 Mybatis-Plus 概念

1.1 Mybatis-Plus 介绍

可以先看下MyBatis笔记
Mybatis-Plus 介绍 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简 化开发、提高 效率而生。

官网: https://mp.baomidou.com/

1.2 特性
  • 无侵入 :只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小 :启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作 :内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用 :通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成 :支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式 :支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作 :支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器 :采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件 :基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库 :支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件 :可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件 :提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
1.3 支持数据库

任何能使用 mybatis 进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下,如果不在下列表查看分页部分教程 PR 您的支持。

  • mysql,oracle,db2,h2,hsql,sqlite,postgresql,sqlserver,Phoenix,Gauss ,clickhouse,Sybase,OceanBase,Firebird,cubrid,goldilocks,csiidb
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
1.4 框架结构

image.png

1.5 代码托管

Gitee (opens new window) | Github(opens new window)

第二部分 快速开始

1.1 基础数据库环境

创建 db 名为 mp

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);


INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

对于 Mybatis 整合 MP 有常常有三种用法,分别是 Mybatis+MP、Spring+Mybatis+MP、Spring Boot+Mybatis+MP。

image.png

1.2 MyBatis 快速开始

代码结构

使用依赖传递先建立上层工程 mybatis-pluse 引入依赖,再建立子模块

image.png

父依赖

<?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>com.galaxy</groupId>
    <artifactId>mybatis-plus</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>mybatis-demo</module>
    </modules>

    <dependencies>
    <!-- mybatis-plus插件依赖 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus</artifactId>
        <version>3.4.0</version>
    </dependency>

    <!--Mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>

    <!--连接池-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.11</version>
    </dependency>

    <!--简化bean代码的工具包-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.4</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.4</version>
    </dependency>

</dependencies>

<build>
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>11</source>
            <target>11</target>
        </configuration>
    </plugin>
</plugins>
</build>

</project>

子模块 sqlMapConfig.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>

    <!--加载外部的properties文件-->
    <properties resource="jdbc.properties"></properties>

    <!--给实体类的全限定类名给别名-->
    <typeAliases>
        <!--给单独的实体起别名-->
        <!--  <typeAlias type="com.lagou.pojo.User" alias="user"></typeAlias>-->
        <!--批量起别名:该包下所有的类的本身的类名:别名还不区分大小写-->
        <package name="com.galaxy.pojo"/>
    </typeAliases>

    <!--environments:运行环境-->
    <environments default="development">
        <environment id="development">
            <!--当前事务交由JDBC进行管理-->
            <transactionManager type="JDBC"></transactionManager>
            <!--当前使用mybatis提供的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--引入映射配置文件-->
    <mappers>
<!--        <mapper resource="UserMapper.xml"></mapper> -->
    <package name="com.galaxy.mapper"/>
    </mappers>
</configuration>

数据库配置信息

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root

日志配置文件 log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout

查询 mapper UserMapper.xml

注意位置和接口 UserMapper 同位置,因为是 package 扫描

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.galaxy.mapper.UserMapper">

    <select id="findAll" parameterType="user" resultType="user">
        select  * from user
    </select>

</mapper>

实体类 User

package com.galaxy.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;


}

UserMapper

package com.galaxy.mapper;

import com.galaxy.pojo.User;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
public interface UserMapper {


    List<User> findAll();
}

MPTest

package com.galaxy.test;

import com.galaxy.mapper.UserMapper;
import com.galaxy.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author lane
 * @date 2021年10月16日 下午5:28
 */
public class MPTest {


    @Test
    public void testMysql() throws IOException {

        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.findAll();
        for (int i = 0; i < users.size(); i++) {
            User user =  users.get(i);
            System.out.println(user);
        }

    }
}

测试结果

17:36:39,995 DEBUG findAll:137 - ==>  Preparing: select * from user
17:36:40,042 DEBUG findAll:137 - ==> Parameters: 
17:36:40,084 DEBUG findAll:137 - <==      Total: 5
User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)
1.3 MyBatis 整合 MyBatis Plus

整合步骤

  1. UserMaper 继承 BaseMapper
  2. MybatisSqlSessionFactoryBuilder 替换 SqlSessionFactoryBuilder
  3. 如果用户表与类名不一致添加注解 @TableName(“user”)

具体操作

user

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
  
}

UserMapper


/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
public interface UserMapper extends BaseMapper<User> {


    List<User> findAll();
}

test

 @Test
    public void testMysqlMp() throws IOException {

        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sessionFactory = new MybatisSqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//        List<User> users = mapper.findAll();
        List<User> users = mapper.selectList(null);
        users.forEach(user -> {
            System.out.println(user);
        });

    }

测试结果

18:23:44,369 DEBUG selectList:137 - ==>  Preparing: SELECT id,name,age,email FROM user
18:23:44,421 DEBUG selectList:137 - ==> Parameters: 
18:23:44,454 DEBUG selectList:137 - <==      Total: 5
User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)

BaseMapper 方法

image.png

1.4 Spring 整合 MyBatis Plus

创建子模块 mybatis-plus-spring

引入了 Spring 框架,数据源、构建等工作就交给了 Spring 管理。

模块结构

image.png

依赖

<?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">
    <parent>
        <artifactId>mybatis-plus</artifactId>
        <groupId>com.galaxy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis-plus-spring</artifactId>

    <properties>
        <spring.version>5.1.6.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

applicationContext.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"
       xsi:schemaLocation="
       	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.xsd">

    <!-- 引入properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--1. 将sqlSessionFactory对象的创建交给spring-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:sqlMapConfig.xml"/>
    </bean>

    <!--2. mapper映射扫描-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.galaxy.mapper"/>
    </bean>


</beans>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout

sqlMapConfig.xml(可以去掉,但是注意 sql)

<?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>
    <!--给实体类的全限定类名给别名-->
    <typeAliases>
        <!--给单独的实体起别名-->
        <!--  <typeAlias type="com.lagou.pojo.User" alias="user"></typeAlias>-->
        <!--批量起别名:该包下所有的类的本身的类名:别名还不区分大小写-->
        <package name="com.galaxy.pojo"/>
    </typeAliases>
</configuration>

UserMapper.xml (注意位置,可以去掉,如果只是单纯的 mp 够用的话)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.galaxy.mapper.UserMapper">

    <select id="findAll" parameterType="user" resultType="user">
        select  * from user
    </select>

</mapper>

User

package com.galaxy.pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;

}

UserMapper

package com.galaxy.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.galaxy.pojo.User;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
public interface UserMapper extends BaseMapper<User> {
    List<User> findAll();

}

测试用例

package com.galaxy.test;

import com.galaxy.mapper.UserMapper;
import com.galaxy.pojo.User;
import lombok.AllArgsConstructor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月16日 下午6:45
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringMPTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public  void springMPTest(){

        List<User> users = userMapper.selectList(null);
        users.forEach(user -> {
            System.out.println(user);
        });

    }

    @Test
    public  void springMPTest2(){

        List<User> users = userMapper.findAll();
        users.forEach(user -> {
            System.out.println(user);
        });

    }
}

还记得 Spring 的 测试

package com.galaxy.test;

import com.galaxy.mapper.UserMapper;
import com.galaxy.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月16日 下午7:05
 */
public class MainTest {


    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserMapper userMapper = applicationContext.getBean(UserMapper.class);
        List<User> users = userMapper.selectList(null);
        for (int i = 0; i < users.size(); i++) {
            System.out.println(users.get(i));
        }

    }
  
}

测试结果

19:03:35,919 DEBUG selectList:137 - ==>  Preparing: SELECT id,name,age,email FROM user
19:03:35,959 DEBUG selectList:137 - ==> Parameters: 
19:03:35,985 DEBUG selectList:137 - <==      Total: 5
19:03:35,986 DEBUG SqlSessionUtils:49 - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@27f9e982]
User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)
1.5 Spring Boot 整合 MyBatis Plus

创建 spring boot 项目

image.png

依赖手动添加

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.galaxy</groupId>
	<artifactId>mybatis-plus-springboot</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>mybatis-plus-springboot</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<!--简化代码的工具包-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<!--mybatis-plus的springboot支持-->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.1.1</version>
		</dependency>
		<!--mysql驱动-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.47</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
			<scope>test</scope>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

application.properties


spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

# \u52A0\u8F7D\u5168\u5C40\u914D\u7F6E\u6587\u4EF6
#mybatis-plus.config-location=classpath:sqlMapConfig.xml

# \u52A0\u8F7D\u6620\u5C04\u914D\u7F6E\u6587\u4EF6
mybatis-plus.mapper-locations=classpath*:mapper/*.xml

# \u8D77\u522B\u540D
mybatis-plus.type-aliases-package=com.galaxy.pojo

log4j.properties

log4j.rootLogger=info,A1

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n
log4j.logger.com.galaxy.mapper=TRACE

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.galaxy.mapper.UserMapper">

    <select id="findById" resultType="user">
     	 select * from user where id = #{id}
    </select>

</mapper>

启动类

package com.galaxy;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.galaxy.mapper")
public class MybatisPlusSpringbootApplication {

	public static void main(String[] args) {
		SpringApplication.run(MybatisPlusSpringbootApplication.class, args);
	}

}

user

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;

}

UserMapper

package com.galaxy.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.galaxy.pojo.User;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
public interface UserMapper extends BaseMapper<User> {


//    List<User> findAll();
    User findById(int id);
}

测试类

package com.galaxy.mybatisplusspringboot;

import com.galaxy.mapper.UserMapper;
import com.galaxy.pojo.User;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
class MybatisPlusSpringbootApplicationTests {

	@Autowired
	private UserMapper userMapper;
	@Test
	public  void testSpringbootMP(){

		List<User> users = userMapper.selectList(null);
		users.forEach(user -> System.out.println(user));
		System.out.println(userMapper.findById(1));
	}
}

测试结果

User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)
User(id=1, name=Jone, age=18, email=test1@baomidou.com)

第三部分 通用 CRUD

通过继承 BaseMapper 就可以获取到各种各样的单表操作,接下来我们将 详细讲解这些操作。

项目是在 Spring Boot 整合 MyBatis Plus 的基础上进行测试 CRUD

image.png

1.1 插入操作

直接调用即可

package com.galaxy.mybatisplusspringboot;

import com.galaxy.mapper.UserMapper;
import com.galaxy.pojo.User;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
class MybatisPlusSpringbootApplicationTests {

	@Autowired
	private UserMapper userMapper;
	 
	@Test
	public  void testInsert(){

		User user = new User();
		user.setAge(17);
		user.setEmail("lane.d@outlook.com");
		user.setName("lane");
		int i = userMapper.insert(user);
		System.out.println("插入行数为"+i);
		//MP会在插入之后为我们添加ID
		System.out.println("user id :"+user.getId());

	}
}

测试结果

插入行数为1
user id :1449560388239454210

修改主键生成策略

先修改数据库表 ID 为自动增长
在这里插入图片描述

修改实体类用户 ID 设置为 auto,也可以选择其他类型

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;

}

先删除刚才的数据,因为 ID 不正确,不然会报错

再次执行测试后结果,ID 自动增长为 6

image.png

1.2 @TableField 注解

在 MP 中通过 @TableField 注解可以指定字段的一些属性,常常解决的问题有 2 个:

1、对象中的属性名和字段名不一致的问题(非驼峰)

2、对象中的属性字段在表中不存在的问题

修改用户实体类为


/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    @TableField(select = false) //查询的时候,不返回该字段的值
    private Integer age;
    @TableField(value = "email") //数据库字段名不一致,mail 的数据库字段为 email
    private String mail;
    @TableField(exist = false) //数据库字段不存在n 
    private String address;

}

测试下

@Test
	public  void testSpringbootMP(){

		List<User> users = userMapper.selectList(null);
		users.forEach(user ->
				System.out.println(user));

		System.out.println(userMapper.findById(1));

	}

测试结果

1、不报错了

2、age 为 null mail 也可以查出来了,address 为 null

3、不影响自已定义的 SQL 查询结果,但是字段不一致还是不会有数据的如 mail 的数据库字段为 email

image.png

1.3 更新操作

在 MP 中,更新操作有 2 种,一种是根据 id 更新,另一种是根据条件更新。

根据 id 更新

/**
	 * 测试更新ById
	 * @author lane
	 * @date 2021/10/17 上午10:56
	 */
	@Test
	public  void testUpdateById(){

		User user = new User();
		//更新内容
		user.setAge(21);
		user.setName("lane2");
		//ID
		user.setId(6l);
		int i = userMapper.updateById(user);
		System.out.println("更新行数为"+i);
		//MP会在插入之后为我们添加ID
		System.out.println("user id :"+user.getId());

	}

测试结果

image.png

根据条件更新

queryWrapper

/**
	 * 测试更新
	 * @author lane
	 * @date 2021/10/17 上午10:56
	 */
	@Test
	public  void testUpdateCondition(){

		User user = new User();
		//更新内容
		user.setAge(23);
		user.setName("lane3");
		//更新条件
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("id", 6);
		int i = userMapper.update(user, queryWrapper);
		System.out.println("行数为"+i);
		//MP会在插入之后为我们添加ID
		System.out.println("user name :"+user.getName());

	}
}

测试结果

在这里插入图片描述

UpdateWrapper

@Test
	public  void testUpdateCondition2(){


		//更新的条件以及字段
		UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
		updateWrapper.eq("id", 6)
				.set("name","lane4")
				.set("age",24);
		int i = userMapper.update(null, updateWrapper);
		System.out.println("行数为"+i);

	}

测试结果

image.png

1.4 删除操作

四种删除方法

    int deleteById(Serializable id);

    int deleteByMap(@Param("cm") Map<String, Object> columnMap);

    int delete(@Param("ew") Wrapper<T> wrapper);

    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

测试用例

/**
	 *
	 * 测试四种删除方法
	 * @author lane
	 * @date 2021/10/17 下午3:11
	 */
	@Test
	public void testDelete(){

		//deleteById
		int i = userMapper.deleteById(6l);

		//deleteByMap
		Map<String, Object> map = new HashMap<>();
		//多个之间是and的关系
		map.put("age",27);
		map.put("name","lane27");
		userMapper.deleteByMap(map);

		//delete
		User user = new User();
		user.setName("lane28");
		user.setAge(28);
		QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
		userMapper.delete(queryWrapper);

		//deleteBatchIds
		userMapper.deleteBatchIds(Arrays.asList(10,11));

	}

测试结果

删除之前先添加几条数据


INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com'),
(6, 'lane26', 26, 'lane26@outlook.com'),
(7, 'lane27', 27, 'lane27@outlook.com'),
(8, 'lane28', 28, 'lane28@outlook.com'),
(9, 'lane6', 29, 'lane29@outlook.com'),
(10, 'lane6', 29, 'lane29@outlook.com'),
(11, 'lane6', 29, 'lane29@outlook.com');

image.png

运行之后

image.png

image.png

1.5 查询操作

MP 提供了多种查询操作,包括根据 id 查询、批量查询、查询单条数据、查询列表、分页查询等操作。

测试方法

/**
	 * 测试查询
	 * @author lane
	 * @date 2021/10/17 下午3:40
	 */
	@Test
	public void testSelect(){
		System.out.println("selectById");
		//selectById 根据 ID 查询
		User user = userMapper.selectById(3);
		System.out.println(user);
		System.out.println("selectBatchIds");
		//selectBatchIds
		//查询(根据ID 批量查询) @param idList 主键ID列表(不能为 null 以及 empty)
		List<User> users = userMapper.selectBatchIds(Arrays.asList(4, 5));
		users.forEach(user1 -> System.out.println(user1));
		System.out.println("selectByMap");
		//selectByMap
		Map<String, Object> map = new HashMap<>();
		//多个之间是and的关系
		map.put("age",27);
		map.put("name","lane27");
		List<User> usersMap = userMapper.selectByMap(map);
		usersMap.forEach(user1 -> System.out.println(user1));
		System.out.println("selectList");
		//selectList
		//根据 entity 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类(可以为 null)
		QueryWrapper<User> queryWrapper = new QueryWrapper();
		queryWrapper.gt("age", 27);//age 大于27
		List<User> usersWrapper = userMapper.selectList(queryWrapper);
		usersWrapper.forEach(user1 -> System.out.println(user1));
		System.out.println("selectCount");
		//selectCount
		//根据 Wrapper 条件,查询总记录数 * * @param queryWrapper 实体对象封装操作类(可以为 null)
		Integer count = userMapper.selectCount(queryWrapper);
		System.out.println(count);
		System.out.println("selectOne");
		//selectOne
		//根据 entity 条件,查询一条记录 * * @param queryWrapper 实体对象封装操作类(可以为 null)
		QueryWrapper<User> queryWrapper2 = new QueryWrapper();
		queryWrapper2.eq("name", "Jack");
		User user1 = userMapper.selectOne(queryWrapper2);
		System.out.println(user1);
	}

测试结果

selectById
User(id=3, name=Tom, age=28, mail=test3@baomidou.com, address=null)
selectBatchIds
User(id=4, name=Sandy, age=21, mail=test4@baomidou.com, address=null)
User(id=5, name=Billie, age=24, mail=test5@baomidou.com, address=null)
selectByMap
User(id=7, name=lane27, age=27, mail=lane27@outlook.com, address=null)
selectList
User(id=3, name=Tom, age=28, mail=test3@baomidou.com, address=null)
User(id=8, name=lane28, age=28, mail=lane28@outlook.com, address=null)
User(id=9, name=lane6, age=29, mail=lane29@outlook.com, address=null)
User(id=10, name=lane6, age=29, mail=lane29@outlook.com, address=null)
User(id=11, name=lane6, age=29, mail=lane29@outlook.com, address=null)
selectCount
5
selectOne
User(id=2, name=Jack, age=20, mail=test2@baomidou.com, address=null)
1.6 分页查询

根据 selectPage 方法进行分页查询,需要先配置下分页插件的拦截器

方法定义

/** 
* 根据 entity 条件,查询全部记录(并翻页) 
* 
* @param page 分页查询条件(可以为 RowBounds.DEFAULT) 
* @param queryWrapper 实体对象封装操作类(可以为 null) 
*/ IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

拦截器配置

spring boot 方式如下


/**
 * @author lane
 * @date 2021年10月17日 下午4:14
 */
@Configuration
public class MybatisPlusConfig {

    /** 分页插件拦截器
     * @author lane
     * @date 2021/10/17 下午4:15
     * @return com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

若仅仅对于 MyBatis 配置如下 sqlMapConfig.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>
    <plugins>
        <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin>
    </plugins>

</configuration>

测试方法

/**
	 * 分页查询
	 * @author lane
	 * @date 2021/10/17 下午4:25
	 */
	@Test
	public void testPage(){

		QueryWrapper<User> queryWrapper = new QueryWrapper();
		queryWrapper.gt("age", 18);
		queryWrapper.orderByAsc("age");
		//分页信息 当前页面,显示条数
		Page<User> page = new Page<User>(1,2);
		IPage<User> userIPage = userMapper.selectPage(page, queryWrapper);
		System.out.println("当前页 "+userIPage.getCurrent());
		System.out.println("总条数 "+userIPage.getTotal());
		System.out.println("总页数 "+userIPage.getPages());
		System.out.println("信息 "+userIPage.getRecords());


	}

测试结果

[main] [com.galaxy.mapper.UserMapper.selectPage]-[DEBUG] ==>  Preparing: SELECT COUNT(1) FROM user WHERE age > ? 
[main] [com.galaxy.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 18(Integer)
[main] [com.galaxy.mapper.UserMapper.selectPage]-[DEBUG] ==>  Preparing: SELECT id,name,age,email AS mail FROM user WHERE age > ? ORDER BY age ASC LIMIT ?,? 
[main] [com.galaxy.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 18(Integer), 0(Long), 2(Long)
[main] [com.galaxy.mapper.UserMapper.selectPage]-[DEBUG] <==      Total: 2
当前页 1
总条数 10
总页数 5
信息 
[User(id=2, name=Jack, age=20, mail=test2@baomidou.com, address=null), 
User(id=4, name=Sandy, age=21, mail=test4@baomidou.com, address=null)]

1.7 SQL 注入原理

MP 在启动后会将 BaseMapper 中的一系列的方法注册到 meppedStatements 中

在 MP 中,ISqlInjector 负责 SQL 的注入工作,它是一个接口,AbstractSqlInjector 是它的实现类,实现关 系如下:

image.png

在 AbstractSqlInjector 中,主要是由 inspectInject()方法进行注入的

最终调用抽象方法 injectMappedStatement 进行真正的注入:

public enum SqlMethod {
    INSERT_ONE("insert", "插入一条数据(选择字段插入)", "<script>\nINSERT INTO %s %s VALUES %s\n</script>"),
    DELETE_BY_ID("deleteById", "根据ID 删除一条数据", "<script>\nDELETE FROM %s WHERE %s=#{%s}\n</script>"),
    DELETE_BY_MAP("deleteByMap", "根据columnMap 条件删除记录", "<script>\nDELETE FROM %s %s\n</script>"),
    DELETE("delete", "根据 entity 条件删除记录", "<script>\nDELETE FROM %s %s\n</script>"),
    DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量删除数据", "<script>\nDELETE FROM %s WHERE %s IN (%s)\n</script>"),
    LOGIC_DELETE_BY_ID("deleteById", "根据ID 逻辑删除一条数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    LOGIC_DELETE_BY_MAP("deleteByMap", "根据columnMap 条件逻辑删除记录", "<script>\nUPDATE %s %s %s\n</script>"),
    LOGIC_DELETE("delete", "根据 entity 条件逻辑删除记录", "<script>\nUPDATE %s %s %s\n</script>"),
    LOGIC_DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量逻辑删除数据", "<script>\nUPDATE %s %s WHERE %s IN (%s) %s\n</script>"),
    UPDATE_BY_ID("updateById", "根据ID 选择修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    UPDATE_ALL_COLUMN_BY_ID("updateAllColumnById", "根据ID 选择修改数据", "<script>\nUPDATE %s SET %s WHERE %s=#{%s} %s\n</script>"),
    UPDATE("update", "根据 whereEntity 条件,更新记录", "<script>\nUPDATE %s %s %s\n</script>"),
    LOGIC_UPDATE_BY_ID("updateById", "根据ID 修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s}"),
    SELECT_BY_MAP("selectByMap", "根据columnMap 查询一条数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>\nSELECT %s FROM %s WHERE %s IN (%s)\n</script>"),
    SELECT_ONE("selectOne", "查询满足条件一条数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_COUNT("selectCount", "查询满足条件总记录数", "<script>\nSELECT COUNT(%s) FROM %s %s\n</script>"),
    SELECT_LIST("selectList", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_MAPS("selectMaps", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    LOGIC_SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s"),
    LOGIC_SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>\nSELECT %s FROM %s WHERE %s IN (%s) %s\n</script>");
}

第四部分 配置信息

1.1 基本配置

在 MP 中有大量的配置,其中有一部分是 Mybatis 原生的配置,另一部分是 MP 的配置,详情:

https://baomidou.com/config/

configLocation

MyBatis 配置文件 sqlMapConfig.xml 位置

Spring Boot:

mybatis-plus.config-location = classpath:sqlMapConfig.xml

Spring MVC:

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
 <property name="configLocation" value="classpath:sqlMapConfig.xml"/> 
</bean>

mapperLocations

MyBatis Mapper 所对应的 XML 文件位置如 resources/mapper/ UserMapper.xml

Spring Boot:

# Mapper 自定义SQL所对应的 XML文件位置
#classpath* 和classpath区别是包括所有的资源二classpath只包括当前项目
mybatis-plus.mapper-locations=classpath*:mapper/*.xml

Spring MVC:

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
 <property name="mapperLocations" value="classpath*:mybatis/*.xml"/> 
</bean>

Maven 多模块项目的扫描路径需以 classpath*: 开头 (即加载多个 jar 包下的 XML 文件)

测试下 UserMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.galaxy.mapper.UserMapper">

    <select id="findById" resultType="user">
     	 select * from user where id = #{id}
    </select>

</mapper>

typeAliasesPackage

MyBaits 别名包扫描路径,通过该属性可以给包中的类注册别名,注册后在 Mapper 对应的 XML 文件 中可以直接使用类名,而不用使用全限定的类名(即 XML 中调用的时候不用包含包名)。

Spring Boot:

#实体类起别名
mybatis-plus.type-aliases-package=com.galaxy.pojo

Spring MVC:

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> 
<property name="typeAliasesPackage" value="com.baomidou.mybatisplus.samples.quickstart.entity"/> 
</bean>
1.2 进阶配置

mapUnderscoreToCamelCase

是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到 经典 Java 属性名 aColumn(驼峰命名) 的类似映射。

column: user_name

property :userName

则无需使用 @TableField 注解指定数据库字段名,默认 MP 开启自动驼峰

注意:

此属性在 MyBatis 中原默认值为 false,在 MyBatis-Plus 中为 true

SpringBoot:

#关闭自动驼峰映射,该参数不能和mybatis-plus.config-location同时存在
mybatis-plus.configuration.map-underscore-to-camel-case=false

cacheEnabled

全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true。

spring boot:

mybatis-plus.configuration.cache-enabled=false

idType

全局默认主键类型,设置后,即可省略实体对象中的 @TableId(type = IdType.AUTO)配置

SpringBoot:

mybatis-plus.global-config.db-config.id-type=auto

SpringMVC:

<!--这里使用MP提供的sqlSessionFactory,完成了Spring与MP的整合-->

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="globalConfig"> 
<bean class="com.baomidou.mybatisplus.core.config.GlobalConfig"> 
<property name="dbConfig"> <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"> 
<property name="idType" value="AUTO"/> 
</bean> 
</property> 
</bean>
</property>
</bean>

tablePrefix

表名前缀,全局配置后可省略 @TableName()配置。

SpringBoot:

mybatis-plus.global-config.db-config.table-prefix=tb_

SpringMVC:

<bean id="sqlSessionFactory"

class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

<property name="dataSource" ref="dataSource"/>

<property name="globalConfig">

<bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">

<property name="dbConfig">

<bean

class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">

<property name="idType" value="AUTO"/>

<property name="tablePrefix" value="tb_"/>

</bean> </property>

</bean>

</property> </bean>

第五部分 条件构造器

1.1 allEq
allEq(Map<R, V> params) 
allEq(Map<R, V> params, boolean null2IsNull) 
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)

测试用例

/**
	 * 测试allEq
	 * @author lane
	 * @date 2021/10/17 下午7:11
	 */
	@Test
	public void testAllEq(){

		Map<String,Object> map = new HashMap<>();
		map.put("age",27);
		map.put("name","lane27");
	    map.put("email",null);
		QueryWrapper<User> queryWrapper = new QueryWrapper();
		//条件查询
		queryWrapper.allEq(map);//WHERE name = ? AND age = ? AND email IS NULL
		//为false时候忽略条件中的null值
		queryWrapper.allEq(map,false);//where name = ? AND age = ?
		//condition为true时候才进行条件查询
//		queryWrapper.allEq(true,map,true);
		//SELECT id,name,age,email AS mail FROM user WHERE name = ? AND age = ? AND email IS NULL
		List<User> users = userMapper.selectList(queryWrapper);
		users.forEach(user -> System.out.println(user));

	}

1.2 基本比较操作

eq

等于 =

ne

不等于 <>

gt

大于 >

ge

大于等于 >=

lt

小于 <

le

小于等于 <=

between

BETWEEN 值 1 AND 值 2

notBetween

NOT BETWEEN 值 1 AND 值 2

in 字段 IN (value.get(0), value.get(1), …)

notIn 字段 NOT IN (v0, v1, …)

测试代码

/**
	 * 测试基本条件
	 * @author lane
	 * @date 2021/10/17 下午7:11
	 */
	@Test
	public void testCondition(){

		QueryWrapper<User> queryWrapper = new QueryWrapper();
		//条件查询
		queryWrapper.gt("age",18 )
				.eq("email", "lane29@outlook.com")
				.in("name", "lane28","lane6")
				.orderByAsc("id");
		List<User> users = userMapper.selectList(queryWrapper);
		users.forEach(user -> System.out.println(user));

	}

测试结果

[main] [com.galaxy.mapper.UserMapper.selectList]-[DEBUG] ==>  Preparing: SELECT id,name,age,email AS mail FROM user WHERE age > ? AND email = ? AND name IN (?,?) ORDER BY id ASC 
[main] [com.galaxy.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: 18(Integer), lane29@outlook.com(String), lane28(String), lane6(String)
[main] [com.galaxy.mapper.UserMapper.selectList]-[DEBUG] <==      Total: 3
User(id=9, name=lane6, age=29, mail=lane29@outlook.com, address=null)
User(id=10, name=lane6, age=29, mail=lane29@outlook.com, address=null)
User(id=11, name=lane6, age=29, mail=lane29@outlook.com, address=null)
1.3 模糊查询

like

LIKE ‘% 值 %’ 例: like(“name”, “王”)

—> name like ‘% 王 %’

notLike

NOT LIKE ‘% 值 %’ 例: notLike(“name”, “王”)

—> name not like ‘% 王 %’

likeLeft

LIKE ‘% 值’ 例: likeLeft(“name”, “王”)

—> name like ‘% 王’

likeRight

LIKE ‘值 %’ 例: likeRight(“name”, “王”)

—> name like ‘王 %’

1.4 排序

orderBy

排序:ORDER BY 字段, …

例: orderBy(true, true, “id”, “name”)

—> order by id ASC,name ASC

orderByAsc

排序:ORDER BY 字段, … ASC 例: orderByAsc(“id”, “name”)

—> order by id ASC,name ASC

orderByDesc

排序:ORDER BY 字段, … DESC 例: orderByDesc(“id”, “name”)

—> order by id DESC,name DESC

1.5 逻辑查询

or

queryWrapper.eq(“age”, 28).or().eq(“age”,“18”);

and

queryWrapper.eq(“name”, “Jack”).eq(“age”,“18”);

1.6 select

在 MP 查询中,默认查询所有的字段,如果有需要也可以通过 select 方法进行指定字段。

测试代码

/**
	 * 测试sort or select
	 * @author lane
	 * @date 2021/10/17 下午7:11
	 */
	@Test
	public void testOr(){

		QueryWrapper<User> queryWrapper = new QueryWrapper();
		//条件查询or  WHERE age = ? OR age = ?
		queryWrapper.eq("age", 28).or().eq("age","18");
		//or() desc select
		// SELECT name,age FROM user WHERE age = ? OR age = ? ORDER BY age DESC
		queryWrapper.eq("age", 28).or()
				.eq("age","18")
				.orderByDesc("age")
				.select("name","age");
		List<User> users = userMapper.selectList(queryWrapper);
		users.forEach(user -> System.out.println(user));

	}

第六部分 ActiveRecord

1.1 什么是 ActiveRecord

ActiveRecord 属于 ORM(对象关系映射)层,由 Rails 最早提出,遵循标准的 ORM 模型:表映射 到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快 速实现模型的操作,而且简洁易懂。

ActiveRecord 的主要思想是:

每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常 表的每个字段在类中都有相应的 Field; ActiveRecord 同时负责把自己持久化,在 ActiveRecord 中封装了对数据库的访问,即 CURD;; ActiveRecord 是一种领域模型(Domain Model),封装了部分业务逻辑;

1.2 开启 AR 之旅

在 MP 中,开启 AR 非常简单,只需要将实体对象继承 Model 即可。Mapper 继承 BaseMapper 接口

代码实现

User

/**
 * @author lane
 * @date 2021年10月16日 下午4:45
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User extends Model<User> {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
//    @TableField(select = false) //不想查出该值
    private Integer age;
    @TableField(value = "email") //数据库字段名不一致
    private String mail;
    @TableField(exist = false) //数据库字段不存在
    private String address;

}

测试代码

package com.galaxy.mybatisplusspringboot;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.galaxy.pojo.User;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月18日 上午10:28
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestAR {

    /*
          在AR模式下,完成根据主键查询
       */
    @Test
    public void testARSelectById(){

        User user = new User();
        user.setId(12L);

        User user1 = user.selectById();
        System.out.println(user1);

    }


    /*
        在AR模式下,完成添加操作
    */
    @Test
    public void testARInsert(){

        User user = new User();
        user.setName("lane18");
        user.setAge(18);
        user.setMail("lane18@outlook.com");

        boolean insert = user.insert();
        System.out.println(insert);

    }


    /*
        在AR模式下,完成更新操作
    */
    @Test
    public void testARUpate(){


        User user = new User();
        User user1 = user.selectById(12L);

        user.setId(12L);
        user.setName("lane12");
        boolean insert = user.updateById();
        System.out.println(insert);

    }

    /*
        在AR模式下,完成删除操作
    */
    @Test
    public void testARDelete(){

        User user = new User();
        //user.setId(16L);

        boolean b = user.deleteById(16L);
        System.out.println(b);
    }


    /*
        在AR模式下,根据条件进行查询
    */
    @Test
    public void testARFindByWrapper(){

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("age","20");

        User user = new User();
        List<User> users = user.selectList(queryWrapper);
        for (User user1 : users) {
            System.out.println(user1);
        }
    }
}

和原先的 mapper 操作几乎一致,注意必须继承接口 BaseMapper 才行,哪怕不使用

第七部分 插件

1.1 MyBatis 自定义插件

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件 来拦截的方法调用包括:

  1. Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  2. ParameterHandler (getParameterObject, setParameters)
  3. ResultSetHandler (handleResultSets, handleOutputParameters)
  4. StatementHandler (prepare, parameterize, batch, update, query)

我们看到了可以拦截 Executor 接口的部分方法,比如 update,query,commit,rollback 等方法,还有 其他接口的一些方法等。

总体概括为:

  1. 拦截执行器的方法
  2. 拦截参数的处理
  3. 拦截结果集的处理
  4. 拦截 Sql 语法构建的处理

代码示例

拦截器插件

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement; 
import org.apache.ibatis.plugin.*;
import java.util.Properties;

@Intercepts({@Signature(

type= Executor.class,

method = "update",

args = {MappedStatement.class,Object.class})})

public class MyInterceptor implements Interceptor {

@Override public Object intercept(Invocation invocation) throws Throwable {

//拦截方法,具体业务逻辑编写的位置

return invocation.proceed(); }

@Override public Object plugin(Object target) {

//创建target对象的代理对象,目的是将当前拦截器加入到该对象中

return Plugin.wrap(target, this); 
}

@Override public void setProperties(Properties properties) { 
//属性设置 
}

}

插件配置

注入到 Spring 容器:

/** * 自定义拦截器 */ 
@Bean 
public MyInterceptor myInterceptor(){ 
return new MyInterceptor(); 
}

或者通过 xml 配置,sqlMapConfig.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> <plugins> 
<plugin interceptor="com.galaxy.plugins.MyInterceptor"></plugin>
 </plugins> 
</configuration>
1.2 MP 执行分析插件

在 MP 中提供了对 SQL 执行的分析的插件

注意:该插件仅适用于开 发环境,不适用于生产环境。

性能分析拦截器,用于输出每条 SQL 语句及其执行时间,可以设置最大执行时间,超过时间会抛出异 常。

SpringBoot 配置:


@Configuration
public class MybatisPlusConfig {

    /*
        分页插件
     */
   /* @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }*/

   /*
        性能分析插件
    */

   @Bean
   public PerformanceInterceptor performanceInterceptor(){

       PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        // 设置sql语句的最大执行时间
       performanceInterceptor.setMaxTime(100);
       // 设置sql是否格式化显示
       performanceInterceptor.setFormat(true);

       return performanceInterceptor;
   }

   /*
         乐观锁插件
    */

   @Bean
   public OptimisticLockerInterceptor optimisticLockerInterceptor(){

       return  new OptimisticLockerInterceptor();
   }

    /*
        自定义的sql注入器
    */

    @Bean
   public MySqlInjector mySqlInjector(){
       return new MySqlInjector();
   }

}

1.3 乐观锁插件

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

乐观锁实现方式:

取出记录时,获取当前 version 更新时,带上这个 version 执行更新时, set version = newVersion where version = oldVersion

如果 version 不对,就更新失败

spring xml:

<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>

spring boot:

@Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { 
return new OptimisticLockerInterceptor(); }

实体类

为表添加 version 字段,并且设置初始值为 1:

需要为实体字段添加 @Version 注解。

第八部分 Sql 注入器

1.1 扩充 BaseMapper 中的方法

MyBaseMapper

package com.galaxy.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.galaxy.pojo.User;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月18日 下午12:01
 */
/*
    通用mapper接口,以后创建其他mapper接口时,不再继承BaseMapper,而是继承MyBaseMapper
 */
public interface MyBaseMapper<T> extends BaseMapper<T> {

    /*
            查询所有用户
    */
    public List<User> findAll();
  
}

FindAll

package com.galaxy.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;

/**
 * @author lane
 * @date 2021年10月18日 下午12:02
 */
public class FindAll extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {

        String sql = "select * from " + tableInfo.getTableName();
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addSelectMappedStatement(mapperClass, "findAll", sqlSource, modelClass, tableInfo);

    }

}

MySqlInjector

package com.galaxy.injector;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;

import java.util.List;

/**
 * @author lane
 * @date 2021年10月18日 下午12:03
 */
/*
    自定义sql注入器
 */
public class MySqlInjector extends DefaultSqlInjector {


    @Override
    public List<AbstractMethod> getMethodList() {

        List<AbstractMethod> methodList = super.getMethodList();
        // 扩充自定义方法
        methodList.add(new FindAll());

        return methodList;
    }
}

MybatisPlusConfig

package com.galaxy.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.galaxy.injector.MySqlInjector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author lane
 * @date 2021年10月17日 下午4:14
 */
@Configuration
public class MybatisPlusConfig {

    /** 分页插件拦截器
     * @author lane
     * @date 2021/10/17 下午4:15
     * @return com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    /*
        性能分析插件
    */

   /* @Bean
    public PerformanceInterceptor performanceInterceptor(){

        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        // 设置sql语句的最大执行时间
        performanceInterceptor.setMaxTime(100);
        // 设置sql是否格式化显示
        performanceInterceptor.setFormat(true);

        return performanceInterceptor;
    }*/

   /*
         乐观锁插件
    */

  /*  @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){

        return  new OptimisticLockerInterceptor();
    }*/

    /*
        自定义的sql注入器
    */

    @Bean
    public MySqlInjector mySqlInjector(){
        return new MySqlInjector();
    }
}

第九部分 自动填充功能

有些时候我们可能会有这样的需求,插入或者更新数据时,希望有些字段可以自动填充数据,比如密 码、version 等。在 MP 中提供了这样的功能,可以实现自动填充。

1.1 添加 @TableField 注解
@TableField(fill = FieldFill.INSERT) 
//插入数据时进行填充 
private String version;

FieldFill 提供了多种模式选择:

public enum FieldFill {

/** * 默认不处理 */ DEFAULT, /** * 插入时填充字段 */ INSERT,
 /** * 更新时填充字段 */ UPDATE, /** * 插入和更新时填充字段 */ INSERT_UPDATE

}
1.2 编写 MyMetaObjectHandler
package com.galaxy.handler;

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

/**
 * @author lane
 * @date 2021年10月18日 下午12:17
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {


    @Override
    public void insertFill(MetaObject metaObject) {

        Object version = getFieldValByName("version", metaObject);
        if(null == version){
            // 该属性为空,可以进行填充
            setFieldValByName("version",1,metaObject);
        }

    }

    @Override
    public void updateFill(MetaObject metaObject) {

    }
}

第十部分 逻辑删除

1.1 逻辑删除介绍

逻辑删除就是将数据标记为删 除,而并非真正的物理删除(非 DELETE 操作),查询时需要携带状态条件,确保被标记的数据不被查询 到。这样做的目的就是避免数据被真正的删除。

1.2 逻辑删除实现

1、修改表结构

为 user 表增加 deleted 字段,用于表示数据是否被删除,1 代表删除,0 代表未删除。

ALTER TABLE `user` ADD COLUMN `deleted` int(1) NULL DEFAULT 0 
COMMENT '1代表删除,0代表未删除' AFTER email

修改 User 实体

增加 deleted 属性并且添加 @TableLogic 注解:

@TableLogic 
private Integer deleted;

2、配置

application.properties:

# 逻辑已删除值(默认为 1) 
mybatis-plus.global-config.db-config.logic-delete-value=1 
# 逻辑未删除值(默认为 0) 
mybatis-plus.global-config.db-config.logic-not-delete-value=0

3、测试

/**
	 * 测试逻辑删除
	 * @author lane
	 * @date 2021/10/18 下午12:34
	 */
	@Test
	public void testDeleteById(){
		// UPDATE user SET deleted=1 WHERE id=? AND deleted=0
		this.userMapper.deleteById(2L);
	}

	/**
	 * 测试逻辑删除
	 * @author lane
	 * @date 2021/10/18 下午12:34
	 */
	@Test
	public void testSelectById(){
		// SELECT id,name,age,email AS mail,deleted FROM user WHERE id=? AND deleted=0 
		this.userMapper.selectById(2L);
	}

image.png

第十一部分 代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、 Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

1.1 创建工程

依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.galaxy</groupId>
    <artifactId>mybatis-plus-geneator</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatis-plus-geneator</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mybatis-plus的springboot支持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

自动生成代码

package com.galaxy.generator;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * mysql 代码生成器演示例子
 * @author lane
 * @date 2021年10月18日 下午12:46
 */
public class MysqlGenerator {
    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    /**
     * RUN THIS
     */
    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        final String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("zimu");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&useSSL=false&characterEncoding=utf8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        mpg.setDataSource(dsc);

        // 包配置
        final PackageConfig pc = new PackageConfig();
        pc.setModuleName(scanner("模块名"));
        pc.setParent("com.galaxy.auto.generator");
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        mpg.setTemplate(new TemplateConfig().setXml(null));

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//        strategy.setSuperEntityClass("com.baomidou.mybatisplus.samples.generator.common.BaseEntity");
        strategy.setEntityLombokModel(true);
//        strategy.setSuperControllerClass("com.baomidou.mybatisplus.samples.generator.common.BaseController");
        strategy.setInclude(scanner("表名"));
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        // 选择 freemarker 引擎需要指定如下加,注意 pom 依赖必须有!
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

测试结果

image.png

第十二部分 IDEA 快速开发插件

1.1 MybatisX

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 并安装。

功能:

Java 与 XML 调回跳转

Mapper 方法自动生成 XML

image.png

image.png

image.png

1.2 MyBatisPlus

安装方式

preference plugins 搜索 MyBatisPlus

作用
generator code

live template

from java to xml or from xml to java
具体使用

参考 :https://github.com/kana112233/mybatis-plus-plugin/wiki

代码导航
在这里插入图片描述

生成代码

配置数据库信息 other config database

自动生成代码 other code generator

68747470733a2f2f64626c6f6766696c652e6f73732d636e2d6265696a696e672e616c6979756e63732e636f6d2f6f6e65626c6f672f32303139303931333139323033373936322e676966.gif

代码模板

在 Java 类中输入以 m 开头可以得到以下模板代码 madd, mupdate, mdelete, mpage

在 xml 文件中输入 m 开头的可以得到以下模板代码 mselect、mupdatemdeleteminsert

68747470733a2f2f64626c6f6766696c652e6f73732d636e2d6265696a696e672e616c6979756e63732e636f6d2f6f6e65626c6f672f32303139303931333139313932363136342e676966.gif
68747470733a2f2f64626c6f6766696c652e6f73732d636e2d6265696a696e672e616c6979756e63732e636f6d2f6f6e65626c6f672f32303139303931333139323030333630312e676966.gif

总结

通过对 MyBatis-Plus 的学习,对 MyBatis、Spring、Spring Boot 的理解加深了很多很多,突然感觉自己懂了

MyBatis 原来就是对 JDBC 的封装 核心 SqlMapConfig.xml

Spring 就是对象交给 Spring 的 Bean 容器进行管理 核心 aplicationContext.xml

Spring Boot 就是方便你去集成各种框架而不担心版本问题 核心 application.properties

代码参考 https://github.com/LaneDu/lane-mybatis-plus-11.1

先学习的 MyBatis 笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值