mybatis-plus 的一款自动生成代码常规包就entity,mapper,service,controller,mapper.xml这几层, 如果按照常规的这样配置,官方文档就有说。 mybatis-plus官方教程
但是业务中可能会多一层manager层,这种情况怎么办呢,mybatis-plus提供了自定义的方法,可以自定义包名,但是官方文档提及太少
就这几行的带过了,导致我冥思苦想之下,网上也没找到好的教材,自己就试着用一下
依赖
<!--mybatis plus启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- 代码生成器模板,用于生成代码 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<!-- freemarker模板 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
本项目是基于springboot来使用,其余的什么mapper包路径就不配置了,比较懒
接下来是常规配置
public class MpGeneratorUtils {
public static void main(String[] args) {
String[] tablesName = {"t_user_line"};
tablesName(tablesName);
}
public static void tablesName(String[] tablesName){
String projectPath = System.getProperty("user.dir");
String packageName = "com.unittec.pic.utils.common.augenerator"; //完整包名
String dbUrl="jdbc:mysql://xxx?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8";
String dbDriverName="com.mysql.jdbc.Driver";
String dbUsername="xxx";
String dbPassword="xxx";
FastAutoGenerator.create(dbUrl, dbUsername, dbPassword)
.globalConfig(builder -> {
builder.author("liuxin") // 设置作者
.enableSwagger() // 开启swagger模式
.fileOverride() // 覆盖已生成的目录
.outputDir(projectPath + "/src/main/java") // 指定输出目录.
.disableOpenDir() // 禁止打开输出目录
.dateType(DateType.TIME_PACK) // 指定时间类型
.commentDate("yyyy-MM-dd HH:ss:mm"); // 注释日期
})
.packageConfig(builder -> {
builder.parent(packageName) // 设置父包名
.other("")// manager包
//.other("manager.impl") // manager.impl 实现类包名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath + "/src/main/resources/mappers")); // 设置mapperXml生成路径
})
.templateConfig(builder -> {
builder.entity("templates/entity.java")
.service("templates/service.java")
.serviceImpl("templates/serviceImpl.java")
.mapper("templates/mapper.java")
.mapperXml("templates/mapper.xml")
.controller("templates/controller.java");
})
.injectionConfig(builder -> {
/*Map<String,String> mapImpl1 = new HashMap();
mapImpl1.put("1111","11111");
builder.customFile(mapImpl1);*/
builder.beforeOutputFile((tableInfo,objMap) -> {
objMap.put("supperManagerClassPackage",classInfo(IManager.class)[0]);
objMap.put("supperManagerClassName",classInfo(IManager.class)[1]);
objMap.put("managerName","I" + tableInfo.getEntityName() + "Manager");
objMap.put("managerNameImpl",tableInfo.getEntityName() + "ManagerImpl");
objMap.put("superManagerImplClassName",classInfo(BaseManager.class)[1]);
objMap.put("superManagerImplClassPackage",classInfo(BaseManager.class)[0]);
objMap.put("responseInfoName",classInfo(ResponseInfo.class)[1]);
objMap.put("responseInfoPackage",classInfo(ResponseInfo.class)[0]);
objMap.put("sqlAlias","${alias}");
Map<String,String> mapImpl = new HashMap();
mapImpl.put("manager/I" + tableInfo.getEntityName() + "Manager.java","templates/manager.java.ftl");
mapImpl.put("manager/impl/" + tableInfo.getEntityName() + "ManagerImpl.java", "templates/managerImpl.java.ftl");
builder.customFile(mapImpl);
}); // 输出文件之前消费者
})
.strategyConfig(builder -> {
builder.addInclude(tablesName) // 设置需要生成的表名
.enableCapitalMode()// 开启大写命名
.entityBuilder() // 实体类配置
.enableLombok() // 开启lombok注解
.enableTableFieldAnnotation() // 开启生成实体时生成字段注解
.serviceBuilder() // service配置
.superServiceImplClass(BaseService.class) // service实现类的包
.mapperBuilder() // mapper层配置
.superClass(BaseMapper.class)
.enableMapperAnnotation()// 开启mapper注解
.enableBaseColumnList() //启用 BaseColumnList
.enableBaseResultMap() // 启用 BaseResultMap 生成
.controllerBuilder()
.superClass(BaseController.class)
.enableRestStyle() // 开启驼峰转连字符
.enableHyphenStyle(); // 开启生成@RestController 控制器
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
public static String[] classInfo(Class tClass){
String[] s = new String[2];
s[0] = tClass.getName();
s[1] = tClass.getSimpleName();
System.out.println(s[0] + "\n" + s[1]);
return s;
}
这基本都是官方文档上面的操作,按着操作就行了,最关键的是自定义 断点调试
发现tableInfo与objmap中存着很多数据,这就是从数据库中读出来的数据,与自己配置的一些参数。代码生成器就是一个工厂,获取数据之后通过模板进行生产,模板在哪里呢?源码
在 AutoGenerator 中如果我们不配置模板的的话,默认使用 Velocity 引擎模板,在 templates文件目录下提供了三种模板引擎 .vm是Velocity 默认。 .ftl是 freemarker模板。 .btl 是beetl模板。本次使用freemarker模板,为了与业务代码相吻合,进行了模板的重构 serviceImpl层
package ${package.ServiceImpl};
import com.github.pagehelper.PageInfo;
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import ${package.Entity}.${entity};
import ${package.Other}${entity}.manager.${managerName};
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* <p>
* ${table.comment!} 服务实现类
* </p>
*
* @author ${author}
* @since ${date}
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass} implements ${table.serviceName} {
@Autowired
private ${managerName} ${managerName?uncap_first};
/***
* @Title: add
* @Param: [${entity?uncap_first}]
* @description: 新增数据
* @author: ${author}
* @date: ${date}
* @return: void
* @throws:
* @param ${entity?uncap_first}
*/
@Override
public void add(${entity} ${entity?uncap_first}) {
${managerName?uncap_first}.add(${entity?uncap_first});
}
/***
* @Title: queryByPage
* @Param: [${entity?uncap_first}, page, limit]
* @description: 条件分页查询
* @author: ${author}
* @date: ${date}
* @return: com.github.pagehelper.PageInfo<${package.Entity}.${entity}>
* @throws:
*/
@Override
public PageInfo<${entity}> queryByPage(${entity} ${entity?uncap_first},Integer page, Integer limit) {
return ${managerName?uncap_first}.queryForPage(${entity?uncap_first},page,limit);
}
/***
* @Title: query
* @Param: [${entity?uncap_first}]
* @description: 根据实体条件查询
* @author: ${author}
* @date: ${date}
* @return: java.util.List<${package.Entity}.${entity}>
* @throws:
* @param ${entity?uncap_first}
*/
@Override
public List<${entity}> query(${entity} ${entity?uncap_first}) {
return ${managerName?uncap_first}.queryAll(${entity?uncap_first});
}
/***
* @Title: queryById
* @Param: [id]
* @description: 通过主键查询
* @author: ${author}
* @date: ${date}
* @return: ${package.Entity}.${entity}
* @throws:
* @param id
*/
@Override
public ${entity} queryById(String id) {
return ${managerName?uncap_first}.selectById(id);
}
/***
* @Title: updateById
* @Param: [${entity?uncap_first}]
* @description: 通过id修改参数
* @author: ${author}
* @date: ${date}
* @return: void
* @throws:
* @param ${entity?uncap_first}
*/
@Override
public void updateById(${entity} ${entity?uncap_first}) {
${managerName?uncap_first}.updateById(${entity?uncap_first});
}
/***
* @Title: updateByConditon
* @Param: [${entity?uncap_first}, condition]
* @description: 按条件跟新数据
* @author: ${author}
* @date: ${date}
* @return: void
* @throws:
*/
@Override
public void updateByConditon(${entity} ${entity?uncap_first},${entity} condition) {
${managerName?uncap_first}.updateByConditon(${entity?uncap_first},condition);
}
/***
* @Title: deleteById
* @Param: [id]
* @description: 通过主键删除
* @author: ${author}
* @date: ${date}
* @return: void
* @throws:
* @param id
*/
@Override
public void deleteById(String id) {
${managerName?uncap_first}.deleteById(id);
}
/***
* @Title: deleteByIds
* @Param: [ids]
* @description: 批量删除
* @author: ${author}
* @date: ${date}
* @return: void
* @throws:
* @param ids
*/
@Override
public void deleteByIds(String[] ids) {
${managerName?uncap_first}.deleteByIds(ids);
}
}
</#if>
对于新建的manager层
package ${package.Other}${entity}.manager.impl;
import ${package.Entity}.${entity};
import ${superManagerImplClassPackage};
import ${superMapperClassPackage};
import org.springframework.stereotype.Repository;
import ${package.Other}${entity}.manager.${managerName};
import org.springframework.beans.factory.annotation.Autowired;
import ${package.Mapper}.${table.mapperName};
/**
* <p>
* ${table.comment!} 服务实现类
* </p>
*
* @author ${author}
* @since ${date}
*/
@Repository
public class ${managerNameImpl} extends ${superManagerImplClassName}<${entity}> implements ${managerName} {
@Autowired
private ${table.mapperName} ${table.mapperName?uncap_first};
/**
* 获取数据操作接口Mapper
*
* @return
*/
@Override
protected ${superMapperClass}<${entity}> getDao() {
return ${table.mapperName?uncap_first};
}
}
里面的一些配置是参数是没有的,所以我们需要手动去配置参数
.injectionConfig(builder -> {
/*Map<String,String> mapImpl1 = new HashMap();
mapImpl1.put("1111","11111");
builder.customFile(mapImpl1);*/
builder.beforeOutputFile((tableInfo,objMap) -> {
objMap.put("supperManagerClassPackage",classInfo(IManager.class)[0]);
objMap.put("supperManagerClassName",classInfo(IManager.class)[1]);
objMap.put("managerName","I" + tableInfo.getEntityName() + "Manager");
objMap.put("managerNameImpl",tableInfo.getEntityName() + "ManagerImpl");
objMap.put("superManagerImplClassName",classInfo(BaseManager.class)[1]);
objMap.put("superManagerImplClassPackage",classInfo(BaseManager.class)[0]);
objMap.put("responseInfoName",classInfo(ResponseInfo.class)[1]);
objMap.put("responseInfoPackage",classInfo(ResponseInfo.class)[0]);
objMap.put("sqlAlias","${alias}");
Map<String,String> mapImpl = new HashMap();
mapImpl.put("manager/I" + tableInfo.getEntityName() + "Manager.java","templates/manager.java.ftl");
mapImpl.put("manager/impl/" + tableInfo.getEntityName() + "ManagerImpl.java", "templates/managerImpl.java.ftl");
builder.customFile(mapImpl);
}); // 输出文件之前消费者
})
这一层便是自定义的一些参数配置。生成的文件路劲
请多指教!