i
iamwalker
V1
2023/02/10阅读:36主题:前端之巅同款
优雅详细的mybatisplus代码生成器生成代码~
代码生成器
1、导入依赖
<!--导入mybatisplus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<!-- freemarker 模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.6.7</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.12</version>
</dependency>
2、application.yaml配置及对应配置类
spring:
# 数据库配置
datasource:
url: jdbc:mysql://localhost:3306/walker_shiro?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimeZone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 代码生成器相关配置
code-generator:
parent: com.walker.shiro # 父包
author: walker # 作者名称
moduleName: business # 模块名称
controllerName: domain.controller # controller的位置
serviceName: domain.service #service的位置
serviceImplName: domain.service.impl # service实现类位置
entityName: domain.model # 数据库实体类位置
mapperName: domain.mapper # mapper位置
formatEntity: "%s" # entity的名称
formatService: "%sService" # service名称
formatServiceImpl: "%sServiceImpl" # service实现类名称
enableSwagger: false # 是否开启swagger
CodeGeneratorProperties类 这个用于代码生成器的相关配置
package com.walker.shiro.common.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "code-generator")
public class CodeGeneratorProperties {
private String parent;
private String author;
private String moduleName;
private String controllerName;
private String serviceName;
private String serviceImplName;
private String entityName;
private String mapperName;
private String formatEntity;
private String formatService;
private String formatServiceImpl;
private Boolean enableSwagger;
}
DatasourceProperties 用于获取数据库配置
package com.walker.shiro.common.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* spring:
* application:
* name: walker-dianping
* datasource:
* driver-class-name: com.mysql.cj.jdbc.Driver
* url: jdbc:mysql://114.132.164.230:3306/walker-dianping?serverTimezone=UTC
* username: root
* password: walker123
*/
@Component
@Data
@ConfigurationProperties(prefix = "spring.datasource")
public class DatasourceProperties {
private String driverClassName;
private String url;
private String username;
private String password;
}
3、工具类封装
主要分为:
-
全局配置,注意,如果要开启swagger的话,记得导入swagger的依赖,或者导入knife4j -
包配置,主要用于配置包的路径,文件的路径 -
策略配置 -
使用模板:一般有两种,一种是freemarker,一种是velocity,我们这里使用的是freemarker,所以记得导入对应的依赖,否则会发生报错
package com.walker.shiro.common.utils;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.walker.shiro.common.properties.CodeGeneratorProperties;
import com.walker.shiro.common.properties.DatasourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
@Service
public class MyCodeGenerator {
@Resource
private DatasourceProperties datasourceProperties;
@Autowired
private CodeGeneratorProperties codeGeneratorProperties;
/**
* 可以先使用show tables查询数据库所有的表,然后复制到该方法进行执行,
* 使用\n 进行分隔,不需要手动去将字符串转为逗号隔开的形式
*/
public void generate(String tables) {
String[] tablenames = tables.split("\n");
generateCode(tablenames);
}
/**
* 根据表名生成对应的实体类
* tableName:表的名称
*/
public void generateCode(String... tableName) {
//xml生成的位置
String xmlPath = this.getClass().getResource("/").getPath();
//输出地址,这里是生成在target中
String outputUrl = this.getClass().getResource("/").getPath();
FastAutoGenerator.create(datasourceProperties.getUrl(),
datasourceProperties.getUsername(),
datasourceProperties.getPassword())
// 全局基础配置
.globalConfig(builder -> {
builder.author(codeGeneratorProperties.getAuthor()) // 设置作者
.fileOverride() // 覆盖已生成文件
.outputDir(outputUrl); // 指定输出目录
// 开启 swagger 模式
if (codeGeneratorProperties.getEnableSwagger()) {
builder.enableSwagger();
}
})
// 包配置
.packageConfig(builder -> {
builder.parent(codeGeneratorProperties.getParent()) // 设置父包名
.moduleName(codeGeneratorProperties.getModuleName()) // 设置父包模块名
.controller(codeGeneratorProperties.getControllerName())
.service(codeGeneratorProperties.getServiceName())
.serviceImpl(codeGeneratorProperties.getServiceImplName())
.mapper(codeGeneratorProperties.getMapperName())
.entity(codeGeneratorProperties.getEntityName())
.pathInfo(Collections.singletonMap(OutputFile.mapperXml,
xmlPath)); // 设置mapperXml生成路径
})
// 策略配置
.strategyConfig(builder -> {
builder.addInclude(tableName)
.entityBuilder()
.formatFileName(codeGeneratorProperties.getFormatEntity())
.enableLombok() //开启lombok
.controllerBuilder()
.enableRestStyle()
.serviceBuilder()
.formatServiceFileName(codeGeneratorProperties.getFormatService())
.formatServiceImplFileName(codeGeneratorProperties.getFormatServiceImpl())
;
// 设置需要生成的表名
// addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
// .templateEngine(new VelocityTemplateEngine())
.execute();
}
}
4、测试代码生成
-
首先是创建数据库,然后建表,这里提供我的sql作为案例进行测试
CREATE TABLE sys_user(
id INT NOT NULL AUTO_INCREMENT COMMENT 'id' ,
name VARCHAR(32) COMMENT '姓名' ,
username VARCHAR(32) COMMENT '用户名' ,
password VARCHAR(32) COMMENT '密码' ,
create_by VARCHAR(32) COMMENT '创建人' ,
create_time DATETIME COMMENT '创建时间' ,
update_by VARCHAR(32) COMMENT '更新人' ,
update_time DATETIME COMMENT '更新时间' ,
PRIMARY KEY (id)
) COMMENT = '用户表 ';/*SQL@Run*/
ALTER TABLE sys_user COMMENT '用户表';/*SQL@Run*/
CREATE TABLE sys_role(
id INT NOT NULL AUTO_INCREMENT COMMENT 'id' ,
name VARCHAR(32) COMMENT '名称' ,
create_by VARCHAR(32) COMMENT '创建人' ,
create_time DATETIME COMMENT '创建时间' ,
update_by VARCHAR(32) COMMENT '更新人' ,
update_time DATETIME COMMENT '更新时间' ,
PRIMARY KEY (id)
) COMMENT = '角色表 ';/*SQL@Run*/
ALTER TABLE sys_role COMMENT '角色表';/*SQL@Run*/
CREATE TABLE sys_user_role(
id INT NOT NULL AUTO_INCREMENT COMMENT 'id' ,
user_id VARCHAR(32) COMMENT '用户id' ,
role_id VARCHAR(32) COMMENT '角色id' ,
create_by VARCHAR(32) COMMENT '创建人' ,
create_time DATETIME COMMENT '创建时间' ,
update_by VARCHAR(32) COMMENT '更新人' ,
update_time DATETIME COMMENT '更新时间' ,
PRIMARY KEY (id)
) COMMENT = '用户-角色关联表 ';/*SQL@Run*/
ALTER TABLE sys_user_role COMMENT '用户-角色关联表';/*SQL@Run*/
CREATE TABLE sys_menu(
id INT NOT NULL AUTO_INCREMENT COMMENT 'id' ,
name VARCHAR(32) COMMENT '名称' ,
path VARCHAR(32) COMMENT '路径' ,
perm VARCHAR(32) COMMENT '权限' ,
create_by VARCHAR(32) COMMENT '创建人' ,
create_time DATETIME COMMENT '创建时间' ,
update_by VARCHAR(32) COMMENT '更新人' ,
update_time DATETIME COMMENT '更新时间' ,
PRIMARY KEY (id)
) COMMENT = '菜单 ';/*SQL@Run*/
ALTER TABLE sys_menu COMMENT '菜单';/*SQL@Run*/
CREATE TABLE sys_role_menu(
id INT NOT NULL AUTO_INCREMENT COMMENT 'id' ,
role_id VARCHAR(32) COMMENT '角色id' ,
menu_id VARCHAR(32) COMMENT '菜单id' ,
create_by VARCHAR(32) COMMENT '创建人' ,
create_time DATETIME COMMENT '创建时间' ,
update_by VARCHAR(32) COMMENT '更新人' ,
update_time DATETIME COMMENT '更新时间' ,
PRIMARY KEY (id)
) COMMENT = '角色-菜单-关联表 ';/*SQL@Run*/
ALTER TABLE sys_role_menu COMMENT '角色-菜单-关联表';/*SQL@Run*/
-
获取需要生成代码的表的名称,进行复制,如果是第一次生成代码,需要生成全部的代码,可以使用sql指令 show tables
将全部的表名进行复制,然后将该复制的表明放到下面的测试方法中
sys_menu
sys_role
sys_role_menu
sys_user
sys_user_role
-
编写测试类
记得需要要在test/java中进行编写
package com.walker.shiro;
import com.walker.shiro.common.utils.MyCodeGenerator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class CodeGenerateTest {
@Autowired
private MyCodeGenerator myCodeGenerator;
@Test
void generatorCode() {
//该方法使用\n 进行分割
myCodeGenerator.generate("sys_menu\n" +
"sys_role\n" +
"sys_role_menu\n" +
"sys_user\n" +
"sys_user_role");
}
}
-
查看结果
执行方法之后,可以发现在/target/test-classes下按照我们配置的路径就会生成代码了 之后将代码复制到我们想到的路径下就ok了
将文件生成之后放在test-classes中的目的,就是为了防止新生成代码直接将原来的代码直接覆盖了,这样是挺危险的,所以还是先生成在test-classes之后再进行复制会相对安全一些。
5、测试执行mybatisplus是否可行
先新增一条数据,然后再查询该数据
package com.walker.shiro;
import com.alibaba.fastjson.JSON;
import com.walker.shiro.domain.model.SysUser;
import com.walker.shiro.domain.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
public class MybatisplusTest {
@Autowired
private SysUserService sysUserService;
@Test
void test(){
SysUser sysUser = new SysUser();
sysUser.setName("walker");
sysUser.setUsername("walker");
sysUserService.save(sysUser);
SysUser user = sysUserService.getById(sysUser.getId());
log.info("返回用户信息 {}", JSON.toJSONString(user));
}
}
-
返回结果
返回用户信息 {"id":1,"name":"walker","username":"walker"}
有返回对应的结果,是没有问题的
作者介绍
i
iamwalker
V1