如何一文学懂 SpringBoot 整合通用 Mapper 和逆向工程生成代码(Mybatis)

文章目录

  • 1、通用 Mapper 介绍
  • 2、快速使用通用 Mapper
    • 2.1、创建表、实体类和 Mapper 接口
    • 2.2、集成通用 Mapper
    • 2.3、配置扫描包
    • 2.4、Mapper 接口继承通用 Mapper 的核心接口 Mapper< T >
  • 3、常用注解
    • 3.1、@Table
    • 3.2、@Column
    • 3.3、@Id
    • 3.4、@GeneratedValue
    • 3.5、@Transient
  • 4、常用方法
    • 4.1、selectOne 方法
    • 4.2、xxxByPrimaryKey 方法
    • 4.3、xxxSelective 方法
  • 5、QBC 查询
    • 5.1、概念
    • 5.2、示例代码
  • 6、逆向工程
    • 6.1、原生 MyBatis 逆向工程和通用 Mapper 逆向工程对比
    • 6.2、参考文档地址
    • 6.3、在 pom 文件中添加参数
    • 6.4、在 pom 文件中添加插件
    • 6.5、创建 MBG 配置文件 generatorConfig.xml
    • 6.6、运行通用 Mapper 逆向工程
      • 6.6.1、Intellij 环境下
      • 6.6.2、eclipse 环境下

1、通用 Mapper 介绍

  • 通用Mapper都可以极大的方便开发人员。可以随意的按照自己的需要选择通用方法,还可以很方便的开发自己的通用方法。
  • 极其方便的使用MyBatis单表的增删改查。
  • 支持单表操作,不支持通用的多表联合查询。
  • 原生 Mapper 的难点:
  1. mapper.xml文件里有大量的sql,当数据库表字段变动,配置文件就要修改
  2. 需要自己实现sql分页,select * from table where . . . limit 1,3。自己手写分页,除了传参page、pageSize,还需要返回条目总数count。
  3. 数据库可移植性差:如果项目更换数据库,比如oracle–>mysql,mapper.xml中的sql要重新写,因为Oracle的PLSQL 和mysql 支持的函数是不同的。
  4. 生成的代码量过大。
  5. 批量操作,批量插入,批量更新,需要自写。
  • 这个东西使用后,会不会降低我们的代码执行效率呢?
       其实他的原理就是通过Mybatis的拦截器原理,利用反射机制拼出的 XML 形式的动态 SQL 然后去执行,并且内部对生成的 SQL 实现有缓存机制,所以你说代码时间消耗肯定也会有一些,但是这是很小很小的,再者在现在项目中,对于提供给前端的接口,通常都会利用些组件进行访问加速(毕竟直接从数据中检索不如在内存中来的快些),比如:redis、memcache、elastic search、solr 等,所以执行效率问题是可以避免或忽略的。
  • 如果有些方法不想使用,例如:用户的接口服务不能使用删除方法也不想暴漏出来,该怎么办呢?
      我们通常会定义增、删、改、查四个基础 Mapper 接口,之后可以按需要引入进行使用,其实即使你使用了公共的 CrudMapper(代表增删改查都在一起的类)也没有问题,只要你在 service 层不要放出删除方法也是可以的。

2、快速使用通用 Mapper

2.1、创建表、实体类和 Mapper 接口

表代码:

CREATE TABLE `table_emp` (
	`emp_id` int NOT NULL AUTO_INCREMENT ,
	`emp_name` varchar(500) NULL ,
	`emp_salary` double(15,5) NULL ,
	`emp_age` int NULL ,
	PRIMARY KEY (`emp_id`)
);
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('tom', '1254.37', '27');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('jerry', '6635.42', '38');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('bob', '5560.11', '40');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('kate', '2209.11', '22');
INSERT INTO `tabple_emp` (`emp_name`, `emp_salary`, `emp_age`) VALUES ('justin', '4203.15', '30');

实体类代码:
  考虑到基本数据类型在 Java 类中都有默认值,会导致 MyBatis 在执行相关操作时很难判断当前字段是否为 null,所以如阿里开发手册所言,Java 实体类尽量不要使用基本数据类型,都使用对应的包装类型。

@Data // lombok 插件,自动生成 get、set 等方法
public class Employee {
	private Integer empId;
	private String empName;
	private Double empSalary;
	private Integer empAge;
}

操作数据库的 Mapper 接口代码:

public interface EmployeeMapper {

}

2.2、集成通用 Mapper

在 pom 文件中引入通用 Mapper 的启动器

<dependency>
	<groupId>tk.mybatisgroupId>
	<artifactId>mapper-spring-boot-starterartifactId>
	<version>2.0.3version>
dependency>

2.3、配置扫描包

在 SpringBoot 启动类上面添加扫描包注解。此时用的是通用 Mapper 的扫描注解(其与原生 Mybatis 扫描包注解同名)
原始扫描包注解全类名:

import org.mybatis.spring.mapper.MapperScannerConfigurer

