目录
一、概述
这个Mybatis Plus(以下简称MP)是什么东西呢?
Mybatis相信很多小伙伴都用过,是目前市面上非常火的ORM框架。而MP则是一个Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发、提高效率而生。最重要的一点,它是国产的(骄傲)。
在官网中我能可以看到MP的愿景是:
成为 MyBatis 最好的搭档,就像魂斗罗中的 1P、2P,基友搭配,效率翻倍。
它有以下特性:
-
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
-
损耗小:启动即会自动注入基本 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的增强,所以只要Mybatis能支持的数据库,它都支持。
二、框架结构
以上内容均来自官网。
2.1 框架剖析
废话不多说,好不好用,用起来看看!
1.创建工程
选择上图中的几个组件,这里我们不需要再选择Mybatis Framework了。
直接创建
等待依赖下载完毕。
2.添加Mybatis Plus的依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
3.支持的数据库类型
依赖下载完后可以看到一共导入了五个Jar包
在mybatis-plus-annotation:3.3.1.tmp这个jar包中
我们能看到它所支持的数据库类型
4.自动配置
在mybatis-plus-boot-starter:3.3.1.tmp这个jar包中
这个配置文件相信大家肯定已经很熟悉了,要想在Spring Boot中开箱即用,肯定需要被Spring Boot自动配置。
spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
可以看到我们的Mybatis Plus会自动装载两个类。
MybatisPlusAutoConfiguration.class
-
@Configuration注解声明它是一个配置类。
-
@ConditionalOnClass这个条件注解告诉Spring容器里面得有SqlSessionFactory.class, SqlSessionFactoryBean.class这两个类,才会加载MybatisPlusAutoConfiguration.class这个类。
-
这里还有一个很有意思的注解:@AutoConfigureAfter。这个注解什么意思呢?就是在加载配置的类之后再加载当前类。意思必须先加载DataSourceAutoConfiguration.class这个类,才会加载MybatisPlusAutoConfiguration.class这个类。
DataSourceAutoConfiguration.class
可以看到它也是一个配置类。它这里使用@EnableConfigurationProperties注解为当前类注入属性,从DataSourceProperties.class这个类中。
DataSourceProperties.class
@ConfigurationProperties这个注解表示我们会从配置文件里面,前缀是spring.datasource这个的配置项中读取属性值。读取属性值后,加载到当前类中,给成员变量赋值。
可以看到这个类中都是一些比较熟悉的属性:url、username、password等等。这些属性的值就从配置文件里面前缀是spring.datasource的配置项中来。
所以现在我们可以来给配置文件添加一些简单的配置项。
application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp_test_db?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
现在这几个配置项就会填充到DataSourceProperties.class类的对应属性中了。
这样我们Spring Boot中集成的Mybatis就可以和数据库连接了。
数据库不会安装的小伙伴们可参考
MYSQL 学习指南 (看完这篇就够了,万字收藏!!!)_mysql入门教程-CSDN博客
2.2 基本使用
注意:集成mybatis-plus要把mybatis、mybatis-spring去掉,避免冲突。
我们先在 mp_test_db 库中创建一张表 user。
SET NAMES utf8mb4;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int NOT NULL auto_increment COMMENT '主键id',
`name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
`age` int NOT NULL COMMENT '年龄',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
插入几条测试数据
INSERT into user(name, age) values('张三', 32);
INSERT into user(name, age) values('李四', 18);
INSERT into user(name, age) values('王五', 23);
创建实体类
@Data
public class User {
/**
* 主键id
*/
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
2.2.1 创建 Mapper 接口
这个用过Mybatis的小伙伴应该都很清楚哈,这里我不再细说什么是 Mapper 接口了。
这里和Mybatis有所不同的是,你只需要创建接口即可,并不需要创建具体的实现类。有点类似 Spring Data JPA,一样的套路。
这里我们只需要继承MP的父接口 BaseMapper 即可。
public interface UserMapper extends BaseMapper<User> {
}
写完 Mapper 接口,别忘了在主启动类上加上
@MapperScan("com.age.mybatisplus.mapper")
否则一会工程启动时候,会找不到 Mapper。
2.2.2 测试
mport org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
@SpringBootTest
class UserMapperTest {
@Resource
private UserMapper userMapper;
@Test
void test() {
// 不加条件,查询user表所有的数据
userMapper.selectList(null).forEach(System.out::println);
}
}
它这里帮我们把一些增删改查的接口,全都写好了,让我们可以更加愉快的crud!
在上面的控制台日志中可以看到并没有打印SQL语句,其实我们可以设置的,在application.yml中添加
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl这一段配置,日志里面就可以打印SQL语句了。
以上就是Mybatis Plus的基本使用。
三、常用注解
其实我们现在开发的话呢,其实都比较少使用xml文件了,很多时候都是通过注解的方式。
我们可以看些MP常用的注解都有哪些,以及怎么使用。
3.1 @TableName
作用:用来映射数据库的表名。
刚才上面的例子中我们可以看到,为什么MP会准确找到user这张表进行查询?是不是就是因为我们创建的实体类,名字就叫User,所以可以和数据库中的user表对应起来的关系。
那假如现在我的实例类名称换成Student,看下什么效果
它就会提示我Table 'mp_test_db.student' doesn't exist。
那么有时候我的实体类名称不一定和数据库中的表名能完全对应上,这时候@TableName注解就派上用场了。
我们可以在Student实体类加上这个注解
@Data
@TableName(value = "user")
public class Student {
现在又会是查询user这张表了。
3.2 @TableField
@TableName注解是把实体类和表做映射,那么表里面还有字段信息,类属性和表字段肯定也是一一映射的。
如果类属性和表字段无法一一对应时,假如我将 ”name“ 这个属性修改为 ”userName“
这时候我们只需要@TableField注解的 value 属性即可解决
/**
* 姓名
*/
@TableField(value = "name")
private String userName;
除了value属性之外,还有两个我们需要关注的属性。
3.2.1 exist
当我们的实体类中定义了一些数据库中不存在的字段时
/**
* 外号
* 数据库不存在的字段
*/
private String nickname;
调用一下查询接口
发现会报错:Unknown column 'nickname' in 'field list'。
遇到这种情况怎么办?我们只需要设置一下exist属性即可解决
/**
* 外号
* 数据库不存在的字段
*/
@TableField(exist = false)
private String nickname;
再运行一下
现在没问题了。
3.2.2 select
该属性表示是否查询该字段。
/**
* 年龄
*/
@TableField(select = false)
private Integer age;
SQL语句中就不再查询age这个字段了。
3.2.3 fill
表示是否自动填充。
在我们日常的开发工作中,数据库表里面通常都会有create_time、update_time字段,而这两个字段通常都是取当前时间来插入,我们就需要使用到自动填充。
我们现在数据库中新增create_time、update_time字段
然后在实体类中新增两个属性
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
这里可以看到fill中还有FieldFill这个枚举类
public enum FieldFill {
DEFAULT,
INSERT,
UPDATE,
INSERT_UPDATE;
private FieldFill() {
}
}
它这里代表四个动作:
-
DEFAULT:不填充
-
INSERT:在插入的时候填充
-
UPDATE:在更新的时候填充
-
INSERT_UPDATE:在插入或者更新时填充
做完这些,程序还不会帮我们自动去填充这两个字段,我们需要创建一个处理器
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
public class MyMetaObjectHandler implements MetaObjectHandler {
}
需要继承MetaObjectHandler这个接口,这是mybatisplus给我们提供的一个处理器,实现这个接口中的两个方法
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 此处的metaObject代表当前对象
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
现在来保存数据试试
@Test
void save() {
User user = new User();
user.setName("王五");
user.setAge(30);
mapper.insert(user);
}
我们的两个时间已经顺利插入进来了。
3.3 @TableId
上面的@TableField注解是用来处理数据库中普通字段的,@TableId是用于处理主键字段的。
这注解中有几个属性需要重点关注一下:
3.3.1 value
映射主键id的字段名
/**
* 主键id
*/
@TableId(value = "id")
private Long userId;
3.3.2 type
设置主键类型,主键的生成策略。这个type的值是使用一组枚举类型来表示的,它一共有五种类型
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ASSIGN_ID(3),
ASSIGN_UUID(4),
/** @deprecated */
@Deprecated
ID_WORKER(3),
/** @deprecated */
@Deprecated
ID_WORKER_STR(3),
/** @deprecated */
@Deprecated
UUID(4);
private final int key;
private IdType(int key) {
this.key = key;
}
public int getKey() {
return this.key;
}
}
其中用@Deprecated注解标注的类型表示已经被弃用,无需再关注。
类型 | 描述 |
---|---|
AUTO | 数据库自增 |
NONE(默认) | MP来设置主键,使用雪花算法实现 |
INPUT | 需要自己给主键赋值 |
ASSIGN_ID | MP使用Long、Integer、String来分配ID |
ASSIGN_UUID | MP分配UUID |
NONE
首先看一下默认的NONE类型。
在测试类中新增一个方法
@Test
void save() {
User user = new User();
user.setName("赵六");
user.setAge(12);
mapper.insert(user);
}
执行后发现报错了
提示我:Data truncation: Out of range value for column 'id' at row 1
由于NONE类型是雪花算法生成一串数字,所以推测应该是数据库中字段长度不够了。
我们改一下
修改为BIGINT(100)
然后我们再来试一下
可以看到数据已经插进去了,主键是1381086714713387010这一串雪花算法生成的数字。
INPUT
/**
* 主键id
*/
@TableId(type = IdType.INPUT)
private Long id;
这种类型比较简单,就是你手工在程序里给主键赋值,我这里就不演示了。
AUTO
这种方式就是交给数据库去处理,该自增自增。开发者无需处理了(就算你在程序里面手工给主键赋值,也只能按照数据库的自增来,相当于赋值无用)。
ASSIGN_ID 和 ASSIGN_UUID
/**
* 主键id
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 主键id
*/
@TableId(type = IdType.ASSIGN_UUID)
private String id;
当使用该属性,同样是MP采用雪花算法生成一个随机值,赋值给你类中id属性,并把该属性插入到数据库,和ASSIGN_UUID的区别在于,ASSIGN_UUID规定id必须是String类型,数据库字段必须是varchar类型,而且数据库原先的主键自增得去掉,否则也会报错,字符串类型是无法自增的。
3.4 @Version
标记乐观锁。
这里什么是乐观锁,我之后会给大伙们详细说一说。
通过 version 字段来保证数据的安全性,当修改修改数据的时候,会以 version 作为条件,当条件成立的时候,才会修改成功。
这里用到了一种乐观锁的思想,判断版本号是否和当前版本号相同,相同才可修改。
假设有两个线程同时修改一条数据,那么update语句就会是如下这样:
线程A:update ... set version = 2 where ... and version = 1;
线程B:update ... set version = 2 where ... and version = 1;
那么假如线程A先执行了,那么version就会被修改为2,线程B再执行时,就不会修改成功了。
那么我们怎么使用呢?
1. 我们在数据库表中新增一个version字段,默认值为1。
2. 给实体类添加 version 成员变量
/**
* 乐观锁标记
*/
@Version
private Integer version;
3. 注册一个配置类
@Configuration
public class MybatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
4. 把这个配置类加上后,我们的@Version应该就可以生效了,更新一条数据试试
@Test
void update() {
User user = mapper.selectById("1381088414421536771");
user.setName("小明");
mapper.updateById(user);
}
SQL语句中已经出现更新version字段的信息了,看下数据库中的数据
乐观锁已经生效。
3.5 @EnumValue
通用枚举类注解:将数据库字段映射成实体类的枚举类型成员变量。
我们在数据库中新增一个字段:status
我们都知道通常状态都有几个固定的值。
我们在程序中新建一个枚举类
public enum StatusEnum {
/**
* 在职
*/
WORK(1, "在职"),
/**
* 离职
*/
DEPARTURE(2, "离职");
/**
* 状态码
*/
@EnumValue
private Integer code;
/**
* 状态描述
*/
private String desc;
StatusEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
}
然后在实体类中增加一个字段
但是到这里还没结束,我们还需要在配置文件application.yml中配置一下枚举包扫描
mybatis-plus:
#枚举包扫描
type-enums-package: com.age.mybatisplus.enums
现在我们来查询一下
可以看到这里的状态已经映射成功了。
实现枚举映射有两种方式,一种就是刚才讲的注解的方式,还有一种是实现接口的方式,这种我不细说了,感兴趣的小伙伴可以自己查询相关资(bai)料(du)。
3.6 @TableLogic
映射逻辑删除。
什么意思呢?
就是很多时候我们的数据,是不能真正删除的,只能进行逻辑删除,就是给它一个删除状态。
我们在表中新增一个字段:deleted
实体类添加字段
/**
* 删除状态
*/
@TableLogic
private Integer deleted;
在application.yml中添加配置
mybatis-plus:
global-config:
db-config:
#逻辑删除配置 0-未删除;1-删除
logic-not-delete-value: 0
logic-delete-value: 1
测试类添加删除方法
@Test
void delete() {
mapper.deleteById("1381088414421536771");
}
我们的删除状态字段已经更新,那么这条数据我们还能查到吗?
现在的查询语句中已经带上了deleted条件了,自然是查不到了。
关于MP一些常用的注解,就说这么多,顺带讲了基础的增删改查方法。
但是关于增删改查还有一些方法需要补充。
四、关于查询
4.1 selectList()
上面我们已经提到了这个方法,参数传null默认是查询全部数据。
如果我需要传递查询条件怎么弄?
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
这里看到我们需要传递一个Wrapper对象,这个Wrapper对象就是用来封装查询条件的。
public abstract class Wrapper<T> implements ISqlSegment {
}
但是这个Wrapper是个接口,所以我们需要实例化它的实现类
QueryWrapper<User> wrapper = new QueryWrapper<>();
在QueryWrapper中有许多的方法,基本上都已经满足了日常的开发需求,关于一些常用的API,我们可以参考它的官网:
https://mp.baomidou.com/guide/wrapper.html#abstractwrapper
这里举一个简单的例子
@Test
void select() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三");
mapper.selectList(wrapper);
}
可以看到 name = '张三' 这个条件已经带上了。
多条件查询
@Test
void select() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("age", 30);
wrapper.allEq(map);
mapper.selectList(wrapper);
}
再来看一个联合查询
@Test
void select() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "select id from user where id = '1381088414421536772'");
mapper.selectList(wrapper);
}
通过inSql这个方法,我们就可以自定义我们自己的SQL语句。
4.2 selectById()
通过主键查询。
@Test
void select() {
mapper.selectById("1381088414421536771");
}
4.3 selectBatchIds()
根据多个主键进行查询。
@Test
void select() {
mapper.selectBatchIds(Arrays.asList(
"1381088414421536771",
"1381088414421536772",
"1381088414421536773"));
}
4.4 selectByMap()
用Map传递多个查询条件。和之前讲的Wrapper有点像,但是这里只能做等值查询,如果做范围查询则做不到。
@Test
void select() {
Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
map.put("age", 30);
mapper.selectByMap(map);
}
4.5 selectCount()
统计查询结果数量。
@Test
void select() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三");
mapper.selectCount(wrapper);
}
4.5 selectMaps()
将查询结果封装到Map中。
@Test
void select() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三");
mapper.selectMaps(wrapper);
}
4.6 selectPage()
分页查询。
想要实现分页查询,我们需要做一下配置,在之前的配置类 MybatisPlusConfig 中添加方法
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
否则分页不起作用。
@Test
void select() {
// Page构造方法有两个参数:current-当前页;size:-页大小
Page<User> page = new Page<>(1, 10);
// 返回值也是一个Page类型,里面包含了分页信息以及查询出来的数据信息。
Page<User> result = mapper.selectPage(page, null);
// 查询的结果在Records中
result.getRecords().forEach(System.out::println);
}
4.7 selectMapsPage()
上面的selectPage()参数是Page封装一个Bean,这个方法的参数Page是封装一个Map。而且这里的返回值也是Map。
@Test
void select() {
Page<Map<String, Object>> page = new Page<>(1, 10);
mapper.selectMapsPage(page, null).getRecords().forEach(System.out::println);
}
4.8 自定义SQL(多表关联查询)
现在我们需要再建一张业绩表:performance
SET NAMES utf8mb4;
-- ----------------------------
-- Table structure for performance
-- ----------------------------
DROP TABLE IF EXISTS `performance`;
CREATE TABLE `performance` (
`id` bigint(100) NOT NULL COMMENT '主键id',
`user_id` bigint(100) NOT NULL COMMENT '用户id',
`score` int NOT NULL COMMENT '成绩',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '业绩表' ROW_FORMAT = Dynamic;
我们添加一些数据
user表
performance表
假如现在我们的需求是查询出每个用户的id、name以及score,那么我们就需要用到关联查询。
我们需要先创建一个VO(视图层)
可能有一些小伙伴会疑惑什么时候使用VO,什么时候使用DTO?
这里简单解释一下:
如果你的数据是从数据库返回给视图层的(就是程序内部逻辑使用),就用VO。
如果你的数据是从数据库返回给业务层的(一般指我们的前端,或者处理数据的中台),就用DTO。
@Data
public class PerformanceVO {
/**
* 用户id
*/
private Long userId;
/**
* 用户名
*/
private String userName;
/**
* 成绩
*/
private Integer score;
}
然后在UserMapper中自定义我们的SQL语句
/**
* 查询用户成绩
*
* @param id 用户id
* @return 用户成绩信息
*/
@Select("select u.id as userId, u.name as userName, p.score from user u, performance p where u.id = p.user_id and u.id = #{id}")
List<PerformanceVO> performanceList(long id);
然后我们来测试一下
@Test
void performanceList() {
mapper.performanceList(1381088414421536772L);
}
可以看到查询已经成功执行啦。
五、关于添加
添加前面已经说过,这里不再赘述。
六、关于删除
除了前面讲到的 deleteById() 以外,还有以下一些删除的方法。
6.1 deleteBatchIds()
根据主键批量删除。
@Test
void delete() {
mapper.deleteBatchIds(Arrays.asList(1381088414421536772L, 1381396647736553474L));
}
6.2 delete()
根据指定条件删除。
@Test
void delete() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三");
mapper.delete(wrapper);
}
6.3 deleteByMap()
也是根据指定条件删除,只不过这里是把条件装在Map里。
@Test
void delete() {
Map<String, Object> map = new HashMap<>();
map.put("name", "张三");
mapper.deleteByMap(map);
}
七、关于修改
前面已经讲过根据主键修改数据的方法 updateById() 。除此之外还有一个修改方法。
7.1 update()
根据特定条件修改数据。
@Test
void update() {
User user = mapper.selectById(1381088414421536772L);
user.setName("王五");
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("age", 30);
mapper.update(user, wrapper);
}
这一段代码表示将年龄为30岁的用户名字修改为”王五“。
八、自动生成
MP还有一个很强大的功能就是可以根据你的数据表自动生成实体类、Mapper接口、Service、ServiceImpl、Controller。
挖槽?我连CRUD都不用做了?危!
8.1 导入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1.tmp</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
8.2 Main方法
我们需要写一个main方法
/**
* @author age
* @since 2021/4/12
*/
public class Main {
public static void main(String[] args) {
// 创建generator对象
AutoGenerator autoGenerator = new AutoGenerator();
// 数据源
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL)
.setUrl("jdbc:mysql://localhost:3306/mp_test_db?useUnicode=true&characterEncoding=UTF-8")
.setUsername("root")
.setPassword("123456")
.setDriverName("com.mysql.cj.jdbc.Driver");
autoGenerator.setDataSource(dataSourceConfig);
// 全局配置
GlobalConfig globalConfig = new GlobalConfig();
// 配置生成的类的路径
globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
// 默认创建好文件路径后会把文件夹打开,这里我们把这个选项关闭
globalConfig.setOpen(false);
// 作者
globalConfig.setAuthor("age");
autoGenerator.setGlobalConfig(globalConfig);
// 包信息
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("com.age.mybatisplus");
// 会在com.age.mybatisplus路径下创建一个generator的包
packageConfig.setModuleName("generator");
// controller包名
packageConfig.setController("controller");
// service包名
packageConfig.setService("service");
// serviceImpl包名
packageConfig.setServiceImpl("service.impl");
// mapper包名
packageConfig.setMapper("mapper");
// entity包名
packageConfig.setEntity("entity");
autoGenerator.setPackageInfo(packageConfig);
// 配置策略
StrategyConfig strategyConfig = new StrategyConfig();
// 实体类中启用lombok
strategyConfig.setEntityLombokModel(true);
// 实体类中字段名映射下划线转驼峰
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
autoGenerator.setStrategy(strategyConfig);
autoGenerator.execute();
}
}
执行这个main方法
舒服吗?
看到这里,你还能心安理得的CRUD吗?赶紧学点东西吧,CRUD都不需要人来做了!
九、总结
Mybatis Plus是一款非常便捷的开发工具,目前在很多企业中也都广泛使用,大大提高我们的开发效率,使我们更加专注于业务逻辑的编写,其他模板化的东西,就交给MP来解决吧。
以上就是本文要介绍的所有内容,感谢您的阅读
标签:一学,private,id,Plus,user,Mybatis,new,查询,主键 From: https://blog.csdn.net/qq_41320700/article/details/143837356