MyBatisPlus(Spring Boot版)的基本使用

1. 初始化项目

1.1. 配置application.yml

xml 复制代码
spring:
	# 配置数据源信息
	datasource:
		# 配置数据源类型
		type: com.zaxxer.hikari.HikariDataSource
		# 配置连接数据库信息
		driver-class-name: com.mysql.cj.jdbc.Driver
		url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
		username: root
		password: 123456

注意:

  1. 驱动类driver-class-name
  • spring boot 2.0(内置jdbc5驱动),驱动类使用:driver-class-name: com.mysql.jdbc.Driver
  • spring boot 2.1及以上(内置jdbc8驱动),驱动类使用:driver-class-name: com.mysql.cj.jdbc.Driver

否则运行测试用例的时候会有 WARN 信息

  1. 连接地址url
  • MySQL5.7版本的url:jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
  • MySQL8.0版本的url:jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

否则运行测试用例报告如下错误:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more

1.2. 启动类

在Spring Boot启动类中添加@MapperScan注解,扫描mapper包

java 复制代码
@SpringBootApplication
@MapperScan("com.wyb.mybatisplus.mapper")
public class MybatisplusApplication {
	public static void main(String[] args) {
		SpringApplication.run(MybatisplusApplication.class, args);
	}
}

1.3. 添加实体

java 复制代码
@Data //lombok注解
public class User {
	private Long id;
	private String name;
	private Integer age;
	private String email;
}

1.4. 添加mapper

BaseMapper是MyBatis-Plus提供的模板mapper,其中包含了基本的CRUD方法,泛型为操作的实体类型

java 复制代码
public interface UserMapper extends BaseMapper<User> {
}

1.5. 测试

java 复制代码
@SpringBootTest
public class MybatisPlusTest {
	@Autowired
	private UserMapper userMapper;
	@Test
	public void testSelectList(){
		//selectList()根据MP内置的条件构造器查询一个list集合,null表示没有条件,即查询所有
		userMapper.selectList(null).forEach(System.out::println);
	}
}

1.6. 添加日志

在application.yml中配置日志输出

java 复制代码
# 配置MyBatis日志
mybatis-plus:
	configuration:
		log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2. 基本CRUD

2.1. BaseMapper

MyBatis-Plus中的基本CRUD在内置的BaseMapper中都已得到了实现,可以直接使用

2.2. 插入

java 复制代码
@Test
public void testInsert(){
	User user = new User(null, "张三", 23, "zhangsan@163.com");
	//INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
	int result = userMapper.insert(user);
	System.out.println("受影响行数:"+result);
	//1475754982694199298
	System.out.println("id自动获取:"+user.getId());
}

2.3. 删除

  1. 通过id删除记录
java 复制代码
@Test
public void testDeleteById(){
	//通过id删除用户信息
	//DELETE FROM user WHERE id=?
	int result = userMapper.deleteById(1475754982694199298L);
	System.out.println("受影响行数:"+result);
}
  1. 通过id批量删除记录
java 复制代码
@Test
public void testDeleteBatchIds(){
	//通过多个id批量删除
	//DELETE FROM user WHERE id IN ( ? , ? , ? )
	List<Long> idList = Arrays.asList(1L, 2L, 3L);
	int result = userMapper.deleteBatchIds(idList);
	System.out.println("受影响行数:"+result);
}
  1. 通过map条件删除记录
java 复制代码
@Test
public void testDeleteByMap(){
	//根据map集合中所设置的条件删除记录
	//DELETE FROM user WHERE name = ? AND age = ?
	Map<String, Object> map = new HashMap<>();
	map.put("age", 23);
	map.put("name", "张三");
	int result = userMapper.deleteByMap(map);
	System.out.println("受影响行数:"+result);
}

2.4. 修改

java 复制代码
@Test
public void testUpdateById(){
	User user = new User(4L, "admin", 22, null);
	//UPDATE user SET name=?, age=? WHERE id=?
	int result = userMapper.updateById(user);
	System.out.println("受影响行数:"+result);
}

2.5. 查询

  1. 根据id查询用户信息
java 复制代码
@Test
public void testSelectById(){
	//根据id查询用户信息
	//SELECT id,name,age,email FROM user WHERE id=?
	User user = userMapper.selectById(4L);
	System.out.println(user);
}
  1. 根据多个id查询多个用户信息
java 复制代码
@Test
public void testSelectBatchIds(){
	//根据多个id查询多个用户信息
	//SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
	List<Long> idList = Arrays.asList(4L, 5L);
	List<User> list = userMapper.selectBatchIds(idList);
	list.forEach(System.out::println);
}
  1. 通过map条件查询用户信息