通用 Mapper 扫描包注解全类名:

import tk.mybatis.spring.mapper.MapperScannerConfigurer

原因是:由通用 Mapper 扫描的 dao 层接口,会在进入容器前,生成通用方法。
如何一文学懂 SpringBoot 整合通用 Mapper 和逆向工程生成代码(Mybatis)_第1张图片

2.4、Mapper 接口继承通用 Mapper 的核心接口 Mapper< T >

/**
* 具体操作数据库的 Mapper 接口,需要继承通用 Mapper 提供的核心接口 :Mapper
* 泛型类型就是实体类的类型
*/
public interface EmployeeMapper extends Mapper<Employee> {
}

3、常用注解

3.1、@Table

作用: 建立实体类和数据库表之间的对应关系。(指定类对应的表名称)
  默认规则为 实体类类名首字母小写作为表名。Employee 类→employee 表。
用法: 在@Table 注解的 name 属性中指定目标数据库表的表名

实体类代码:

@Data
@Table(name = "table_emp")
public class Employee {
    private Integer empId;
    private String empName;
    private BigDecimal empSalary;
    private Integer empAge;
}

3.2、@Column

作用: 建立实体类字段和数据库表字段之间的对应关系。
  默认规则:
    实体类字段:驼峰式命名
    数据库表字段:使用“_”区分各个单词
用法: 在@Column 注解的 name 属性中指定目标字段的字段名

实体类代码:

@Data
@Table(name = "table_emp")
public class Employee {
    @Column(name = "emp_id")
    private Integer empId;

    @Column(name = "emp_name")
    private String empName;

    @Column(name = "emp_salary")
    private BigDecimal empSalary;

    @Column(name = "emp_age")
    private Integer empAge;
}

3.3、@Id

通用 Mapper 在执行 xxxByPrimaryKey(key)方法时,有两种情况:
  情况 1:没有使用@Id 注解明确指定主键字段生成如下通用方法:
在这里插入图片描述
之所以会生成上面这样的 WHERE 子句是因为通用 Mapper 将实体类中的所有字段都拿来放在一起作为联合主键。
  情况 2:使用 @Id 主键明确标记和数据库表中主键字段对应的实体类字段:

   @Id
   @Column(name = "emp_id")
   private Integer empId;

3.4、@GeneratedValue

作用: 让通用 Mapper 在执行 insert 操作之后将数据库自动生成的主键值回写到实体类对象中。
自增主键用法(MySQL):

   @Id
   @Column(name = "emp_id")
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer empId;

序列主键用法(Oracle):

   @Id
   @Column(name = "emp_id")
   @GeneratedValue(
           strategy = GenerationType.IDENTITY,
           generator = "select SEQ_ID.nextval from dual")
   private Integer empId;

应用场景:

  • 增加商品销量…
  • 减少商品库存…
  • 生成订单数据→封装到 Order 对象中→保存 Order 对象→数据库自动生成主键值→回写到实体类对象 Order 中
  • 生成一系列订单详情数据→List< OrderItem >→在每一个 OrderItem 中设置 Order 对象的主键值作为外键→批量保存 List< OrderItem >

3.5、@Transient

用于标记不与数据库表字段对应的实体类字段,即该属性不参与 SQL 语句。若属性没有加该注解,并且在数据库表中找不到匹配列,则会抛出列找不到异常

@Transient
private String otherThings; //非数据库表中字段

4、常用方法

4.1、selectOne 方法

   public Employee getOne(Employee employee) {
    
       return employeeMapper.selectOne(employee);
   }
  • 通用 Mapper 替我们自动生成的 SQL 语句情况如下:

在这里插入图片描述

  • 实体类封装查询条件生成 WHERE 子句的规则
  1. 使用非空的值生成 WHERE 子句
  2. 在条件表达式中使用 “=” 进行比较(= 号局限性大,可以使用的是下文的 QBC 查询)
  • 要求必须返回一个实体类结果,如果有多个,则会抛出异常
    在这里插入图片描述

4.2、xxxByPrimaryKey 方法

    public Employee getOne(Employee employee) {
        
        return employeeMapper.selectByPrimaryKey(employee);
    }

需要使用 @Id 主键明确标记和数据库表主键字段对应的实体类字段,否则通用 Mapper 会将所有实体类字段作为联合主键。

4.3、xxxSelective 方法

非主键字段如果为 null 值,则不加入到 SQL 语句中。适用于字段很多,但是插入少的情况。如果表字段很多,但是一开始可能只插入某几个字段,用此方法生成的 SQL 语句会很简介,并且便于调试。

5、QBC 查询

5.1、概念

  • Query By Criteria
  • Criteria 是 Criterion 的复数形式。意思是:规则、标准、准则。在 SQL 语句中相当于查询条件。
  • QBC 查询是将查询条件通过 Java 对象进行模块化封装。

5.2、示例代码

