1.什么是Mybatis-plus?

官网地址:MyBatis-Plus

1.1MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变为简化开发提高效率而生

Mybatis-plus的愿景成为Mybatis的最好拍档,就跟魂斗罗里面的P1、P2一样

2.MyBatis-plus的特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库

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

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb

  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库

框架结构

3.开发环境

开发工具:IDEA 2020.1、Navicat 15

Java版本:jdk8

SpringBoot: 2.6.7

mybatis-plus: 3.5.1

MySQL:5.7

4.入门

4.1新建数据库

在Navicat 15中新建一个数据库

在mp数据库中新建一张为user的表

新建查询,复制以下SQL添加数据

insert into user(id,`name`,age,email)
values (1,'张三',18,'test1@qq.com'),
(2,'李四',19,'test2@qq.com'),
(3,'王五',20,'test3@qq.com'),
(4,'刘六',28,'test4@qq.com'),
(5,'武七',24,'test5@qq.com')

4.2我们打开IDEA新建一个SpringBoot项目(这里我们使用导入lombok)

导入MyBatis-plus依赖

 <!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency>                                                                                       

配置application.yml文件

spring:#MySQL数据源配置datasource:#数据源类型配置type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mp?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8username: rootpassword: 123456mybatis-plus:#实体类别名配置type-aliases-package: com.xiaoliu.mybatisplus.pojo#日志配置configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

新建四个包

在pojo包中新建一个User的类

package com.xiaoliu.mybatisplus.pojo;import lombok.Data;import java.io.Serializable;/*** 用户实体类* @author xiaoliu*/
@Data
public class User implements Serializable {private Integer id;private String name;private Integer age;private String email;
}

再到mapper包中新建一个UserMapper的接口(注意:要继承BaseMapper,并且填上泛型)

package com.xiaoliu.mybatisplus.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaoliu.mybatisplus.pojo.User;/*** 用户Mapper层接口* @author xiaoliu*/
public interface UserMapper extends BaseMapper<User> {}

随后我们在SpringBoot主启动类上添加@MapperScan注解

package com.xiaoliu.mybatisplus;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author xiaoliu*/
@MapperScan("com.xiaoliu.mybatisplus.mapper")
@SpringBootApplication
public class MybatisPlusApplication {public static void main(String[] args) {SpringApplication.run(MybatisPlusApplication.class, args);}}

4.3测试

在test目录下的测试类中进行测试是否成功,注意这里使用@Autowired注解发生红线时,像我一样换成@Resource就不会报错了

package com.xiaoliu.mybatisplus;import com.xiaoliu.mybatisplus.mapper.UserMapper;
import com.xiaoliu.mybatisplus.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import java.util.List;@SpringBootTest
class MybatisPlusApplicationTests {@Resourceprivate UserMapper userMapper;@Testvoid contextLoads() {//通过条件构造器查询一个list集合List<User> list = userMapper.selectList(null);list.forEach(System.out::println);}}

5.开启日志功能

在刚刚配置Mybatis-plus配置时,我们已经开启了日志功能了,现在我们来详细讲解一下这个功能

里面有多套log日志信息打印,它们都会打印出执行的SQL语句,查询到的结果信息,这里的配置默认推荐使用StdOutImpl这个日志功能

开启Log之后,会帮我们打印出对应的SQL语句,数据库中对应的行列信息,但是Mybatis-plus再我们刚刚写的这些代码中,并没有去写SQL语句,那他是怎么知道我们要操纵的是哪一张表中的信息呢?

其实在我们写UserMapper接口时就已经指定了使用哪一张表的SQL了

然后它会根据你指定的实体类中的成员变量查询对应的字段。

6.BaseMapper

BaseMapper中封装了很多对单表的增删改查操作的方法,点进源码我们可以发现有各种各样的方法,什么inset,delete。。。等等

这些执行的操作都是通过你在Mapper层 extens BaseMapper<T>泛型中指定的实体类进行对应表的操作,前提是你数据库中的表名要与实体类名一样对应。

刚刚我们已经对查询进行了一下简单的操作,现在我们再做一个简单的示范,这里只示范一下增加操作,其余的可以自己去试试

