Mybatis-plus
本文最后更新于 2023-08-16,文章内容可能已经过时,请注意内容的辨别。
Mybatis-plus
简介
MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
作者:苞米豆组织 因为项目是在码云上的,看成员很多都是中文名字所以我默认是中国的
特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
准备工作
创建springboot工程
依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>kj08</groupId>
<artifactId>mybatisplusdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatisplusdemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mybatisPlus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.4</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.18</version>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置文件
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/kj08?useAffectedRows=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 9320
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1 #逻辑删除的值是1
logic-not-delete-value: 0 #不逻辑删除的值是0
configuration:
#我们在数据库的字段名也是 userCode
#但是如果我们不设置mybstis plus 默认的驼峰式编码在mybatis plus 则会默认把驼峰式编码写成 user_code, 这种下划线格式的字段,
#这时你会发现你的代码会出错,它会提示你user_code字段不存在
map-underscore-to-camel-case: false
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
创建实体类
普通查询
创建mapper只要继承了baseMapper就能省略基础的CURD操作了
@Mapper
@Repository
public interface BlogMapper extends BaseMapper<Blog> {
}
test测试
package kj08.mybatisplusdemo;
import kj08.mybatisplusdemo.mapper.BlogMapper;
import kj08.mybatisplusdemo.pojo.Blog;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class MybatisplusdemoApplicationTests {
@Autowired
private BlogMapper blogMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<Blog> userList = blogMapper.selectList(null);
for (Blog blog : userList) {
System.out.println(blog);
}
}
}
插入操作
在谈到插入操作的时候,我们要先来看一下关于主键的策略,已知我们有默认的之间策略即我们的mysql自增的策略,但是在分布式的项目当中如果说用mysql自带的主键生成策略就会出现重复,所以又有了其他的主键生成策略一般来说有uuid和雪花算法(记得是推特的)在mybatis中也有相关的操作能让我们不用自己写主键值靠mp自动填充
简单的插入操作
@Test
public void testInsert() {
System.out.println(("----- selectInsert method test ------"));
int insert = blogMapper.insert(new Blog());
System.out.println(insert);
}
加入生成主键策略(在实体类加注解)
@TableId
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | "" | 主键字段名 |
type | Enum | 否 | IdType.NONE | 主键类型 |
idtype是枚举型
值 | 描述 |
---|---|
AUTO | 数据库ID自增 |
NONE | 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT) |
INPUT | insert前自行set主键值 |
ASSIGN_ID | 分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator 的方法nextId (默认实现类为DefaultIdentifierGenerator 雪花算法) |
ASSIGN_UUID | 分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator 的方法nextUUID (默认default方法) |
一般我们用ASSIGN_ID,但是有个问题他生成的值是19位的,我们数据库就要有相应的改变,首先数据库字段要是bigint的并且我们的实体类的一定要是Long的这样才能成功,数据库设置自增不自增已经不影响了
package kj08.mybatisplusdemo.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Blog {
@TableId(type = IdType.ASSIGN_ID)
private Long blogId;
private String title;
private String comment;
private String picPath;
}
普通修改操作
//普通的修改
@Test
public void testUpdate() {
Blog blog = blogMapper.selectById(1L);
blog.setComment("ss");
int i = blogMapper.updateById(blog);
System.out.println("有"+i+"条数据被修改");
}
普通删除操作
//普通删除操作
@Test
public void testDelete() {
int i = blogMapper.deleteById(1L);
System.out.println("有"+i+"条数据被删除");
}
逻辑删除操作
首先逻辑删除并不是删除,因为我说了,删除这个操作我们一般是不用的,所以逻辑删除很有必要,其实所谓的逻辑删除也就是修改,那下面我们来学习怎么去逻辑删除
1.加表字段logicDel 设置默认值是0 加实体类属性logicDel
2.配置逻辑删除
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1 #逻辑删除的值是1
logic-not-delete-value: 0 #不逻辑删除的值是0
3.加注解
package kj08.mybatisplusdemo.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
public class Blog {
@TableId(type = IdType.ASSIGN_ID)
private Long blogId;
private String title;
private String comment;
private String picPath;
@TableLogic //逻辑删除注解
private String logicDel;
}
4.删除(修改)
//逻辑删除
@Test
public void testLogicDel() {
int i = blogMapper.deleteById(2L);
System.out.println(i);
}
你看他的日志,其实是修改。总结,方法都是一样的但是注意只要有了配置logic-delete-value和注解 @TableLogic他就不删了生成的sql是很标准严谨的sql
UPDATE blog SET logicDel='1' WHERE blogId=? AND logicDel='0'
乐观锁操作
1.加表字段version 设置默认值是1 加实体类属性version 并加注解@Version 默认int
2.加配置类
package kj08.mybatisplusdemo.conf;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor optimisticLockerInnerInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
原代码
//乐观锁
@Test
public void testlgUpdate() {
Blog blog = blogMapper.selectById(3L);
blog.setComment("sss");
int i = blogMapper.updateById(blog);
System.out.println("有"+i+"条数据被修改");
}
注意sql语句
SELECT blogId,title,comment,picPath,logicDel,version FROM blog WHERE blogId=? AND logicDel='0'
UPDATE blog SET title=?, comment=?, picPath=?, version=? WHERE blogId=? AND logicDel='0'
当我们的实体类加了@version之后
SELECT blogId,title,comment,picPath,logicDel,version FROM blog WHERE blogId=? AND logicDel='0'
UPDATE blog SET title=?, comment=?, picPath=?, version=? WHERE blogId=? AND version=? AND logicDel='0'
注意看version也变了变成了2
总结:节约了我们的乐观锁的操作
自动填充
在我们日常的数据库操作当中,肯定会遇到添加创建时间修改时间的事情,这些事情也是固定化的操作而这种操作,我们一般用代码方式,而我们的mybatisplus就帮助我们实现了
1.表创建字段createtime,updatetime date类型 实体类也创建
2.在confi下创建处理器
package kj08.mybatisplusdemo.conf;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "createtime", Date.class,new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "updatetime", Date.class, new Date());
}
}
3.在实体类加注解
@TableField(fill=FieldFill.INSERT)
private Date createtime;
@TableField(fill=FieldFill.UPDATE)
private Date updatetime;
//实体类数据类型和处理器数据类型要保证一致
3.运行新增修改代码试试,注意自动填充策略是如果属性有值则不覆盖,如果没值就填充,改变这一现象需要加一下代码,但是可能以后会有变动。mp个版本差异性很大,使用的时候需要明确版本。
@TableField(fill=FieldFill.INSERT_UPDATE,update = "now()")
private Date updatetime;
BaseMapper
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.baomidou.mybatisplus.core.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteById(T entity);
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
//map里面放字段名和值 string是字段名 object是值
int delete(@Param("ew") Wrapper<T> queryWrapper);
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
int updateById(@Param("et") T entity);
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
List<T> ts = this.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(ts)) {
if (ts.size() != 1) {
throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records", new Object[0]);
} else {
return ts.get(0);
}
} else {
return null;
}
}
Long selectCount(@Param("ew") Wrapper<T> queryWrapper);
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);
}
关于map参数举例
@Test
public void testSelectByMap() {
System.out.println(("----- selectAll method test ------"));
HashMap<String, Object> map = new HashMap<>();
map.put("title","aa");
List<Blog> userList = blogMapper.selectByMap(map);
for (Blog blog : userList) {
System.out.println(blog);
}
}
关于Wrapper参数举例
Wrapper是条件构造器的抽象类
一般两个继承类是QueryWrapper和UpdateWrapper
QueryWrapper方法
方法名 | 说明 | 使用 |
---|---|---|
eq | = | eq(“real_name”,“王昭君”) |
ne | <> | ne(“nick_name”,“空想 4”) |
gt | > | gt(“age”,21) |
ge | >= | ge(“age”,22) |
lt | < | lt(“age”,22) |
le | <= | le(“age”,21") |
between | cloum between ? and ? | between(“age”,21) |
notBetween | cloum between ? and ? | notBetween(“age”,21) |
like | cloum like ‘% 王 %’ | like(“real_name”,“王”) |
notLike | not like ‘% 王 %’ | notLike(“real_name”,“王”) |
likeLeft | like ‘% 王’ | likeLeft(“real_name”,“昭”) |
likeRight | like ‘王 %’ | likeRight(“real_name”,“昭”) |
isNull | is null | isNull(“gender”) |
isNotNull | is not null | isNotNull(“gender”) |
in | in (1,2,3) | in(“nick_name”,lists) |
notIn | age not in (1,3) | notIn(“nick_name”,lists) |
insql | age in (1,3,4,5,6) | insql(“nick_name”,"‘空想 4’,‘空想 5’,‘空想 6’") |
notInsql | age not in (1,6) | notInsql(“nick_name”,‘空想 6’") |
groupBy | group by id,name | groupBy(“nick_name”,“age”) |
orderByAsc | order by id ASC,name ASC | orderByAsc(“nick_name”,“age”) |
orderByDesc | order by id DESC,name DESC | orderByDesc(“age”) |
orderBy | order by id ASC,name ASC | orderBy(true,true,“age”) |
having | having sum(age) > 10 | having(“sum(age) > 10”) |
or | id = 1 or name = ‘老王’ | eq(“nick_name”,“空想 4”).or(i->i.eq(“age”,21) eq(“nick_name”,“空想 4”).or().eq(“nick_name”,“空想 5”) |
and | and (name = ‘李白’ and status <> ‘活着’) | and(i->i.eq(“age”,21)) |
nested | (name = ‘李白’ and status <> ‘活着’) | nested(i->i.eq(“age”,21).eq(“nick_name”,“空想 4”)) |
apply | id = 1 | apply(“nick_name = ‘空想 4’”) |
last | 最后添加多个以最后的为准,有 sql 注入风险 | last(“limit 1”) |
exists | 拼接 EXISTS (sql 语句) | exists(“select id from table where age = 1”) |
notExists | 拼接 NOT EXISTS (sql 语句) | notExists(“select id from table where age = 1”) |
//wrapper查询
@Test
public void testWrapperSelectByMap() {
System.out.println(("----- selectAll method test ------"));
QueryWrapper wrapper=new QueryWrapper();
wrapper.eq("title","aa");
List<Blog> list = blogMapper.selectList(wrapper);
for (Blog blog : list) {
System.out.println(blog);
}
}
//wrapper修改一般不用
@Test
public void testWrapperUpdate() {
UpdateWrapper<Blog> blogUpdateWrapper = new UpdateWrapper<>();
blogUpdateWrapper.eq("title","aa");
Blog blog = blogMapper.selectById(1447419394744479746L);
blogMapper.update(blog,blogUpdateWrapper);
}
分页查询
我们之前学了原始的limit个mybatis常用的pagehelper在mp中也是有分页的插件的
他就是Page
在使用这个page之前要做一个配置操作,死代码
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 注册乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 分页查询插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
配置完成之后测试
// 测试分页查询
@Test
public void testPage(){
// 参数一:当前页,参数二:页面大小
Page<Blog> page = new Page<>(2,3);
// 不进行 count sql 优化,解决 MP 无法自动优化 SQL 问题,这时候你需要自己查询 count 部分
// page.setOptimizeCountSql(false);
/*有时使用分页功能的时候发现统计到的total和预期不符,于是在控制台查看分页count sql,
发现mybatis自动优化了sql,把select 后面要查询的内容全部省略,直接count。这是mysql自动优化的策略。
正常情况下这样做并没有什么问题,但是当我select 后面需要聚合,比如使用sum函数的时候,自动优化得到的total就会比预期多。
当日解决办法也是有的,就是禁用自动优化*/
// 当 total 为小于 0 或者设置 setSearchCount(false) 分页插件不会进行 count 查询
// 要点!! 分页返回的对象与传入的对象是同一个
IPage<Blog> bolgPage = blogMapper.selectPage(page, null);
List<Blog> records = bolgPage.getRecords();
for (Blog record : records) {
System.out.println(record);
}
System.out.println(page.getTotal());
}
排序查询
两种方式
加注解
@OrderBy(优先级低于wrapper)
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
isDesc | boolean | 否 | 是 | 是否倒序查询 |
sort | short | 否 | Short.MAX_VALUE | 数字越小越靠前 |
条件构造器
wrapper.orderByAsc(R... columns)
wrapper.orderByDesc(R... columns)
执行 SQL 分析打印
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/kj08?useAffectedRows=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 9320
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1 #逻辑删除的值是1
logic-not-delete-value: 0 #不逻辑删除的值是0
configuration:
#我们在数据库的字段名也是 userCode
#但是如果我们不设置mybstis plus 默认的驼峰式编码在mybatis plus 则会默认把驼峰式编码写成 user_code, 这种下划线格式的字段,
#这时你会发现你的代码会出错,它会提示你user_code字段不存在
map-underscore-to-camel-case: false
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
主要改 driver-class-name: com.p6spy.engine.spy.P6SpyDriver url: jdbc:p6spy:mysql://localhost:3306/kj08?useAffectedRows=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
加spy.properties
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
日志输出:
Consume Time:13 ms 2021-10-12 16:39:02 Execute SQL:SELECT blogId,title,comment,picPath,logicDel,version,createtime,updatetime FROM blog WHERE title = 'aa' AND logicDel='0'
代码生成器
步骤
1.加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
运行这个类
package kj08.mybatisplusdemo;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
@SpringBootTest
public class Generator {
@Test
public void GeneratorCode(){
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("afeng");//設置作者
gc.setOpen(false);//是否打開資源管理器(不管他)
gc.setSwagger2(true); //实体属性 Swagger2 注解
gc.setFileOverride(false);//是否覆蓋原來的
gc.setServiceImplName("%sService");//去service的I前綴
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/kj08?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("9320");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("login");
pc.setParent("kj08.mybatisplusdemo");
pc.setController("controller");
pc.setEntity("pojo");
pc.setMapper("mapper");
pc.setService("service");
mpg.setPackageInfo(pc);
StrategyConfig stConfig = new StrategyConfig();
stConfig.setInclude("blog","class");//主要是用這個要生成几个表的
stConfig.setEntityLombokModel(true);//要不要用lombok
mpg.setStrategy(stConfig);
mpg.execute();
}
}
MybatisX 快速开发插件
作用:响应文件 生成mapper.xml 里的基本标签
步骤
1.打开 IDEA,进入 File -> Settings ->搜索 plugins 输入 mybatisx
搜索并安装。重启idea
你能在mapper上能看到小鸟
然后你写个接口
alt加enter
generate statement 选择 就自定在mapper。xml中生成标签了
- 感谢你赐予我前进的力量