学习mybatis-plus主要是看中这个框架给我们省去了好多时间编写相类似的代码,特别是脚手架自动生成代码的机制,在开发过程中,我们只需编写业务逻辑,CRUD等操作自动封装好了,相比传统的方式,我们需要在mapper.xml文件中编写增删查改,而使用了mybatis-plus,这些配置你都不用写了,你一定会爱上它的。
脚手架代码:
package com.mp.generator;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.PostgreSqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
/**
* 代码生成器
*
* <p>
* 根据数据库中的表生成:数据库表映射对象、Mapper 接口、Mapper XML 文件(含基础的 ResultMap 和字段代码片段)、
* Service 接口、Service 接口实现累、基础的 Controller 类。
* </p>
* <p>
* 如果数据库设计符合规范,并且代码没有特殊要求。设置好表名前缀(无则忽略)、表字段前缀(无则忽略)后,
* 直接修改输出的路径、JDBC Url、数据库的账户和密码即可直接生成代码。
* </p>
* <p>
* 生成后将 Mapper 中的 xml 包中的 XML 文件移动到 resource 下即可,XML 存放文件夹名为 Mapper 接口包名(全包名)的同名文件夹<br/>
* 如 Mapper 接口包名为:com.example.mapper,那么在 resource 下新建同名文件夹:com.example.mapper,将 xml 文件移动到该文件夹下即可。
* </p>
*
* @author 黄宝康
* @since 2020-03-01 15:00
*/
public class MappingGenerator {
/**
* 生成代码输出路径,<strong>路径必须是绝对路径,不需要包含包名</strong>
*/
private static final String OUTPUT_DIR = System.getProperty("user.dir")+"/src/main/java";
/**
* 生成代码输出的包名
* <p>总包名,后续生成的 Mapper,Service 等将在该包下生成子包</p>
*/
private static final String PACKAGE = "com.hbk";
/**
* JDBC URL
*/
private static final String JDBC_URL = "jdbc:mysql://192.168.169.133:3306/blog?useUnicode=true&useSSL=false&characterEncoding=utf8";
/**
* 数据库账户
*/
private static final String DB_USERNAME = "root";
/**
* 数据库账户密码
*/
private static final String DB_PASSWORD = "123456";
/**
* 执行即可生成代码
*/
public static void main(String[] args) {
autoGenerator().execute();
}
private static AutoGenerator autoGenerator() {
AutoGenerator autoGenerator = new AutoGenerator();
autoGenerator.setGlobalConfig(globalConfig());
autoGenerator.setDataSource(mysqlDataSourceConfig());
autoGenerator.setStrategy(strategyConfig());
autoGenerator.setPackageInfo(packageConfig());
autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
return autoGenerator;
}
/**
* 全局配置
*
* @return {@link GlobalConfig}
*/
private static GlobalConfig globalConfig() {
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setAuthor("huangbaokang");
// 设置代码输出位置,需要绝对路径
globalConfig.setOutputDir(OUTPUT_DIR);
// 覆盖已有的代码
globalConfig.setFileOverride(false);
// 基本表的 ResultMap
globalConfig.setBaseResultMap(true);
// 基本表字段片段
globalConfig.setBaseColumnList(true);
// 开启基于 Model 操作数据库
globalConfig.setActiveRecord(true);
// 设置 ID 类型
globalConfig.setIdType(IdType.ASSIGN_ID);
// 生成基本 Swagger2 文档
globalConfig.setSwagger2(true);
// 开启二级缓存
globalConfig.setEnableCache(true);
// 设置生成的对象名称规则,%s 表示当前的 Entity
// 数据库表映射对象名称规则
globalConfig.setEntityName("%s");
// Mapper 接口名称规则
globalConfig.setMapperName("%sMapper");
// Mapper XML 文件名称规则
globalConfig.setXmlName("%sMapper");
// Controller 生成规则
globalConfig.setControllerName("%sController");
// Service 接口生成名称规则
globalConfig.setServiceName("%sService");
// Service 实现类生成名称规则
globalConfig.setServiceImplName("%sServiceImpl");
return globalConfig;
}
/**
* 生成策略配置
*
* @return StrategyConfig
*/
private static StrategyConfig strategyConfig() {
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setCapitalMode(false);
strategyConfig.setEntityLombokModel(true);
strategyConfig.setRestControllerStyle(true);
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
// TODO 填写表名前缀,在生成代码时去除指定前缀
strategyConfig.setTablePrefix("tb_");
// TODO 填写表字段前缀,生成代码时去除字段前缀
strategyConfig.setFieldPrefix("a_", "u_", "c_", "p_", "u_", "t_");
return strategyConfig;
}
/**
* MySQL 数据源配置
*
* @return DataSourceConfig
*/
private static DataSourceConfig mysqlDataSourceConfig() {
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setTypeConvert(new MySqlTypeConvert());
// dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");
dataSourceConfig.setUrl(JDBC_URL);
dataSourceConfig.setUsername(DB_USERNAME);
dataSourceConfig.setPassword(DB_PASSWORD);
return dataSourceConfig;
}
/**
* PostgreSQL 数据源配置
*
* @return DataSourceConfig
*/
private static DataSourceConfig postgresqlDataSourceConfig() {
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.POSTGRE_SQL);
dataSourceConfig.setTypeConvert(new PostgreSqlTypeConvert());
dataSourceConfig.setDriverName("org.postgresql.Driver");
dataSourceConfig.setUrl(JDBC_URL);
dataSourceConfig.setUsername(DB_USERNAME);
dataSourceConfig.setPassword(DB_PASSWORD);
return dataSourceConfig;
}
/**
* 包相关配置信息
* <p>配置生成代码的包信息,如生成的 Mapper 包,Service 包等</p>
*/
private static PackageConfig packageConfig() {
PackageConfig packageConfig = new PackageConfig();
// 设置父包
packageConfig.setParent(PACKAGE);
// TODO 设置生成代码的包
// Controller 包
packageConfig.setController("controller");
// 数据库表映射对象包
packageConfig.setEntity("entity");
// Mapper 接口包,含 XML 文件
packageConfig.setMapper("mapper");
// Service 接口包
packageConfig.setService("service");
// Service 接口实现类包
packageConfig.setServiceImpl("service.impl");
return packageConfig;
}
}
另外一种风格的,在开发中,也可以用到
package com.mp.generator;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
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 lombok.extern.java.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @ClassName CodeGenerator
* @Description TODO
* @Author YsCY丶
* @Date 2018/10/17 11:23
* @Version 1.0
**/
public class CodeGenerator {
/**
* <p>
* 读取控制台内容
* </p>
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("Huangbaokang");
gc.setOpen(false);
gc.setFileOverride(true);//是否覆盖已有文件
gc.setSwagger2(true);
gc.setBaseResultMap(true);
gc.setBaseColumnList(true);
gc.setIdType(IdType.AUTO);
//gc.setActiveRecord(true);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://192.168.169.133:3306/blog?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(scanner("模块名"));
pc.setParent("com");//父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输入文件名称
return projectPath + "/src/main/resources/mapper/"
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.setTemplate(new TemplateConfig().setXml(null));
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略 小驼峰
//strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
strategy.setEntityLombokModel(true);//实体类启用lombok模式
strategy.setRestControllerStyle(true);//生成 @RestController 控制器
//strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
strategy.setInclude(scanner("表名"));//需要生成的表名
//strategy.setExclude("users"); 排除不生成的表名
strategy.entityTableFieldAnnotationEnable(true);//是否生成实体时,生成字段注解
//strategy.setSuperEntityColumns("id");//自定义基础的Entity类,公共字段
strategy.setControllerMappingHyphenStyle(true);//驼峰转连字符
strategy.setTablePrefix(pc.getModuleName() + "_");//表名前缀
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
使用的pom依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--Failed to read artifact descriptor for org.springframework.boot:spring-boot-configuration-processor:jar:2.0.5.RELEAS -->
<groupId>com.mp</groupId>
<artifactId>mybatisplus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mybatisplus</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.29</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
通用的数据响应格式封装
package com.util;
/**
* <h3>客户端响应对象</h3>
* <p>
* <ul>
* 响应包含如下信息:
* <li>desc: 请求状态的描述</li>
* <li>status: 请求状态码</li>
* <li>data: 响应数据</li>
* </ul>
* 当请求成功时,desc 默认为 success; 状态码为 200, data 为用户期望的信息。如:
* 当用户请求获取 ID 为 1221 的文章时,成功后返回信息为:
* <blockquote><pre>
* data = Object;
* status = 200;
* desc = "success";
* </pre></blockquote>
* <p>
* 当请求失败时,desc 为失败原因,data 为用户提供的信息,status 同 http 状态码。如:
* 当用户请求删除 ID 为 1025 的文章时,如果该 ID 不存在则返回的信息为:
* <blockquote><pre>
* data = 1025;
* desc = "resource not found";
* status = 404;
* </pre></blockquote>
* </p>
*
* @param <T> 响应数据类型
*/
public class ResponseVO<T> {
/**
* 默认的成功描述
*/
public static final String DESC_SUCCESS = "success";
/**
* 默认的失败描述
*/
public static final String DESC_FAILED = "failed";
public static final int STATUS_SUCCESS = 200;
public static final int STATUS_BAD_REQUEST = 400;
public static final int STATUS_NO_AUTH = 401;
public static final int STATUS_DENY = 403;
public static final int STATUS_NOT_FOUND = 404;
public static final int STATUS_NOT_SUPPORT = 405;
public static final int STATUS_INTERNAL_SERVER_ERROR = 500;
/**
* 请求状态码,同 HTTP 状态码
*/
private int status;
/**
* 请求状态描述,成功时为 success,失败时为失败原因
*/
private String desc;
/**
* 响应信息
*/
private T data;
public ResponseVO() {
status = STATUS_SUCCESS;
desc = DESC_SUCCESS;
}
public ResponseVO(int status, String desc, T data) {
this.status = status;
this.desc = desc;
this.data = data;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
/**
* 生成默认的成功响应对象
* 返回内容如下:
* <blockquote><pre>
* data = param;
* desc = "success";
* status = 200;
* </pre></blockquote>
*
* @param data 响应信息
* @param <T> 响应信息泛型
* @return 响应对象 {@link ResponseVO}
*/
public static <T> ResponseVO<T> success(T data) {
return new ResponseVO<>(STATUS_SUCCESS, DESC_SUCCESS, data);
}
public static <T> ResponseVO<T> failed(int status, T data) {
return new ResponseVO<>(status, DESC_FAILED, data);
}
}