 /*** 增加操作*/@Testvoid add(){User user = new User();user.setId(6);user.setName("小刘");user.setAge(21);user.setEmail("1234567890@qq.com");int result = userMapper.insert(user);System.out.println("result:"+ result);}

Mybatis-plus解决了单表查询的问题,但是对于多表还是建议手写SQL语句进行查询

自定义多表SQL的话,在Mybatis的时候要配置xxxMapper.xml的文件路径进行映射,在Mybatis-plus中默认配置了一个Mapper文件的路径,这个路径是在resources路径下建立一个mapper文件,当然你如果想要自定义路径的话可以进行编写配置

7.Service

在Mybatis-plus中,在service层给我们进一步封装了很多较为复杂的业务逻辑层的功能方法。这些方法其实也是基于BaseMapper接口中的功能做进一步的增强操作

7.1准备工作

创建一个Service接口

源码:

我们可以看见在这个接口中封装了更多的方法,对应不同的业务逻辑,比如增加和修改操作直接调用一个saveOrUpdate方法即可实现

我们再创建一个Service接口的实现类(注意:这里还是需要指定@Service把它加入组件中的)

源码:

在这个类中,我们可以看见也有很多的方法可以进行调用,平时的话我们大部分都是调用IService接口中的方法就可以实现很多功能了!

7.2使用

在测试类中,我们进行一些方法的操作

查询数据总条数: count();

package com.xiaoliu.mybatisplus;import com.xiaoliu.mybatisplus.mapper.UserMapper;
import com.xiaoliu.mybatisplus.pojo.User;
import com.xiaoliu.mybatisplus.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import java.util.List;@SpringBootTest
class MybatisPlusApplicationTests {@Resourceprivate UserService userService;/*** 查询数据总条数*/@Testvoid count(){long result = userService.count();System.out.println("result:" + result);}}

批量添加:saveBatch(); 这里做一个模拟的批量添加功能,具体功能实现看你自己的业务

package com.xiaoliu.mybatisplus;import com.xiaoliu.mybatisplus.mapper.UserMapper;
import com.xiaoliu.mybatisplus.pojo.User;
import com.xiaoliu.mybatisplus.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;@SpringBootTest
class MybatisPlusApplicationTests {@Resourceprivate UserService userService;/*** 批量添加*/@Testvoid adds(){List<User> list = new ArrayList<>();for (int i = 0; i <= 10 ; i++) {User user = new User();user.setName("ybc"+i);user.setAge(20+i);list.add(user);}boolean batch = userService.saveBatch(list);System.out.println(batch);}}

这里批量添加的时候Id主键是Mybatis-plus中利用雪花算法给我们生成的一个Id,后面再告诉你如何利用主键的自动递增实现

总结:IService中的方法使用就到这了,以上只是演示了两种方法,其他的方法各位可以好好自己去试试

8.Mybatis-plus中的注解

1.@TableName

在真实业务中,会存在多个xx_xxx的表名,这时候如果直接使用泛型就会找不到对应的表了。所以我们在写实体类的时候,需要加上

@TableName这个注解指定数据库中对应的表。这样即使是有下划线直接指定实体类也能找到对应的表了。

/*** 用户实体类* @author xiaoliu*/
@Data
@TableName("user")
public class User implements Serializable {private Integer id;private String name;private Integer age;private String email;
}

当然你也可以在yaml配置文件中去配置Mybatis-plus的全局配置,它会为每个实体类都加上一个前缀

mybatis-plus:#实体类别名配置type-aliases-package: com.xiaoliu.mybatisplus.pojo#日志配置configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl#设置Mybatis-plus全局配置global-config:db-config:#设置实体类对应表的统一前缀table-prefix: t_

当然我不建议这么去使用,因为如果说你的表名不是你指定的前缀开头的,它会匹配不上,从而报错,最好还是选择注解进行使用

2.@TableId

该注解是表示将该属性所对应的字段指定为主键

/*** 用户实体类* @author xiaoliu*/
@Data
@TableName("user")
public class User implements Serializable {@TableIdprivate Integer id;private String name;private Integer age;private String email;

使用@TableId里面的value属性,如果只是指定一个字段名,当然这个value = " " 也可以不用写,直接在括号中写入" "即可

/*** 用户实体类* @author xiaoliu*/
@Data
@TableName("user")
public class User implements Serializable {//指定数据库中对应主键字段名@TableId(value = "id")private Integer id;private String name;private Integer age;private String email;
}

使用@TableId中的Type属性,上面设置了value属性,当然这样是不够的,如果你的主键是自动递增的,那么还是使用的雪花算法进行生成主键ID,但是加上Type = IdType.xxx 后是自动递增的,当然这个设置自动递增在你的数据库中也要进行对应设置

/*** 用户实体类* @author xiaoliu*/
@Data
@TableName("user")
public class User implements Serializable {//设置成自动递增@TableId(value = "id",type = IdType.AUTO)private Integer id;private String name;private Integer age;private String email;
}

当然你也可以在yaml配置文件中进行一个设置,但是具体的话也是要根据你业务进行设置,因为这个配置的话是全局配置,如果你的数据库主键不是自增的,那么还是会出错的

mybatis-plus:#实体类别名配置type-aliases-package: com.xiaoliu.mybatisplus.pojo#日志配置configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl#设置Mybatis-plus全局配置global-config:db-config:#设置全局实体类表名加上前缀table-prefix: t_#设置全局实体类主键Id自增id-type: auto

3.雪花算法

4.@TableField

该注解设置属性所对应的字段名,如果说你实体类中的属性名与数据库中的字段名不一致,使用该注解进行一个指定即可

/*** 用户实体类* @author xiaoliu*/
@Data
@TableName("user")
public class User implements Serializable {@TableId(value = "id",type = IdType.AUTO)private Integer id;@TableField("name")private String name;@TableField("age")private Integer age;@TableField("email")private String email;
}

5.@TableLogic

在数据库中新增一个字段,is_delete默认值设置为0

在实体类中添加对应属性,假删除的属性上加上@TableLogic注解

/*** 用户实体类* @author xiaoliu*/
@Data
@TableName("user")
public class User implements Serializable {@TableId(value = "id",type = IdType.AUTO)private Integer id;@TableField("name")private String name;@TableField("age")private Integer age;@TableField("email")private String email;@TableLogicprivate Integer isDelete;
}

这时我们再执行删除的方法会发现,它的语句变成了update修改的SQL了,我们再看数据库is_delete这个字段变成了1

以前我们删除都是直接物理删除,把对应条件的都进行了删除,它就不再存在了这条数据。而用了@TableLogic这个注解可以实现逻辑删除,只要再数据库中新增一个假删除的字段,再该字段对应的实体类属性上加上该注解,再使用删除方法就会进行逻辑删除,而该数据库依旧保存再该数据库中,0表示未删除,1表示已删除。

这时我们再进行查询所有数据时,就不会查询到已经进行逻辑删除的数据了。它会自动的在查询后面加上条件查询未逻辑删除的字段。

9.条件构造器

1.wapper介绍

2.QueryWrapper

我们使用QueryWrapper<T> 进行一些条件查询

/*** 条件构造器*/@Testvoid selectWrapper(){//查询name中包含'刘',age在20-30之间,邮箱信息不为Null的用户信息QueryWrapper<User> wrapper = new QueryWrapper<>();//column为数据库中的字段名而非实体类的属性名,后面是条件wrapper.like("name","刘").between("age",20,30).isNotNull("email");List<User> list = userService.list(wrapper);

我们会发现它的SQL语句会根据我们使用的条件构造器去进行相同条件的查询结果。

该类还有很多的方法可以进行尝试,这里只做部分演示啦,剩下的自己去探索哦!

3.Condition

使用带有该参数的方法进行条件组装,它是个布尔类型的参数,如果为true则表示组装,如果为false则表示不组装该条件

 /*** 条件构造器*/@Testvoid selectWrapper(){String name = "刘";Integer ageBegin = null;Integer ageEnd = 30;QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.like(StringUtils.isNotBlank(name),"name",name).ge(ageBegin != null,"age",ageBegin).le(ageEnd != null,"age",ageEnd);List<User> list = userService.list(wrapper);list.forEach(System.out::println);}

由条件我们可以看出,如果为条件不成立,则不会执行该条件构造进行拼接操作。

4.LambdaQueryWrapper

该表达式里面的指定数据库字段名的参数可以用实体类的lambda表达式进行表示

/*** 条件构造器*/@Testvoid selectWrapper(){String name = "刘";Integer ageBegin = null;Integer ageEnd = 30;LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.like(StringUtils.isNotBlank(name),User::getName,name).ge(ageBegin != null,User::getAge,ageBegin).le(ageEnd != null,User::getAge,ageEnd);List<User> list = userService.list(queryWrapper);list.forEach(System.out::println);}

使用起来基本与上面没太大区别

10.Mybatis-plus分页插件

使用Mybatis-plus分页插件之前我们要对Mybatis-plus进行配置

package com.xiaoliu.mybatisplus.config;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Mybatis-Plus配置类* @author xiaoliu*/
@MapperScan("com.xiaoliu.mybatisplus.mapper")
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return mybatisPlusInterceptor;}
}

随后使用分页插件功能

