代码生成器初体验
开发人员提升的第一步:就是使用轮子或者创建轮子,减少CURD,集火核心业务和技术。
受此感念,开启了使用代码生成器的初体验。
1、Git拉取项目
首先拉取开源项目
https://gitee.com/wuming_yst/renren-generator.git
2、修改配置文件
修改数据库的连接信息,由于目前使用的MySQL8.0版本,所以只修改了MySQL的相关信息,可以根据自己需要修改相关数据库的连接信息。
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/renren?allowPublicKeyRetrieval=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
3、模板管理
说到模板管理,自然是想到增删改查。那下面就演示增加模板需要哪些步骤,修改和删除以此类推
]增加模板
1、第一步:修改需要导入的模板信息
package io.renren.utils;
public static List<String> getTemplates() {
List<String> templates = new ArrayList<String>();
// 1、增加了EntityDto.java.vm模板和Mgr.java.vm模板
templates.add("template/Mgr.java.vm");
templates.add("template/EntityDto.java.vm");
// 2、删除了ServiceImpl.java.vm
// 其实删除就是字面意思,注释掉该行代码
//templates.add("template/ServiceImpl.java.vm");
templates.add("template/Entity.java.vm");
templates.add("template/Dao.xml.vm");
templates.add("template/Controller.java.vm");
templates.add("template/Service.java.vm");
templates.add("template/Dao.java.vm");
templates.add("template/index.vue.vm");
templates.add("template/add-or-update.vue.vm");
if (MongoManager.isMongo()) {
// mongo不需要mapper、sql 实体类需要替换
templates.remove(0);
templates.remove(1);
templates.remove(2);
templates.add("template/MongoEntity.java.vm");
}
return templates;
}
2、第二步:导出已经生成的模板信息
/**
* 获取文件名
* 这里需要注意,templates列表中模板名称需要全部判断,否则返回null,会报错NPE。
*/
public static String getFileName(String template, String className, String packageName, String moduleName) {
String packagePath = "main" + File.separator + "java" + File.separator;
if (StringUtils.isNotBlank(packageName)) {
packagePath += packageName.replace(".", File.separator)
+ File.separator + moduleName + File.separator;
}
// 1、添加的模板需要在这里指定导出文件名称和路径
if (template.contains("EntityDto.java.vm")) {
return packagePath + "dto" + File.separator + className + "ReqDto.java";
}
if (template.contains("Mgr.java.vm")) {
return packagePath + "mgr" + File.separator + className + "Mgr.java";
}
if (template.contains("Entity.java.vm")) {
return packagePath + "entity" + File.separator + className + ".java";
}
if (template.contains("Dao.java.vm")) {
return packagePath + "mapper" + File.separator + className + "Mapper.java";
}
if (template.contains("Service.java.vm")) {
return packagePath + "service" + File.separator + className + "Service.java";
}
if (template.contains("Controller.java.vm")) {
return packagePath + "controller" + File.separator + className + "Controller.java";
}
if (template.contains("Dao.xml.vm")) {
return "main" + File.separator + "resources" + File.separator + "mapper"
+ File.separator + className + "Mapper.xml";
}
if (template.contains("menu.sql.vm")) {
return className.toLowerCase() + "_menu.sql";
}
if (template.contains("index.vue.vm")) {
return "main" + File.separator + "resources" + File.separator + "src"
+ File.separator + "views" + File.separator + "modules" +File.separator
+ moduleName + File.separator + className.toLowerCase() + ".vue";
}
if (template.contains("add-or-update.vue.vm")) {
return "main" + File.separator + "resources" + File.separator + "src"
+ File.separator + "views" + File.separator + "modules" +
File.separator + moduleName + File.separator + className.toLowerCase()
+ "-add-or-update.vue";
}
return null;
}
4、基本模板信息
4.1、Controller.java.vm
进入文件 resources/template/Controller.java.vm。
package ${package}.${moduleName}.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ${package}.${moduleName}.entity.${className};
import ${package}.${moduleName}.mgr.${className}Mgr;
import ${package}.${moduleName}.common.R;
/**
* ${comments}
* @date ${datetime}
*/
@RestController
@RequestMapping("${classname}")
public class ${className}Controller {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private ${className}Mgr ${classname}Mgr;
/**
* 根据条件查询
*/
@RequestMapping(value = "/list", method = RequestMethod.POST)
public R list(@RequestBody ${className} param){
try {
return R.ok().data(${classname}Mgr.selectByCondition(param)).build();
} catch (Exception e) {
logger.error("信息异常", e);
return R.error("信息异常").build();
}
}
}
那么问题来了, p a c k a g e {package} package和 m o d u l e N a m e 在哪里设置? {moduleName}在哪里设置? moduleName在哪里设置? c l a s s N a m e {className} className又是什么呢?
# generator.properties,
# 由此可知package和moduleName则是在配置文件中定义的
# 后续生成的文件路径 com.tjau.controller.XxxController.java
mainPath=com.tjau
package=com
moduleName=tjau
author=abc
email=123456@qq.com
至于
c
l
a
s
s
N
a
m
e
className
className,这张图是否可以解决你的疑惑呢!
4.2、Mgr.java.vm
这时在看Mgr的模板代码是不是感觉很熟悉呢?
package ${package}.${moduleName}.mgr;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ${package}.${moduleName}.entity.${className};
import ${package}.${moduleName}.service.${className}Service;
@Service
public class ${className}Mgr {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private ${className}Service ${classname}Service ;
/**
* 根据条件查询, 使用分页插件
*/
public PageInfo<${className}> selectByCondition(${className} param){
// 1、设置分页
PageHelper.startPage(param.getPageNumber(), param.getPageSize());
List<${className}> list = ${classname}Service.selectByCondition(${classname});
return new PageInfo<>(list);
}
}
4.3、Service.java.vm
package ${package}.${moduleName}.service;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import ${package}.${moduleName}.mapper.${className}Mapper;
@Service
public class ${className}Service {
@Autowired
private ${className}Mapper ${classname}Mapper;
/**
* 根据条件查询
*/
public List<${className}> selectByCondition(${className} ${classname}){
return ${classname}Mapper.selectByCondition(${classname});
}
}
4.4、Dao.java.vm
package ${package}.${moduleName}.mapper;
import org.apache.ibatis.annotations.Mapper;
import ${package}.${moduleName}.entity.${className};
import java.util.List;
@Mapper
public interface ${className}Mapper {
public List<${className}> selectByCondition(${className} ${classname});
}
4.5、Entity.java.vm
package ${package}.${moduleName}.entity;
#if(${hasBigDecimal})
import java.math.BigDecimal;
#end
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
@Data
public class ${className} implements Serializable {
private static final long serialVersionUID = 1L;
#foreach ($column in $columns)
/**
* $column.comments
*/
private $column.attrType $column.attrname;
#end
}
这里又出现了名词 c o l u m n s columns columns以及 c o l u m n . a t t r T y p e column.attrType column.attrType,那么它们有什么意思呢?下面接着放图。
看到这里,你会发现也就那么回事了。同时也点到为止,毕竟只是轮子。
4.6、dao.xml.vm
比较麻烦的可能还是mapper.xml,可能会说为什么不使用mp呢,然后很多框架的使用并非我们说的算。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package}.${moduleName}.mapper.${className}Mapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="${package}.${moduleName}.entity.${className}" id="${classname}Map">
#foreach($column in $columns)
<result property="${column.attrname}" column="${column.columnName}"/>
#end
</resultMap>
<insert id="save" parameterType="${package}.${moduleName}.entity.${className}">
insert into ${tableName} (
#foreach($column in $columns)
${column.columnName}#if($foreach.hasNext),
#end
#end
) values (
#foreach($column in $columns)
#{${column.attrname}}#if($foreach.hasNext),
#end
#end
)
</insert>
<update id="update" parameterType="${package}.${moduleName}.entity.${className}">
update ${tableName} set
#foreach($column in $columns)
<if test=" ${column.attrname} !=null and ${column.attrname} != ''">
${column.columnName} = #{${column.attrname}}#if($foreach.hasNext),
#end
</if>
#end
where id = #{id}
</update>
<delete id="delete" parameterType="java.lang.String">
delete from ${tableName} where id = #{id}
</delete>
<select id="selectByCondition" resultMap="${classname}Map" parameterType="${package}.${moduleName}.entity.${className}">
select
#foreach($column in $columns)
${column.columnName}#if($foreach.hasNext),
#end
#end
from ${tableName}
<where>
#foreach($column in $columns)
<if test=" ${column.attrname} !=null and ${column.attrname} != ''">
${column.columnName} = #{${column.attrname}}#if($foreach.hasNext) and
#end
</if>
#end
</where>
</select>
<select id="selectById" resultMap="${classname}Map" parameterType="${package}.${moduleName}.entity.${className}">
select
#foreach($column in $columns)
${column.columnName}#if($foreach.hasNext),
#end
#end
from ${tableName}
where id = #{id, jdbcType=VARCHAR}
</select>
<select id="selectList" resultMap="${classname}Map">
select
#foreach($column in $columns)
${column.columnName}#if($foreach.hasNext),
#end
#end
from ${tableName}
</select>
</mapper>
可能几个地方还是有些迷惑,补充一下。
<!-- 判断foreach循环是否还有下一项,如果存在则有 逗号或者 and -->
<!-- 例子1 -->
#if($foreach.hasNext),
#end
<!-- 例子2 -->
#if($foreach.hasNext)and
#end
如果你想了解更多,可以充分了解一下velocity(vm)模板引擎语法。
5、总结
在初次体验上的一些心得体会,一些细枝末节的地方花费了好多时间,希望能够为你们的迅速上手提供帮助。