java 复制代码
@Test
public void testSelectByMap(){
	//通过map条件查询用户信息
	//SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
	Map<String, Object> map = new HashMap<>();
	map.put("age", 22);
	map.put("name", "admin");
	List<User> list = userMapper.selectByMap(map);
	list.forEach(System.out::println);
}
  1. 查询所有数据
java 复制代码
@Test
public void testSelectList(){
	//查询所有用户信息
	//SELECT id,name,age,email FROM user
	List<User> list = userMapper.selectList(null);
	list.forEach(System.out::println);
}

2.6. 通用Service

说明:

  • 通用 Service CRUD 封装 IService 接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆,
  • 泛型 T 为任意实体对象
  • 建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类
  1. IService
    MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑,详情查看源码IService和ServiceImpl
  2. 创建Service接口和实现类
java 复制代码
/**
* UserService继承IService模板提供的基础功能
*/
public interface UserService extends IService<User> {
}
java 复制代码
/**
* ServiceImpl实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
  1. 测试查询记录数
java 复制代码
@Autowired
private UserService userService;
@Test
public void testGetCount(){
	long count = userService.count();
	System.out.println("总记录数:" + count);
}
  1. 测试批量插入
java 复制代码
@Test
public void testSaveBatch(){
	// SQL长度有限制,海量数据插入单条SQL无法实行,
	// 因此MP将批量插入放在了通用Service中实现,而不是通用Mapper
	ArrayList<User> users = new ArrayList<>();
	for (int i = 0; i < 5; i++) {
		User user = new User();
		user.setName("ybc" + i);
		user.setAge(20 + i);
		users.add(user);
	}
	//SQL:INSERT INTO t_user ( username, age ) VALUES ( ?, ? )
	userService.saveBatch(users);
}

3. 常用注解

3.1. @TableName

MyBatis-Plus在确定操作的表时,由BaseMapper的泛型决定,即实体类型决定,且默认操作的表名和实体类型的类名一致

  1. 问题:若实体类类型的类名和要操作的表的表名不一致,会出现什么问题?
    程序抛出异常,Table 'mybatis_plus.user' doesn't exist,因为现在的表名为t_user,而默认操作的表名和实体类型的类名一致,即user表
  2. 解决:
    1. 使用@TableName:在实体类类型上添加@TableName("t_user"),标识实体类对应的表,即可成功执行SQL语句
    2. 通过全局配置解决问题:使用MyBatis-Plus提供的全局配置,为实体类所对应的表名设置默认的前缀
java 复制代码
mybatis-plus:
	configuration:
		# 配置MyBatis日志
		log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
	global-config:
		db-config:
			# 配置MyBatis-Plus操作表的默认前缀
			table-prefix: t_

3.2. @TableId

MyBatis-Plus在实现CRUD时,会默认将id作为主键列,并在插入数据时,默认基于雪花算法的策略生成id

  1. 问题:若实体类和表中表示主键的不是id,而是其他字段,例如uid,MyBatis-Plus会自动识别uid为主
    键列吗?
    程序抛出异常,Field 'uid' doesn't have a default value,说明MyBatis-Plus没有将uid作为主键
    赋值
  2. 解决
    1. @TableId:在实体类中uid属性上通过@TableId将其标识为主键,即可成功执行SQL语句
    2. @TableId的value属性:@TableId("uid")或@TableId(value="uid")
    3. @TableId的type属性:type属性用来定义主键策略
      • IdType.ASSIGN_ID(默认):雪花算法的策略生成数据id,与数据库id是否设置自增无关
      • IdType.AUTO:使用数据库的自增策略,注意,该类型请确保数据库设置了id自增,否则无效
java 复制代码
mybatis-plus:
	configuration:
		# 配置MyBatis日志
		log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
	global-config:
		db-config:
		# 配置MyBatis-Plus操作表的默认前缀
		table-prefix: t_
		# 配置MyBatis-Plus的主键策略
		id-type: auto

3.3. @TableField

  1. 问题:MyBatis-Plus在执行SQL语句时,要保证实体类中的属性名和表中的字段名一致,如果实体类中的属性名和字段名不一致的情况,会出现什么问题呢?
  2. 解决:
    1. 若实体类中的属性使用的是驼峰命名风格,而表中的字段使用的是下划线命名风格,此时MyBatis-Plus会自动将下划线命名风格转化为驼峰命名风格
    2. 若实体类中的属性和表中的字段不满足情况1,此时需要在实体类属性上使用@TableField("username")设置属性所对应的字段名

3.4. @TableLogic

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
  • 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为"被删除状态",之后在数据库中仍旧能看到此条数据记录 => 在实体类中添加@TableLogic属性
  • 使用场景:可以进行数据恢复

4. 条件构造器和常用接口

4.1. wapper介绍

  • Wrapper : 条件构造抽象类,最顶端父类
    • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
      • QueryWrapper : 查询条件封装
      • UpdateWrapper : Update 条件封装
      • AbstractLambdaWrapper : 使用Lambda 语法
        • LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
        • LambdaUpdateWrapper : Lambda 更新封装Wrapper

4.2. QueryWrapper

  1. 组装查询条件
java 复制代码
@Test
public void test01(){
	//查询用户名包含a,年龄在20到30之间,并且邮箱不为null的用户信息
	//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE
	is_deleted=0 AND (username LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper.like("username", "a").between("age", 20, 30).isNotNull("email");
	List<User> list = userMapper.selectList(queryWrapper);
	list.forEach(System.out::println);
}
  1. 组装排序条件
java 复制代码
@Test
public void test02(){
	//按年龄降序查询用户,如果年龄相同则按id升序排列
	//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE
	is_deleted=0 ORDER BY age DESC,id ASC
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper.orderByDesc("age").orderByAsc("id");
	List<User> users = userMapper.selectList(queryWrapper);
	users.forEach(System.out::println);
}
  1. 组装删除条件
java 复制代码
@Test
public void test03(){
	//删除email为空的用户
	//DELETE FROM t_user WHERE (email IS NULL)
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper.isNull("email");
	//条件构造器也可以构建删除语句的条件
	int result = userMapper.delete(queryWrapper);
	System.out.println("受影响的行数:" + result);
}
  1. 条件的优先级
java 复制代码
@Test
public void test04() {
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	//将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
	//UPDATE t_user SET age=?, email=? WHERE (username LIKE ? AND age > ? OR
	email IS NULL)
	queryWrapper.like("username", "a").gt("age", 20).or().isNull("email");
	User user = new User();
	user.setAge(18);
	user.setEmail("user@163.com");
	int result = userMapper.update(user, queryWrapper);
	System.out.println("受影响的行数:" + result);
}
java 复制代码
@Test
public void test04() {
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	//将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
	//UPDATE t_user SET age=?, email=? WHERE (username LIKE ? AND (age > ? OR email IS NULL))
	//lambda表达式内的逻辑优先运算
	queryWrapper.like("username", "a").and(i -> i.gt("age", 20).or().isNull("email"));
	User user = new User();
	user.setAge(18);
	user.setEmail("user@163.com");
	int result = userMapper.update(user, queryWrapper);
	System.out.println("受影响的行数:" + result);
}
  1. 组装select子句
java 复制代码
@Test
public void test05() {
	//查询用户信息的username和age字段
	//SELECT username,age FROM t_user
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper.select("username", "age");
	//selectMaps()返回Map集合列表,通常配合select()使用,避免User对象中没有被查询到的列值
	为null
	List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
	maps.forEach(System.out::println);
}
  1. 实现子查询
java 复制代码
@Test
public void test06() {
	//查询id小于等于3的用户信息
	//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE (id IN
	(select id from t_user where id <= 3))
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper.inSql("id", "select id from t_user where id <= 3");
	List<User> list = userMapper.selectList(queryWrapper);
	list.forEach(System.out::println);
}

4.3. UpdateWrapper

java 复制代码
@Test
public void test07() {
	//将(年龄大于20或邮箱为null)并且用户名中包含有a的用户信息修改
	//组装set子句以及修改条件
	UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
	//lambda表达式内的逻辑优先运算
	updateWrapper.set("age", 18).set("email", "user@163.com").like("username", "a").and(i -> i.gt("age", 20).or().isNull("email"));
	//这里必须要创建User对象,否则无法应用自动填充。如果没有自动填充,可以设置为null
	//UPDATE t_user SET username=?, age=?,email=? WHERE (username LIKE ? AND (age > ? OR email IS NULL))
	//User user = new User();
	//user.setName("张三");
	//int result = userMapper.update(user, updateWrapper);
	//UPDATE t_user SET age=?,email=? WHERE (username LIKE ? AND (age > ? OR email IS NULL))
	int result = userMapper.update(null, updateWrapper);
	System.out.println(result);
}

4.4. condition

在组装条件时,必须先判断用户是否选择了这些条件,若选择则需要组装该条件,若没有选择则不能组装,以免影响SQL执行的结果

  1. 实现一:
java 复制代码
@Test
public void test08() {
	//定义查询条件,有可能为null(用户未输入或未选择)
	String username = null;
	Integer ageBegin = 10;
	Integer ageEnd = 24;
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	//StringUtils.isNotBlank()判断某字符串是否不为空且长度不为0且不由空白符(whitespace) 构成
	if(StringUtils.isNotBlank(username)){
		queryWrapper.like("username","a");
	}
	if(ageBegin != null){
		queryWrapper.ge("age", ageBegin);
	}
	if(ageEnd != null){
		queryWrapper.le("age", ageEnd);
	}
	//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE (age >= ? AND age <= ?)
	List<User> users = userMapper.selectList(queryWrapper);
	users.forEach(System.out::println);
}

缺点:代码复杂,可以使用带condition参数的重载方法构建查询条件,简化代码的编写

  1. 实现二:
java 复制代码
@Test
public void test08UseCondition() {
	//定义查询条件,有可能为null(用户未输入或未选择)
	String username = null;
	Integer ageBegin = 10;
	Integer ageEnd = 24;
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	//StringUtils.isNotBlank()判断某字符串是否不为空且长度不为0且不由空白符(whitespace) 构成
	queryWrapper.like(StringUtils.isNotBlank(username), "username", "a").ge(ageBegin != null, "age", ageBegin).le(ageEnd != null, "age", ageEnd);
	//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE (age >= ? AND age <= ?)
	List<User> users = userMapper.selectList(queryWrapper);
	users.forEach(System.out::println);
}

4.5. LambdaQueryWrapper

java 复制代码
@Test
public void test09() {
	//定义查询条件,有可能为null(用户未输入)
	String username = "a";
	Integer ageBegin = 10;
	Integer ageEnd = 24;
	LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
	//避免使用字符串表示字段,防止运行时错误
	queryWrapper.like(StringUtils.isNotBlank(username), User::getName, username).ge(ageBegin != null, User::getAge, ageBegin).le(ageEnd != null, User::getAge, ageEnd);
	List<User> users = userMapper.selectList(queryWrapper);
	users.forEach(System.out::println);
}

4.6. LambdaUpdateWrapper

java 复制代码
@Test
public void test10() {
	//组装set子句
	LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
	updateWrapper.set(User::getAge, 18).set(User::getEmail, "user@163.com").like(User::getName, "a").and(i -> i.lt(User::getAge, 24).or().isNull(User::getEmail)); //lambda表达式内的逻辑优先运算
	User user = new User();
	int result = userMapper.update(user, updateWrapper);
	System.out.println("受影响的行数:" + result);
}

5. 插件

5.1. 分页插件

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

  1. 添加配置类
java 复制代码
@Configuration
@MapperScan("com.wyb.mybatisplus.mapper") //可以将主类中的注解移到此处
public class MybatisPlusConfig {
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
		return interceptor;
	}
}
  1. 测试
java 复制代码
@Test
public void testPage(){
	//设置分页参数
	Page<User> page = new Page<>(1, 5);
	userMapper.selectPage(page, null);
	//获取分页数据
	List<User> list = page.getRecords();
	list.forEach(System.out::println);
	System.out.println("当前页:"+page.getCurrent());
	System.out.println("每页显示的条数:"+page.getSize());
	System.out.println("总记录数:"+page.getTotal());
	System.out.println("总页数:"+page.getPages());
	System.out.println("是否有上一页:"+page.hasPrevious());
	System.out.println("是否有下一页:"+page.hasNext());
}

5.2. xml自定义分页

  1. UserMapper中定义接口方法
java 复制代码
/**
* 根据年龄查询用户列表,分页显示
* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位
* @param age 年龄
* @return
*/
Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
  1. UserMapper.xml中编写SQL
