目录
一,MyBatis-Plus基本简介。
二,特性
三,实现代码自动生成工具
3.1,准备一个初始项目,数据表,连接好数据库
3.2,导入Mybatis-Plus相关依赖
3.3,配置数据库配置文件application.yml
3.4,构建代码自动生成工具类,其他更多的配置可参考官网=》苞米豆
四,新旧代码生成器简单分析及补充
4.1,源码上的简单分析
4.2,模板配置TemplateConfig说明。
4.3,注入配置(InjectionConfig)说明
MyBatis-Plus,又简称为“MP”,是一个MyBatis的增强工具,在MyBatis原有的使用功能基础上只做增强,不做改变。纯粹为了简化开发,提高效率而生。
为什么需要这样的工具呢?
因为最简单的一点,相比于同类型的数据库框架JPA而言,原生的MyBatis框架在处理JDBC和SQL语句上无疑更为繁琐,因为需要独立编写SQL语句,虽然更加灵活,性能较高,并且易于维护与阅读,但是相较于JPA直接集成jpaRepository省去大部分sql语句而言,开发效率明显不如jpa。所以,产生了MyBatis-plus,在Mybatis的基础上进一步增强了他的功能(理由并不唯一)。
详情可参考MyBatis-plus官方文档
虽然IDEA中一些类似于easycode,RestfulToolkitX Code等插件也能实现代码自动生成,但是他们并不全面,而且缺乏灵活度。而MyBatis-Plus比他们更全面,虽然需要我们自己编写一些配置代码,但是在构建Springboot项目中,通过代码自动生成,直接构建出项目全面的基本结构。例如常用的POJO,DAO,Service,Service实现类,Controller层以及mapper.xml文件 ,并且在service中继承了封装好的IService类,一般的sql和实现类基本不用书写就能在controller中调用,并且我们还可以自己编辑自己的业务SQL语句,可谓相当灵活!话不多,直接上过程:
com.baomidou
mybatis-plus-boot-starter
3.5.1
com.baomidou
mybatis-plus-generator
3.5.1
org.apache.velocity
velocity-engine-core
2.3
由于项目依赖于springboot,还需要数据库,数据表。因次,需要使用到的相关注解依赖也要一并引入,如果没有用到,可自行添减。
org.springframework.boot
spring-boot-starter-data-jdbc
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
runtime
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
junit
junit
test
io.springfox
springfox-boot-starter
3.0.0
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
password: 123456
username: root
url: jdbc:mysql://localhost:3306?test_user&useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
server:
port: 8086
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.Collections;
/**
* @author young
* Date 2023/2/16 17:56
* Description: store-cloud
*/
public class CodeGeneration {
public static void main(String[] args) {
/**
* 先配置数据源
*/
MySqlQuery mySqlQuery = new MySqlQuery() {
@Override
public String[] fieldCustom() {
return new String[]{"Default"};
}
};
DataSourceConfig dsc = new DataSourceConfig.Builder("jdbc:mysql://localhost:3306/flowerpotnet?&useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai","root","123456")
.dbQuery(mySqlQuery).build();
//通过datasourceConfig创建AutoGenerator
AutoGenerator generator = new AutoGenerator(dsc);
/**
* 全局配置
*/
String projectPath = System.getProperty("user.dir"); //获取项目路径
String filePath = projectPath + "/src/main/java"; //java下的文件路径
GlobalConfig global = new GlobalConfig.Builder()
.outputDir(filePath)//生成的输出路径
.author("young")//生成的作者名字
//.enableSwagger()开启swagger,需要添加swagger依赖并配置
.dateType(DateType.TIME_PACK)//时间策略
.commentDate("yyyy年MM月dd日")//格式化时间格式
.disableOpenDir()//禁止打开输出目录,默认false
.fileOverride()//覆盖生成文件
.build();
/**
* 包配置
*/
PackageConfig packages = new PackageConfig.Builder()
.entity("entity")//实体类包名
.parent("com.yy")//父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
.controller("controller")//控制层包名
.mapper("dao")//mapper层包名
.xml("mapper.xml")//数据访问层xml包名
.service("service")//service层包名
.serviceImpl("service.impl")//service实现类包名
.other("output")//输出自定义文件时的包名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath + "/src/main/resources/mapper")) //路径配置信息,就是配置各个文件模板的路径信息,这里以mapper.xml为例
.build();
/**
* 模板配置
*/
// 如果模板引擎是 freemarker
// String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
TemplateConfig template = new TemplateConfig.Builder()
// .disable()//禁用所有模板
//.disable(TemplateType.ENTITY)禁用指定模板
// .service(filePath + "/service.java")//service模板路径
// .serviceImpl(filePath + "/service/impl/serviceImpl.java")//实现类模板路径
// .mapper(filePath + "/mapper.java")//mapper模板路径
// .mapperXml("/templates/mapper.xml")//xml文件模板路路径
// .controller(filePath + "/controller")//controller层模板路径
.build();
/**
* 注入配置,自定义配置一个Map对象
*/
// Map map = new HashMap<>();
// map.put("name","young");
// map.put("age","22");
// map.put("sex","男");
// map.put("description","深情不及黎治跃");
//
// InjectionConfig injectionConfig = new InjectionConfig.Builder()
// .customMap(map)
// .build();
/**
* 策略配置开始
*/
StrategyConfig strategyConfig = new StrategyConfig.Builder()
.enableCapitalMode()//开启全局大写命名
//.likeTable()模糊表匹配
.addInclude()//添加表匹配,指定要生成的数据表名,不写默认选定数据库所有表
//.disableSqlFilter()禁用sql过滤:默认(不使用该方法)true
//.enableSchema()启用schema:默认false
.entityBuilder() //实体策略配置
//.disableSerialVersionUID()禁用生成SerialVersionUID:默认true
.enableChainModel()//开启链式模型
.enableLombok()//开启lombok
.enableRemoveIsPrefix()//开启 Boolean 类型字段移除 is 前缀
.enableTableFieldAnnotation()//开启生成实体时生成字段注解
//.addTableFills()添加表字段填充
.naming(NamingStrategy.underline_to_camel)//数据表映射实体命名策略:默认下划线转驼峰underline_to_camel
.columnNaming(NamingStrategy.underline_to_camel)//表字段映射实体属性命名规则:默认null,不指定按照naming执行
.idType(IdType.AUTO)//添加全局主键类型
.formatFileName("%s")//格式化实体名称,%s取消首字母I
.build()
.mapperBuilder()//mapper文件策略
.enableMapperAnnotation()//开启mapper注解
.enableBaseResultMap()//启用xml文件中的BaseResultMap 生成
.enableBaseColumnList()//启用xml文件中的BaseColumnList
//.cache(缓存类.class)设置缓存实现类
.formatMapperFileName("%sMapper")//格式化Dao类名称
.formatXmlFileName("%sMapper")//格式化xml文件名称
.build()
.serviceBuilder()//service文件策略
.formatServiceFileName("%sService")//格式化 service 接口文件名称
.formatServiceImplFileName("%sServiceImpl")//格式化 service 接口文件名称
.build()
.controllerBuilder()//控制层策略
//.enableHyphenStyle()开启驼峰转连字符,默认:false
.enableRestStyle()//开启生成@RestController
.formatFileName("%sController")//格式化文件名称
.build();
/*至此,策略配置才算基本完成!*/
/**
* 将所有配置项整合到AutoGenerator中进行执行
*/
generator.global(global)
.template(template)
// .injection(injectionConfig)
.packageInfo(packages)
.strategy(strategyConfig)
.execute();
}
}
执行完成后即可看到我们相关的文件已经全部生成,并且注解,介绍已经基本到位。这样就能为我们的开发节省很多时间。
通过源码可以看到旧版本是通过实现不同配置类的实现类,实列化后的配置对象陆续设置我们所需要的配置后,最后通过AutoGenerator 执行execute方法实现。
但是新版本的代码生成器明显有了结构上的变化。
很多配置类采用单例模式的方法,用pricate修饰了构造器,主要用于执行代码生成器的AutoGenerator类必须通过将配置好的DataSourceConfig类传给它才能实现实列化,也就是说优先处理数据源配置。至于其他策略,全局配置则采用了建造者模式,通过Bulider().Build()来进行配置类实例化。这样在一些ture or false的配置上省了很多功夫,用户需要使用时就调用其方法即可,不用设置true or false。发挥了单例模式和建造者模式的优势,值得我们学习参考。
模板配置决定了代码生成的代码模板,一般情况下导入了模板引擎,然后执行模板配置即可,不需要我们额外自己配置。当然,该类也可以让我们自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/template 下面内容修改, 放置到自己的项目src/main/resources/template 目录下。当然这个笔者没有过多研究,大家去自行参考学习。
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
新版的代码生成器并未有过多说明,但是不配置并不会影响代码生成的正常执行,官方旧版上有一定的使用说明,可供大家学习参考。
如有不足之处欢迎指出~
补充
有小伙伴反馈mapper.xml文件一直在java下的目录生成,放在资源目录下需要Ctrl+X,V比较麻烦,不做修改就得在pom中配置build,导出src/main/java下的mapper.xml文件,上面我已作出修改了,在包配置下自定义xml文件生成路径即可。
pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath + "/src/main/resources/mapper"))
最后给出一个通用的生成代码到这给大家使用,基于指定数据库,表名生成基本结构。但是其余基本的信息还是要根据个人配置。比之前那个更为简洁
public class CodeGeneration {
/**
* 根据表名生成相应结构代码
* @param databaseName 数据库名
* @param tableName 表名
*/
public static void Generation(String databaseName,String... tableName){
FastAutoGenerator.create("jdbc:mysql://localhost:3306/"+databaseName+"?&useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai","root","123456")
.globalConfig(builder -> {
builder.author("young")
//启用swagger
//.enableSwagger()
//指定输出目录
.outputDir(System.getProperty("user.dir")+"/src/main/java");
})
.packageConfig(builder -> {
builder.entity("entity")//实体类包名
.parent("com.yy")//父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
.controller("controller")//控制层包名
.mapper("dao")//mapper层包名
//.other("dto")//生成dto目录 可不用
.service("service")//service层包名
.serviceImpl("service.impl")//service实现类包名
//自定义mapper.xml文件输出目录
.pathInfo(Collections.singletonMap(OutputFile.mapperXml,System.getProperty("user.dir")+"/src/main/resources/mapper"));
})
.strategyConfig(builder -> {
//设置要生成的表名
builder.addInclude(tableName)
.addTablePrefix("sys_")//设置表前缀过滤
.entityBuilder()
.enableLombok()
.enableChainModel()
.naming(NamingStrategy.underline_to_camel)//数据表映射实体命名策略:默认下划线转驼峰underline_to_camel
.columnNaming(NamingStrategy.underline_to_camel)//表字段映射实体属性命名规则:默认null,不指定按照naming执行
.idType(IdType.AUTO)//添加全局主键类型
.formatFileName("%s")//格式化实体名称,%s取消首字母I,
.mapperBuilder()
.enableMapperAnnotation()//开启mapper注解
.enableBaseResultMap()//启用xml文件中的BaseResultMap 生成
.enableBaseColumnList()//启用xml文件中的BaseColumnList
.formatMapperFileName("%sMapper")//格式化Dao类名称
.formatXmlFileName("%sMapper")//格式化xml文件名称
.serviceBuilder()
.formatServiceFileName("%sService")//格式化 service 接口文件名称
.formatServiceImplFileName("%sServiceImpl")//格式化 service 接口文件名称
.controllerBuilder()
.enableRestStyle();
})
// .injectionConfig(consumer -> {
// Map customFile = new HashMap<>();
// // 配置DTO(需要的话)但是需要有能配置Dto的模板引擎,比如freemarker,但是这里我们用的VelocityEngine,因此不多作介绍
// customFile.put("DTO.java", "/templates/entityDTO.java.ftl");
// consumer.customFile(customFile);
// })
.execute();
}
}