  @Testvoid Page(){//分页插件Page<User> page = new Page<>(1,3);userService.page(page,null);System.out.println(page);}

结果

使用分页插件,如果查询的是第一页的参数,那么它的语句如上图结果所示,LIMIT ? 只有一个参数

10.1 获取分页数据的方法

常用的一些方法:

@Testvoid Page(){//分页插件Page<User> page = new Page<>(1,3);userService.page(page,null);// 获取当前分页数据System.out.println(page.getRecords());// 获取总条数System.out.println(page.getTotal());// 获取每页的数据条数System.out.println(page.getSize());// 当前在第几页System.out.println(page.getCurrent());// 获取总页数System.out.println(page.getPages());}

11.乐观锁和悲观锁

简述一下乐观锁和悲观锁,个人理解,详情还请自行百度

悲观锁:在执行语句时,我们就认为这个语句它就是会失败,它就是会报错,我们就提前给它加上锁机制,让它出现错误就回滚。这种悲观的加锁机制就被叫做悲观锁,通常使用for update来进行实现。

乐观锁:与悲观锁相反,通常使用加version字段的方法进行实现。

11.1模拟冲突

新建一张表为product

在表中添加一条商品数据

新建实体类Product

/*** 商品表实体类* @author xiaoliu*/
@Data
@TableName("product")
public class Product implements Serializable {@TableId(value = "id",type = IdType.AUTO)private Integer id;@TableField("name")private String name;@TableField("price")private Integer price;@TableField("version")private Integer version;
}

在idea中编辑代码模拟冲突

@Testvoid testProduct01(){// 小李查询商品价格Product productLi = productService.getById(1);System.out.println("小李查询的商品价格:" + productLi.getPrice());// 小王查询商品价格Product productWang = productService.getById(1);System.out.println("小王查询的商品价格:" + productWang.getPrice());// 小李将商品价格+50productLi.setPrice(productLi.getPrice()+50);productService.updateById(productLi);// 小王将商品价格-30productWang.setPrice(productWang.getPrice()-30);productService.updateById(productWang);// 老板查询商品价格Product productBoss = productService.getById(1);System.out.println("老板查询的商品价格:" + productBoss.getPrice());}

小李查询出来的价格

小王查询出来的价格

结果:我们可以发现,小李和小王都是对原有价格进行了操作,但是最终结果确为小王操作的70,这是因为两边同时拿到的都是100,而小王是最后执行的覆盖掉了小李的数据,才会导致最终老板拿到的价格应该为150-30 =120,但是老板拿到的是小王最终修改的70元价格,这就发生了冲突了。

11.2Mybatis-plus乐观锁插件

为了解决刚刚这个冲突,我们使用Mybatis-plus提供的乐观锁插件进行加锁处理

在实体类上进行修改:在版本号字段上加上@Version注解

/*** 商品表实体类* @author xiaoliu*/
@Data
@TableName("product")
public class Product implements Serializable {@TableId(value = "id",type = IdType.AUTO)private Integer id;@TableField("name")private String name;@TableField("price")private Integer price;/*** 该注解标识乐观锁版本号字段*/@Versionprivate Integer version;
}

在config配置类中加入乐观锁插件

/*** Mybatis-Plus配置类* @author xiaoliu*/
@MapperScan("com.xiaoliu.mybatisplus.mapper")
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();// 新增分页插件mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 新增乐观锁插件mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}
}

接下来我们再去执行刚刚的代码:为什么是150?

因为小李先进行了修改,以版本号0为条件进行修改,这时修改成功,版本号也变成了。在后来小王进行修改时,他也是以版本号为0进行修改,但这时小李已经修改了版本号把它变成1了,所以这时小王的条件失效了,修改失败了。老板查询结果为150

但是这也不正确,按照常理来说,这时应该为120才正确吧。所以我们进行一步小小的优化

@Testvoid testProduct01(){// 小李查询商品价格Product productLi = productService.getById(1);System.out.println("小李查询的商品价格:" + productLi.getPrice());// 小王查询商品价格Product productWang = productService.getById(1);System.out.println("小王查询的商品价格:" + productWang.getPrice());// 小李将商品价格+50productLi.setPrice(productLi.getPrice()+50);productService.updateById(productLi);// 小王将商品价格-30productWang.setPrice(productWang.getPrice()-30);boolean result = productService.updateById(productWang);if (result == false){// 操作失败重试Product productNew = productService.getById(1);productNew.setPrice(productNew.getPrice() - 30);productService.updateById(productNew);}// 老板查询商品价格Product productBoss = productService.getById(1);System.out.println("老板查询的商品价格:" + productBoss.getPrice());}

结果:

12.通用枚举

在数据库中添加一个sex字段

我们声明一个枚举类:SexEnum

/*** 性别枚举类* @author xiaoliu*/
@Getter
public enum SexEnum {MALE(1,"男"),FEMALE(2,"女");//将注解所标识的属性的值存储到数据库中@EnumValueprivate Integer sex;private String sexName;SexEnum(Integer sex, String sexName) {this.sex = sex;this.sexName = sexName;}
}

接下来我们在yaml的Mybatis-plus配置扫描通用枚举的包

mybatis-plus:#实体类别名配置type-aliases-package: com.xiaoliu.mybatisplus.pojo#日志配置configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl#扫描通用枚举的包type-enums-package: com.xiaoliu.mybatisplus.enums

编写测试代码:

 @Testvoid TestEnum(){User user = new User();user.setName("admin");user.setAge(33);user.setSex(SexEnum.MALE);boolean save = userService.save(user);System.out.println("save = " + save);}

13.代码生成器

13.1导入依赖

 <!--代码生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency>

13.2代码

这里选择最新版

从官网copy一份代码下来:

package com.xiaoliu.mybatisplus.generator;import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import java.util.Collections;/*** 代码生成器* @author xiaoliu*/
public class Generator {public static void main(String[] args) {//要操作的数据库FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8","root","123456").globalConfig(builder -> {builder.author("xiaoliu") // 设置作者.enableSwagger() // 开启 swagger 模式.fileOverride() // 覆盖已生成文件.outputDir("D:\\dbsk\\mybatis-plus\\src\\main\\java"); // 指定输出目录}).packageConfig(builder -> {builder.parent("com.xiaoliu.mybatisplus") // 设置父包名.moduleName(null) // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\dbsk\\mybatis-plus\\src\\main\\resources\\mapper")); // 设置mapperXml生成路径}).strategyConfig(builder -> {// 这个是entity实体类设置builder.entityBuilder().enableLombok();//添加Lombok// 这个是controller控制层设置builder.controllerBuilder().enableHyphenStyle(). //开启驼峰转连注解enableRestStyle();//开启@RestController注解builder.addInclude("") // 设置需要生成的表名.addTablePrefix("t_", "c_"); // 设置过滤表前缀})// 使用Freemarker引擎模板,默认的是Velocity引擎模板.templateEngine(new FreemarkerTemplateEngine()).execute();}
}

13.3执行代码生成器

新建一个Teacher表

执行代码生成器的main方法,会先弹出文件夹,然后看输出台打印结果

检查一下生成的类和接口,我这里没有用Swagger所以爆错了。

如果你自己想div一个代码生成的模板, 你可以如下图去进行修改,把源码中的模板复制到你的resource-->templates下进行修改里面的内容即可,修改完成后每次执行就是你自己div 的模板啦

14.多数据源

新建一个数据库:mp-2,把product复制粘贴过去

再新建一个SpringBoot项目

14.1导入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.1</version>
</dependency>

14.2Yml配置数据源

spring:datasource:dynamic:primary: master #设置默认的数据源或者数据源组,默认值即为masterstrict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源datasource:master:url: jdbc:mysql://xx.xx.xx.xx:3306/dynamicusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置slave_1:url: jdbc:mysql://xx.xx.xx.xx:3307/dynamicusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverslave_2:url: ENC(xxxxx) # 内置加密,使用请查看详细文档username: ENC(xxxxx)password: ENC(xxxxx)driver-class-name: com.mysql.jdbc.Driver#......省略#以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
# 多主多从                      纯粹多库(记得设置primary)                   混合配置
spring:                               spring:                               spring:datasource:                           datasource:                           datasource:dynamic:                              dynamic:                              dynamic:datasource:                           datasource:                           datasource:master_1:                             mysql:                                master:master_2:                             oracle:                               slave_1:slave_1:                              sqlserver:                            slave_2:slave_2:                              postgresql:                           oracle_1:slave_3:                              h2:                                   oracle_2:

14.3使用代码生成器生成User和Product实体类

别忘了在启动类加上@MapperScan()注解开启扫描

14.4使用数据源

在ServiceImpl类上加上@DS()注解,指定数据源

@DS("master")
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IService<User> {
}
@DS("slave_1")
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {}

14.5测试多数据源

package com.xiaoliu.mybatisplus;import com.xiaoliu.mybatisplus.service.IProductService;
import com.xiaoliu.mybatisplus.service.IUserService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;@SpringBootTest
class MybatisPlusDatasourceApplicationTests {@Resourceprivate IUserService userService;@Resourceprivate IProductService productService;@Testvoid contextLoads() {System.out.println(userService.getById(2));System.out.println(productService.getById(1));}}

结果表示我们可以从配置多数据源中获取数据

15.MybatisX插件

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

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

官网地址:MybatisX快速开发插件 | MyBatis-Plus

Mybatis-plus (教程来自尚硅谷视频)相关推荐

  1. Spring框架(基于尚硅谷视频)

    该笔记源于尚硅谷视频对Spring的讲解(适合新手,大佬划走),视频连接如下: https://www.bilibili.com/video/BV1Vf4y127N5?p=27&spm_id_ ...

  2. Mybatis学习笔记(尚硅谷版整理)

    Mybatis [尚硅谷]2022版MyBatis教程(细致全面,快速上手)_哔哩哔哩_bilibili 笔记 Mybatis框架搭建 步骤 创建maven工程,引入依赖 创建Mybatis的核心配置 ...

  3. Docker_尚硅谷视频学习笔记

    文章目录 1 Docker 简介 前提知识+课程定位 Docker 是什么? 问题:为什么会有docker出现 docker理念 总结 能干嘛 之前的虚拟机技术 容器虚拟化技术 开发/运维(DevOp ...

  4. 浅谈面试与简历——总结于尚硅谷视频《程序员面试指南》

    前言:如果你没有面试机会或者面试机会很少,那么问题出现在简历上:如果你面试机会并不少,但面试成功率很低,那么问题出现在面试上,可能是面试准备不足.面试发挥不好或者面试薪资无法契合等等.千万不要否定自己 ...

  5. javascript全笔记-基础版(尚硅谷视频李立超老师)

    目录 一.JavaScript简介 1.1 JS简介 1.2 JS的HelloWorld 1.3 JS代码编写的位置 二.JS的基础语法 2.1 JS的基本语法 2.2 字面量与变量 2.3 标识符 ...

  6. JavaSE(尚硅谷视频学习笔记)

    文章目录 Java基础编程 Java语言概述 Java语言简述 1.基础图解 2.常识 3.计算机语言的发展迭代 4.Java语言版本迭代概述 5. Java语言应用的领域 6.Java语言的特点 开 ...

  7. 【javaScript】学完js基础,顺便把js高级语法学了(尚硅谷视频学习笔记)

    文章目录 [1]基本总结深入 一.什么是数据 1.数据类型 基本(值)类型 对象(引用)类型 2.判断 相关问题 二.什么是内存 1.什么是数据 2.什么是内存? 3.什么是变量 4.内存.数据.变量 ...

  8. Git学习(1)pro git阅读尚硅谷视频

    目录 目录: 1. 起步 2. Git 基础 3. Git 分支 4. 服务器上的 Git 5. 分布式 Git 第一章 1.3 Git是什么 1.6运行git前的配置 该开源图书网站 Git - B ...

  9. 4.Java学习笔记第四节——程序流程控制(尚硅谷视频整理)

    文章目录 一.分支语句 1.       if-else 结构 1)如何从键盘获取不同类型的变量 2.      switch-case 结构 二.循环结构 1.      for 循环 一.分支语句 ...

最新文章

  1. 企业中的混乱:如何对云计算具有信心
  2. python mmap对象
  3. Python实现进度条总结
  4. C# 删除指定目录下全部文件
  5. 十二、泛型、反射和异常
  6. php中gd为什么是乱码的,php gd库中文乱码怎么解决?
  7. Ubuntu 挂载新磁盘
  8. java springMVC生成二维码
  9. 如何正确使用RS485半双工芯片
  10. 支教日记软件测试,烟酒行销售实习日志(74页)-原创力文档
  11. 设计模式总览及工厂模式详解
  12. HTML5 新特性 - WebSocket实现聊天(群聊天室、一对一聊天)
  13. keil软件仿真时如何使用逻辑分析仪查看波形
  14. 【转】机器学习embedding
  15. [原]简易Windows密码查看器
  16. 算法与数据结构07:前缀树,计数排序与桶排序
  17. java设置小数点格式_java指定小数点后位数格式
  18. 北大教授:只剩下学术的生活是危险的
  19. 基于Python新闻信息管理系统设计与实现 开题报告
  20. c++课程设计——班车管理系统

热门文章

  1. ajax返回字符串怎么处理,ajax请求返回json字符串/json对象 处理
  2. 图形 1.2.1 向量基础
  3. 牛!Android 开发者成神之路!
  4. 【数据分析】如何在企业中从0-1建立一个数据/商业分析部门
  5. 关于WINCE下输入法声韵母问题的解决方法
  6. Android TV 源码修改默认输入法
  7. ScholarRanking中国高校计算机学科排名:第2名你绝对想不到
  8. AG6201 (HDMI 转 VGA)内置MCU音频DAC
  9. Dev的安装和简单使用
  10. leecode-试水