一、MyBatis-Plus简介
1、简介
MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为 简化开发、提高效率而生。
我们的愿景是成为 MyBatis 最好的搭档,就像魂斗罗中的 1P、2P,基友搭配,效率翻倍。
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 操作智能分析阻断,也可自定义拦截规则,预防误操作
3、支持数据库
任何能使用
MyBatis
进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下,如果不在下列表查看分页部分教程 PR 您的支持。
- MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
- 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
4、框架结构
5、代码及文档地址
官方地址: http://mp.baomidou.com
代码发布地址:
文档发布地址: https://baomidou.com/pages/24112f
二、入门案例
1、建表
我们使用Mysql8版本
创建表
CREATE DATABASE `mybatis_plus` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
use `mybatis_plus`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
添加数据
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');
2、导入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
其中,lombok只是为了简化我们实体类的代码
IDEA 2020.3及以上版本已经内置Lombok plugin了,无需安装插件
3、application.yml
spring:
# 配置数据源信息
datasource:
# 配置数据源类型
type: com.zaxxer.hikari.HikariDataSource
# 配置连接数据库信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
username: root
password: root
#配置mybatis日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 配置MyBatis-Plus操作表的默认前缀
global-config:
db-config:
table-prefix: t_
# 配置MyBatis-Plus的主键策略
# id-type: auto
# 配置类型别名所对应的包
# type-aliases-package: com.zl.po
4、启动类
在Spring Boot启动类中添加@MapperScan注解,扫描mapper包
package com.zl;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @date 2022-05-15
* @author ZL
*/
@SpringBootApplication
@MapperScan("com.zl.mapper")
public class MybatisPlusDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusDemoApplication.class, args);
}
}
5、实体类
package com.zl.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author zl
* @time 2022/5/15
*/
@Data
@TableName("t_user")
public class User {
//@TableId("uid")
private Long id;
//@TableField("user_name")
private String name;
private Integer age;
private String email;
/**
* 逻辑删除
*/
//@TableLogic
// private Integer isDeleted;
}
6、通用Mapper接口
package com.zl.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zl.po.User;
import org.springframework.stereotype.Repository;
/**
* @author zl
* @time 2022/5/15
*/
@Repository
public interface UserMapper extends BaseMapper<User> {
}
7、测试
package com.zl;
import com.zl.mapper.UserMapper;
import com.zl.po.User;
import com.zl.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.*;
/**
* 通用Mapper测试
*/
@SpringBootTest
class MybatisPlusTest {
@Autowired
private UserMapper userMapper;
/**
* 查询所有
* SELECT id,name,age,email FROM user
*/
@Test
void testSelectList() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
}
三、进阶
1、不同数据库yml配置
Mysql
spring:
# 配置数据源信息
datasource:
# 配置数据源类型
type: com.zaxxer.hikari.HikariDataSource
# 配置连接数据库信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
username: root
password: root
#配置mybatis日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 配置MyBatis-Plus操作表的默认前缀
global-config:
db-config:
table-prefix: t_
# 配置MyBatis-Plus的主键策略
# id-type: auto
# 配置类型别名所对应的包
# type-aliases-package: com.zl.po
其中mysql8的url为:
jdbc:mysql://localhost:3307/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
mysql5的url为:
jdbc:mysql://localhost:3307/mybatis_plus?characterEncoding=utf-8&useSSL=false
Sqlserver
# DataSource Config
spring:
datasource:
username: sa
password: root
url: jdbc:sqlserver://localhost:1433;DatabaseName=test
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
Oracle
spring:
datasource:
driverClassName: oracle.jdbc.OracleDriver
username: root
password: root
url: jdbc:oracle:thin:@//localhost:1521/test
2、通用Service接口
Uservice
package com.zl.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zl.po.User;
/**
* @author zl
* @time 2022/5/15
*/
public interface UserService extends IService<User> {
}
UserServiceImpl
package com.zl.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zl.mapper.UserMapper;
import com.zl.po.User;
import com.zl.service.UserService;
import org.springframework.stereotype.Service;
/**
* @author zl
* @time 2022/5/15
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
3、通用Mapper和通用Service常规用法
package com.zl;
import com.zl.mapper.UserMapper;
import com.zl.po.User;
import com.zl.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.*;
/**
* 通用Mapper测试
*/
@SpringBootTest
class MybatisPlusTest {
@Autowired
private UserMapper userMapper;
@Autowired
private UserService userService;
/**
* 查询所有
* SELECT id,name,age,email FROM user
*/
@Test
void testSelectList() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
/**
* 插入
* INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
*/
@Test
void testInsert(){
User user = new User();
user.setName("张三");
user.setAge(23);
user.setEmail("zhangsan@163.com");
int result = userMapper.insert(user);
System.out.println("受影响的行数:"+result);
System.out.println("新建的ID:"+user.getId());
}
/**
* 根据ID删除
* DELETE FROM user WHERE id=?
*/
@Test
void testDeleteById(){
int result = userMapper.deleteById(1525835539440345090L);
System.out.println("受影响的行数:"+result);
}
/**
* 根据ID批量删除
* DELETE FROM user WHERE id IN ( ? , ? )
*/
@Test
void testDeleteBatchIds(){
int result = userMapper.deleteBatchIds(Arrays.asList(1L, 2L));
System.out.println("受影响的行数:"+result);
}
/**
* 根据Map删除
* DELETE FROM user WHERE name = ? AND age = ?
*/
@Test
void testDeleteByMap(){
Map<String,Object> map = new HashMap<>();
map.put("age",21);
map.put("name","Sandy");
int result = userMapper.deleteByMap(map);
System.out.println("受影响的行数:"+result);
}
/**
* 根据ID更新
* UPDATE user SET name=?, age=? WHERE id=?
*/
@Test
void testUpdateById(){
User user = new User();
user.setId(5L);
user.setName("admin");
user.setAge(33);
int result = userMapper.updateById(user);
System.out.println("受影响的行数:"+result);
}
/**
* 根据ID查询
* SELECT id,name,age,email FROM user WHERE id=?
*/
@Test
void testSelectById(){
User user = userMapper.selectById(5L);
System.out.println(user);
}
/**
* 根据ID批量查询
* SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
*/
@Test
void testSelectByBatchIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(3L, 5L));
users.forEach(System.out::println);
}
/**
* 根据Map查询
* SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
*/
@Test
void testSelectByMap(){
Map<String,Object> map = new HashMap<>();
map.put("name","admin");
map.put("age",33);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
/**
* 查询总记录数
* SELECT COUNT( * ) FROM user
*/
@Test
void testGetCount(){
long count = userService.count();
System.out.println("总记录数:"+count);
}
/**
* 批量插入:执行10次
* INSERT INTO user ( id, name, age ) VALUES ( ?, ?, ? )
*/
@Test
void testSaveBatch(){
List<User> userList = new ArrayList<>();
for (int i=0;i<10;i++){
User user = new User();
user.setName("zl" + i);
user.setAge(20 + i);
userList.add(user);
}
boolean flag = userService.saveBatch(userList);
System.out.println("插入是否成功:"+flag);
}
}
4、Wrapper常规用法
package com.zl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zl.mapper.UserMapper;
import com.zl.po.User;
import com.zl.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import java.util.Map;
/**
* Wrapper测试
* @author zl
* @time 2022/5/15
*/
@SpringBootTest
public class MybatisPlusWrapperTest {
@Autowired
private UserMapper userMapper;
@Autowired
private UserService userService;
/**
* 查询用户名包含a,年龄在20到30之间,并且邮箱不为null的用户信息
* SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (user_name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
*/
@Test
void test01(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","a")
.between("age",20,30)
.isNotNull("email");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 按年龄降序查询用户,如果年龄相同则按id升序排列
* SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 ORDER BY age DESC,uid ASC
*/
@Test
void test02(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("age").orderByAsc("uid");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 删除email为空的用户
* UPDATE t_user SET is_deleted=1 WHERE is_deleted=0 AND (email IS NULL)
*/
@Test
void test03(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("email");
int result = userMapper.delete(queryWrapper);
System.out.println("影响的行数:"+result);
}
/**
* 将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
* UPDATE t_user SET age=?, email=? WHERE is_deleted=0 AND (age >= ? AND user_name LIKE ? OR email IS NULL)
*/
@Test
void test04(){
User user = new User();
user.setAge(10);
user.setEmail("zl@163.com");
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age",20)
.like("user_name","a")
.or()
.isNull("email");
int result = userMapper.update(user, queryWrapper);
System.out.println("受影响的行数:"+result);
}
/**
* 将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
* UPDATE t_user SET age=?, email=? WHERE is_deleted=0 AND (user_name LIKE ? AND (age >= ? OR email IS NULL))
*/
@Test
void test05(){
User user = new User();
user.setAge(15);
user.setEmail("zl2@163.com");
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("user_name","a")
.and(i->i.ge("age",20).or().isNull("email"));
int result = userMapper.update(user, queryWrapper);
System.out.println("受影响的行数:"+result);
}
//todo 组装select子句
/**
* 查询用户信息的username和age字段
* SELECT user_name,age FROM t_user WHERE is_deleted=0
*/
@Test
void test06(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("user_name","age");
//selectMaps()返回Map集合列表,通常配合select()使用,避免User对象中没有被查询到的列值为null
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
maps.forEach(System.out::println);
}
/**
* 将(年龄大于20或邮箱为null)并且用户名中包含有a的用户信息修改
* UPDATE t_user SET age=?,email=? WHERE is_deleted=0 AND (user_name LIKE ? AND (age > ? OR email IS NULL))
*/
@Test
void test07(){
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("age",18)
.set("email","zl@163.com")
.like("user_name","a")
.and(i->i.gt("age",20).or().isNull("email"));
int result = userMapper.update(null, updateWrapper);
System.out.println("影响行数:"+result);
}
/**
* Condition条件
* SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (age >= ? AND age <= ?)
*/
@Test
void test08(){
//定义查询条件,有可能为null(用户未输入或未选择)
String username = null;
Integer ageBegin = 10;
Integer ageEnd = 24;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(username), "username", "a")
.ge(ageBegin != null, "age", ageBegin)
.le(ageEnd != null, "age", ageEnd);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
@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);
}
@Test
public void test10() {
//组装set子句
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
.set(User::getAge, 18)
.set(User::getEmail, "user@atguigu.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、分页和乐观锁
1) 分页
配置类-包含分页和乐观锁
package com.zl.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 插件配置类-包含分页插件、乐观锁
* @author zl
* @time 2022/5/16
*/
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
简单测试--查询所有
/**
* 分页
* SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 LIMIT ?,?
*/
@Test
void testPage(){
//当前页、每页显示条数
Page<User> page = new Page<>(1,2);
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());
}
自定义分页接口
Mapper
/**
* 根据年龄查询用户列表,分页显示
* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位
* @param age 年龄
* @return
*/
Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
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.zl.mapper.UserMapper">
<!-- 当实体类的属性名称和数据库的列名不一致时,需要用resultMap映射 -->
<resultMap id="UserMap" type="User">
<!-- id为主键 -->
<id column="id" property="id"/>
<!-- column是数据库表的列名 , property是对应实体类的属性名 -->
<result column="uid" property="id"/>
<result column="user_name" property="name"/>
</resultMap>
<!--Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);-->
<select id="selectPageVo" resultMap="UserMap">
select uid,user_name,age,email from t_user where age > #{age}
</select>
</mapper>
测试类
/**
*
* 自定义分页接口
*/
@Test
public void testSelectPageVo(){
//设置分页参数
Page<User> page = new Page<>(1, 2);
userMapper.selectPageVo(page, 10);
//获取分页数据
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());
}
2) 乐观锁
数据库表要增加一个字段version
然后用注解@Version
package com.zl.po;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
/**
* @author zl
* @time 2022/5/16
*/
@Data
public class Product {
private Long id;
private String name;
private Integer price;
@Version
private Integer version;
}
测试代码
/**
* 乐观锁
*/
@Test
public void testProduct01(){
//小李查询商品价格
Product productLi = productMapper.selectById(1);
System.out.println("小李查询的商品价格:"+productLi.getPrice());
//小王查询商品价格
Product productWang = productMapper.selectById(1);
System.out.println("小王查询的商品价格:"+productWang.getPrice());
//小李将商品价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//小王将商品价格-30
productWang.setPrice(productWang.getPrice()-30);
int result = productMapper.updateById(productWang);
if(result == 0){
//操作失败,重试
Product productNew = productMapper.selectById(1);
productNew.setPrice(productNew.getPrice()-30);
productMapper.updateById(productNew);
}
//老板查询商品价格
Product productLaoban = productMapper.selectById(1);
System.out.println("老板查询的商品价格:"+productLaoban.getPrice());
}
6、代码生成器
依赖
<!-- 代码生成器 -->
<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>
测试类
package com.zl;
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 zl
* @time 2022/5/16
*/
public class FastAutoGeneratorTest {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3307/mybatis_plus?characterEncoding=utf-8&userSSL=false", "root", "root")
.globalConfig(builder -> {
builder.author("zl") // 设置作者
//.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("D://mybatis_plus"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.zl") // 设置父包名
.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();
}
}
7、多数据源
依赖
<!-- 多数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
配置文件
spring:
# 配置数据源信息
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3307/mybatis_plus?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
slave_1:
url: jdbc:mysql://localhost:3307/mybatis_plus_1?characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
type-aliases-package: com.zl.po
在UserServiceImpl上加上注解@DS
package com.zl.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zl.mapper.UserMapper;
import com.zl.po.User;
import com.zl.service.UserService;
import org.springframework.stereotype.Service;
/**
* @author zl
* @time 2022/5/15
*/
//指定所操作的数据源
@DS("master")
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
8、MybatisX插件
MyBatis-Plus为我们提供了强大的mapper和service模板,能够大大的提高开发效率
但是在真正开发过程中,MyBatis-Plus并不能为我们解决所有问题,例如一些复杂的SQL,多表 联查,我们就需要自己去编写代码和SQL语句,我们该如何快速的解决这个问题呢,这个时候可 以使用MyBatisX插件 MyBatisX一款基于 IDEA 的快速开发插件,为效率而生。
MyBatisX插件用法:https://baomidou.com/pages/ba5b24