java 复制代码
<!--SQL片段,记录基础字段-->
<sql id="BaseColumns">id,username,age,email</sql>
<!--IPage<User> selectPageVo(Page<User> page, Integer age);-->
<select id="selectPageVo" resultType="User">
	SELECT <include refid="BaseColumns"></include> FROM t_user WHERE age > #{age}
</select>
  1. 测试
java 复制代码
@Test
public void testSelectPageVo(){
	//设置分页参数
	Page<User> page = new Page<>(1, 5);
	userMapper.selectPageVo(page, 20);
	//获取分页数据
	List<User> list = page.getRecords();
	list.forEach(System.out::println);
	System.out.println("当前页:"+page.getCurrent());
	System.out.println("每页显示的条数:"+page.getSize());
	System.out.println("总记录数:"+page.getTotal());
	System.out.println("总页数:"+page.getPages());
	System.out.println("是否有上一页:"+page.hasPrevious());
	System.out.println("是否有下一页:"+page.hasNext());
}

5.3. 乐观锁与悲观锁

  1. 乐观锁实现流程
    数据库中添加version字段,取出记录时,获取当前version
    更新时,version + 1,如果where语句中的version版本不对,则更新失败
  2. Mybatis-Plus实现乐观锁
  • 修改实体类
java 复制代码
package com.wyb.mybatisplus.entity;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
@Data
public class Product {
	private Long id;
	private String name;
	private Integer price;
	@Version
	private Integer version;
}
  • 添加乐观锁插件配置
