简介:
Mybatis-Plus特性:
- 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
- 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击
- 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
- 支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
- 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
- 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词
- 内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
- 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作
实现过程:
- maven依赖
<properties>
<java.version>1.8</java.version>
<lombok.version>1.16.18</lombok.version>
<fastjson.version>1.2.39</fastjson.version>
<mysql.connector.version>8.0.16</mysql.connector.version>
<mybatis-plus-version>3.1.0</mybatis-plus-version>
<druid-version>1.0.29</druid-version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--Json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--使用Mysql数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
<!--mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus-version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid-version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity-version}</version>
</dependency>
<!--swagger2 集成-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2-version}</version>
</dependency>
- application.yml配置
server:
port: 8081
tomcat:
uri-encoding: UTF-8
max-http-post-size: -1
spring:
application:
name: blog
datasource:
url: jdbc:mysql://127.0.0.1:3306/blog?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8
driverClassName: com.mysql.cj.jdbc.Driver
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
# 配置druid数据库连接池---------------------------------------
initialSize: 5 # 初始化大小,最小,最大
minIdle: 5
maxActive: 20
maxWait: 60000 # 配置获取连接等待超时的时间
timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
validationQuery: SELECT 'x' # 校验SQL,Oracle配置 spring.datasource.validationQuery=SELECT 1 FROM DUAL,如果不配validationQuery项,则下面三项配置无用
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true # 打开PSCache,并且指定每个连接上PSCache的大小
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,wall,log4j # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
# 配置mybatis-plus的xml和bean的目录
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config: #逻辑删除配置
db-config:
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
refresh-mapper: true # 刷新mapper 调试神器
- 接下来我们来进行mybatis-plus的配置
package com.blog.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Date;
/**
* @author LiWT
* @Date 2020-12-04
*/
@EnableTransactionManagement
@Configuration
@MapperScan("com.blog.mapper")
public class MybatisPlusConfig implements MetaObjectHandler {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("isDeleted", false, metaObject);
this.setFieldValByName("createId", "1", metaObject);
this.setFieldValByName("createName", "创建人姓名", metaObject);
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateId", "2", metaObject);
this.setFieldValByName("updateName", "更新人姓名", metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateId", "2", metaObject);
this.setFieldValByName("updateName", "更新人姓名", metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
/**
* 配置监控服务器
*
* @return 返回监控注册的servlet对象
*/
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
// 添加IP白名单
// servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
// 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
// servletRegistrationBean.addInitParameter("deny", "127.0.0.1");
// 添加控制台管理用户
servletRegistrationBean.addInitParameter("loginUsername", "blog_admin");
servletRegistrationBean.addInitParameter("loginPassword", "43kqZ$WG");
// 是否能够重置数据
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
}
- paginationInterceptor()用于配置MybatisPlus分页插件
- insertFill()方法用于自动填充数据,创建人/修改人ID、姓名这些数据可以从JWT中获取用户真实数据填入
- updateFill()方法用于更新数据时自动填充修改人ID、姓名数据
- statViewServlet()配置sql监控服务器,可以监控sql执行情况及查询情况,但是生产环境建议不要开启;其中的loginUsername与loginPassword用于登录监控服务器
-
启动类上需要使用@MapperScan(“com.blog.mapper.*”)配置扫描Mapper的路径
-
最后贴上MybatisPlus最好用的结构生成器,从Entity -> Mapper -> Mapper.xml -> Service -> ServiceImpl -> Controller层结构全部自动生成,究极好用
package com.blog.utils;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* mybatis-plus自动生成代码工具类
*
* @author LiWT
* @date 2020-12-04
*/
public class Generator {
@Data
static class ConfigureParams {
private String auth;
private String packageName;
private String path;
private String url;
private String username;
private String password;
private String driverName;
private String[] tablePrefix;
private String logicDeleteFieldName;
private String[] include;
private String controllerPackage;
private String entityPackage;
private String mapperPackage;
private String xmlPackage;
private String[] autoFillInsertAndUpdate;
private String[] autoFillInsert;
public ConfigureParams(String auth, String packageName, String path, String url, String username, String password, String driverName, String[] tablePrefix, String logicDeleteFieldName, String[] include, String controllerPackage, String entityPackage, String mapperPackage, String xmlPackage, String[] autoFillInsertAndUpdate, String[] autoFillInsert) {
this.auth = auth;
this.packageName = packageName;
this.path = path;
this.url = url;
this.username = username;
this.password = password;
this.driverName = driverName;
this.tablePrefix = tablePrefix;
this.logicDeleteFieldName = logicDeleteFieldName;
this.include = include;
this.controllerPackage = controllerPackage;
this.entityPackage = entityPackage;
this.mapperPackage = mapperPackage;
this.xmlPackage = xmlPackage;
this.autoFillInsertAndUpdate = autoFillInsertAndUpdate;
this.autoFillInsert = autoFillInsert;
}
}
/**
* 生成代码直接运行该main方法即可,注意需修改一些配置信息
* auth://创建人
* packageName://包前缀
* path://项目路径
* url://数据库连接地址xxx.xxx.x.xxx:端口/数据库名称
* username://数据库连接用户名
* password://数据库连接密码
* driverName://数据库驱动
* tablePrefix://生成的实体类去掉前缀,可以配置多个
* logicDeleteFieldName://逻辑删除属性名称
* include://要生成代码的表名,多个表名用英文逗号分割 ".*." 生成全部
* controllerPackage://controller包名
* entityPackage://实体类包名
* mapperPackage://mapper包名
* xmlPackage://xml包名
* autoFillInsertAndUpdate://表中新增或修改时需自动填充的字段
* autoFillInsert://表中新增时需自动填充的字段
*/
public static void main(String[] args) {
String auth = "LiWT";
String packageName = "com.blog";
String path = "D:\\Projects\\blog\\src\\main\\java";
String url = "127.0.0.1:3306/blog";
String username = "root";
String password = "root";
String driverName = "com.mysql.cj.jdbc.Driver";
String[] tablePrefix = new String[]{"sys_", "usc_"};
String logicDeleteFieldName = "is_deleted";
String[] include = new String[]{".*."};
String controllerPackage = "controller";
String entityPackage = "entity";
String mapperPackage = "mapper";
String xmlPackage = "classpath:mapper";
String[] autoFillInsertAndUpdate = new String[]{"update_id", "update_name", "update_time"};
String[] autoFillInsert = new String[]{"create_id", "create_name", "create_time"};
ConfigureParams configureParams = new ConfigureParams(auth, packageName, path, url, username, password, driverName,
tablePrefix, logicDeleteFieldName, include, controllerPackage, entityPackage, mapperPackage, xmlPackage, autoFillInsertAndUpdate, autoFillInsert);
//加载配置信息并执行
generate(configureParams);
}
private static void generate(ConfigureParams configureParams) {
//******************************全局配置******************************//
GlobalConfig config = new GlobalConfig();
//设置是否支持AR模式
config.setActiveRecord(true)
//设置生成代码的作者
.setAuthor(configureParams.getAuth())
//设置输出代码的位置
.setOutputDir(configureParams.getPath())
// XML 二级缓存
.setEnableCache(false)
// XML ResultMap
.setBaseResultMap(true)
// XML columList
.setBaseColumnList(true)
//.setKotlin(true) 是否生成 kotlin 代码
// 是否使用Swagger2
.setSwagger2(true)
// 设置是否覆盖原来的代码
.setFileOverride(false);
//******************************数据源配置******************************//
//数据库连接url
String dbUrl = "jdbc:mysql://" + configureParams.getUrl() + "?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
//数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
//数据库类型 枚举
dataSourceConfig.setDbType(DbType.MYSQL)
//设置url
.setUrl(dbUrl)
//设置用户名
.setUsername(configureParams.getUsername())
//设置密码
.setPassword(configureParams.getPassword())
//设置数据库驱动
.setDriverName(configureParams.getDriverName())
// 自定义数据库表字段类型转换【可选】
.setTypeConvert(new MySqlTypeConvert() {
@Override
public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
System.out.println("转换类型:" + fieldType);
//将数据库中datetime转换成date
if (fieldType.toLowerCase().contains("datetime")) {
return DbColumnType.DATE;
}
return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
}
});
//******************************策略配置******************************//
// 自定义需要填充的字段 数据库中的字段
List<TableFill> tableFillList = new ArrayList<>();
for (String autoFillName : configureParams.getAutoFillInsertAndUpdate()) {
tableFillList.add(new TableFill(autoFillName, FieldFill.INSERT_UPDATE));
}
for (String autoFillName : configureParams.getAutoFillInsert()) {
tableFillList.add(new TableFill(autoFillName, FieldFill.INSERT));
}
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig
//全局大写命名是否开启
.setCapitalMode(true)
//【实体】是否为lombok模型
.setEntityLombokModel(true)
//表名生成策略 下划线转驼峰
.setNaming(NamingStrategy.underline_to_camel)
//生成的去掉前缀,可以配置多个
.setTablePrefix(configureParams.getTablePrefix())
//自动填充设置
.setTableFillList(tableFillList)
//逻辑删除属性名称
.setLogicDeleteFieldName(configureParams.getLogicDeleteFieldName())
.setRestControllerStyle(true)
//要生成代码的表名
.setInclude(configureParams.getInclude());
//集成注入设置 注入全局设置
new AutoGenerator().setGlobalConfig(config)
//注入数据源配置
.setDataSource(dataSourceConfig)
//注入策略配置
.setStrategy(strategyConfig)
//设置包名信息
.setPackageInfo(
new PackageConfig()
//提取公共父级包名
.setParent(configureParams.getPackageName())
//设置controller信息
.setController(configureParams.getControllerPackage())
//设置实体类信息
.setEntity(configureParams.getEntityPackage())
//设置mapper信息
.setMapper(configureParams.getMapperPackage())
.setXml(configureParams.getXmlPackage())
)
//设置自定义模板
.setTemplate(
new TemplateConfig()
//.setXml(null)//指定自定义模板路径, 位置:/resources/templates/entity2.java.ftl(或者是.vm)
//注意不要带上.ftl(或者是.vm), 会根据使用的模板引擎自动识别
// 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
// 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置:
// .setController("...");
// .setEntity("...");
// .setMapper("...");
// .setXml("...");
// .setService("...");
.setServiceImpl("templates/serviceImpl.java")
)
//开始执行代码生成
.execute();
}
}
该Generator需要配置几个关键信息,然后直接执行main方法即可快速生成代码
- packageName://包前缀(com.xxx.xxx)
- path://项目路径(该路径需要copy到java层,如果使用IDEA编辑器的话直接选中java文件夹右键 -> Copy Path -> Absolute Path 即可)
- url://数据库连接地址xxx.xxx.x.xxx:端口/数据库名称 (该项配置数据库连接地址 IP:Port/数据库名称)
- username://数据库连接用户名
- password://数据库连接密码
- driverName://数据库驱动 (写死com.mysql.cj.jdbc.Driver即可,无需修改)
- tablePrefix://生成的实体类去掉前缀,可以配置多个(该项为数据库表名前缀,生成代码时会根据该项配置自动去掉前缀)
- logicDeleteFieldName://逻辑删除属性名称(该项为数据库表逻辑删除字段名,在调用mybatis-plus删除接口时会根据application.yml中的逻辑删除配置自动填充值)
- include://要生成代码的表名,多个表名用英文逗号分割 (".*." 生成全部)
- controllerPackage://controller包名(controller层要生成代码的包名,与上方packageName合起来即为生成controller代码的路径)
- entityPackage://实体类包名(entity层要生成代码的包名,与上方packageName合起来即为生成entity代码的路径)
- mapperPackage://mapper包名(mapper层要生成代码的包名,与上方packageName合起来即为生成mapper代码的路径)
- xmlPackage://xml包名(resources下存放xml文件的包名)
- 创建mysql数据库及表
CREATE TABLE `usc_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`account` varchar(60) NOT NULL COMMENT '账号',
`name` varchar(60) DEFAULT NULL COMMENT '名字',
`nick_name` varchar(255) DEFAULT NULL COMMENT '昵称',
`password` varchar(60) NOT NULL COMMENT '密码',
`password_date` datetime DEFAULT NULL COMMENT '密码设置日期',
`address` varchar(512) DEFAULT NULL COMMENT '地址',
`birthday` datetime DEFAULT NULL COMMENT '生日',
`sex` varchar(60) DEFAULT NULL COMMENT '性别',
`mobile` varchar(60) DEFAULT NULL COMMENT '手机',
`email` varchar(60) DEFAULT NULL COMMENT '邮箱',
`comment` varchar(512) DEFAULT NULL COMMENT '用户备注',
`picture` varchar(255) DEFAULT NULL COMMENT '图片',
`org_id` bigint(20) DEFAULT '1' COMMENT '所属组织机构ID',
`join_date` datetime DEFAULT NULL COMMENT '入职时间',
`create_id` bigint(20) DEFAULT NULL COMMENT '创建人id',
`update_id` bigint(20) DEFAULT '0' COMMENT '修改人id',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`create_name` varchar(60) DEFAULT NULL COMMENT '创建人姓名',
`update_name` varchar(60) DEFAULT NULL COMMENT '最后修改人姓名',
`is_deleted` tinyint(1) DEFAULT '0' COMMENT '是否删除(0:未删除,1:已删除)',
`status` int(2) DEFAULT NULL COMMENT '状态',
`fail_num` int(11) DEFAULT '0' COMMENT '登录失败次数',
`idcard_number` varchar(40) DEFAULT NULL COMMENT '用户身份证号',
PRIMARY KEY (`id`),
UNIQUE KEY `UNI_ACCOUNT` (`account`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用户中心-用户信息表';
- 执行上边生成代码,然后我们在Service中写一个方法实验一下
可以看到MybatisPlus自带的方法我们就都可以使用了,它还自带了QueryWrapper、LambdaQueryWrapper等条件查询器,使单表的查询更加方便了,具体使用请参考条件构造器的使用教程