//目标 SQL 查询语句:WHERE (emp_salary>? AND emp_age?)
//1.创建 Example 对象
Example example = new Example(Employee.class);
//***********************
//i.设置排序信息
example.orderBy("empSalary").asc().orderBy("empAge").desc();
//ii.设置“去重”
example.setDistinct(true);
//iii.设置 select 字段
example.selectProperties("empName","empSalary");
//***********************
//2.通过 Example 对象创建 Criteria 对象
Criteria criteria01 = example.createCriteria();
Criteria criteria02 = example.createCriteria();
//3.在两个 Criteria 对象中分别设置查询条件
//property 参数:实体类的属性名
//value 参数:实体类的属性值
criteria01.andGreaterThan("empSalary", 3000).andLessThan("empAge", 25);
criteria02.andLessThan("empSalary", 5000).andGreaterThan("empAge", 30);
//4.使用 OR 关键词组装两个 Criteria 对象
example.or(criteria02);
//5.执行查询
List<Employee> empList = employeeService.getEmpListByExample(example);
for (Employee employee : empList) {
	System.out.println(employee);
}

6、逆向工程

6.1、原生 MyBatis 逆向工程和通用 Mapper 逆向工程对比

如何一文学懂 SpringBoot 整合通用 Mapper 和逆向工程生成代码(Mybatis)_第2张图片

6.2、参考文档地址

代码生成器

6.3、在 pom 文件中添加参数

在 pom 文件中写入所有参数并不是硬性的要求,可以在要用的时候硬编码写死到代码中。先把参数放在 pom 文件中方便管理

<properties>
    
    
    <targetJavaProject>${basedir}/src/main/javatargetJavaProject>
    
    
    <targetMapperPackage>per.cjh.example.mapperstargetMapperPackage>
    
    
    <targetModelPackage>per.cjh.example.entitiestargetModelPackage>
    
    <targetResourcesProject>${basedir}/src/main/resourcestargetResourcesProject>
    
    <targetXMLPackage>mapperstargetXMLPackage>
    
    <mapper.version>4.0.0mapper.version>
    
    <mysql.version>8.0.19mysql.version>
properties>

6.4、在 pom 文件中添加插件

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-pluginartifactId>
            <configuration>
                <source>1.8source>
                <target>1.8target>
            configuration>
        plugin>
        <plugin>
            <groupId>org.mybatis.generatorgroupId>
            <artifactId>mybatis-generator-maven-pluginartifactId>
            <version>1.3.6version>
            <configuration>
                <configurationFile>
                    ${basedir}/src/main/resources/generator/generatorConfig.xml
                configurationFile>
                <overwrite>trueoverwrite>
                <verbose>trueverbose>
            configuration>
            
            <dependencies>
                
                <dependency>
                    <groupId>mysqlgroupId>
                    <artifactId>mysql-connector-javaartifactId>
                    <version>${mysql.version}version>
                dependency>
                
                <dependency>
                    <groupId>tk.mybatisgroupId>
                    <artifactId>mapperartifactId>
                    <version>${mapper.version}version>
                dependency>
            dependencies>
        plugin>
    plugins>
build>

6.5、创建 MBG 配置文件 generatorConfig.xml

注意:配置文件的路径要在上一步声明的路径下面。



<generatorConfiguration>
    
    <properties resource="config.properties"/>
    
    <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        
        
        <plugin type="${mapper.plugin}">
            <property name="mappers" value="${mapper.Mapper}"/>
            <property name="caseSensitive" value="true"/>
        plugin>
        
        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.url}"
                        userId="${jdbc.user}"
                        password="${jdbc.password}">
        jdbcConnection>
        
        <javaModelGenerator targetPackage="${targetModelPackage}"
                            targetProject="${targetJavaProject}"/>
        
        <sqlMapGenerator targetPackage="${targetXMLPackage}"
                         targetProject="${targetResourcesProject}"/>

        
        <javaClientGenerator targetPackage="${targetMapperPackage}"
                             targetProject="${targetJavaProject}"
                             type="XMLMAPPER"/>
        
        
        
        
        
        <table tableName="account" domainObjectName="account">
            
            <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
        table>
    context>
generatorConfiguration>

6.6、运行通用 Mapper 逆向工程

6.6.1、Intellij 环境下

  1. 点击编译器左下角 Terminal,调出控制台
    如何一文学懂 SpringBoot 整合通用 Mapper 和逆向工程生成代码(Mybatis)_第3张图片
  2. 让路径跳转到当前工程,即 pom 文件所在目录。cd 命令 (change dir 改变目录)
    如何一文学懂 SpringBoot 整合通用 Mapper 和逆向工程生成代码(Mybatis)_第4张图片
  3. 运行 mvn mybatis-generator:generate 命令
    在这里插入图片描述

6.6.2、eclipse 环境下

右键 pom 文件,Run As -> Maven build
在弹出窗口的 Goals:文本框内写入右边的命令 mvn mybatis-generator:generate
点击Run

你可能感兴趣的:(Mybatis框架)