java 复制代码
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
	MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
	//添加分页插件
	interceptor.addInnerInterceptor(new
	PaginationInnerInterceptor(DbType.MYSQL));
	//添加乐观锁插件
	interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
	return interceptor;
}

6. 通用枚举

6.1. 创建通用枚举类型

java 复制代码
package com.wyb.mp.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
@Getter
public enum SexEnum {
	MALE(1, "男"),
	FEMALE(2, "女");
	@EnumValue
	private Integer sex;
	private String sexName;
	SexEnum(Integer sex, String sexName) {
		this.sex = sex;
		this.sexName = sexName;
	}
}

6.2. 配置扫描通用枚举

java 复制代码
mybatis-plus:
	configuration:
		# 配置MyBatis日志
		log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
	global-config:
		db-config:
			# 配置MyBatis-Plus操作表的默认前缀
			table-prefix: t_
			# 配置MyBatis-Plus的主键策略
			id-type: auto
	# 配置扫描通用枚举
	type-enums-package: com.wyb.mybatisplus.enums

6.3. 测试

java 复制代码
@Test
public void testSexEnum(){
	User user = new User();
	user.setName("Enum");
	user.setAge(20);
	//设置性别信息为枚举项,会将@EnumValue注解所标识的属性值存储到数据库
	user.setSex(SexEnum.MALE);
	//INSERT INTO t_user ( username, age, sex ) VALUES ( ?, ?, ? )
	//Parameters: Enum(String), 20(Integer), 1(Integer)
	userMapper.insert(user);
}

7. 代码生成器

7.1. 引入依赖

xml 复制代码
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-generator</artifactId>
	<version>3.5.1</version>
	</dependency>
	<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
	<version>2.3.31</version>
</dependency>

7.2. 快速生成

java 复制代码
public class FastAutoGeneratorTest {
	public static void main(String[] args) {
		FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=utf-8&userSSL=false", "root", "123456")
		.globalConfig(builder -> {
			builder.author("wyb") // 设置作者
			//.enableSwagger() // 开启 swagger 模式
			.fileOverride() // 覆盖已生成文件
			.outputDir("D://mybatis_plus"); // 指定输出目录
			})
		.packageConfig(builder -> {
			builder.parent("com.wyb") // 设置父包名
			.moduleName("mybatisplus") // 设置父包模块名
			.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://mybatis_plus"));
			// 设置mapperXml生成路径
		})
		.strategyConfig(builder -> {
			builder.addInclude("t_user") // 设置需要生成的表名
			.addTablePrefix("t_", "c_"); // 设置过滤表前缀
		})
		.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
		.execute();
	}
}

8. 多数据源

java 复制代码
spring:
	# 配置数据源信息
	datasource:
		dynamic:
		# 设置默认的数据源或者数据源组,默认值即为master
		primary: master
		# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
		strict: false
		datasource:
			master:
				url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-
				8&useSSL=false
				driver-class-name: com.mysql.cj.jdbc.Driver
				username: root
				password: 123456
			slave_1:
				url: jdbc:mysql://localhost:3306/mybatis_plus_1?characterEncoding=utf-
				8&useSSL=false
				driver-class-name: com.mysql.cj.jdbc.Driver
				username: root
				password: 123456
相关推荐
码上一元1 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
计算机-秋大田1 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
魔道不误砍柴功3 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
失落的香蕉3 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
枫叶_v3 小时前
【SpringBoot】22 Txt、Csv文件的读取和写入
java·spring boot·后端
wclass-zhengge3 小时前
SpringCloud篇(配置中心 - Nacos)
java·spring·spring cloud
路在脚下@3 小时前
Springboot 的Servlet Web 应用、响应式 Web 应用(Reactive)以及非 Web 应用(None)的特点和适用场景
java·spring boot·servlet
黑马师兄3 小时前
SpringBoot
java·spring
数据小小爬虫3 小时前
如何用Java爬虫“偷窥”淘宝商品类目API的返回值
java·爬虫·php
暮春二十四3 小时前
关于用postman调用接口成功但是使用Java代码调用却失败的问题
java·测试工具·postman