目录
基于velocity达梦数据库代码生成
1.前言
刚来新公司,做的是政府项目,要求技术国产化,由于使用的数据库是dm7并没有集成代码生成功能,
每次写个业务的基础代码全是纯手敲,有人说用idea的插件进行生成代码
但情况是这样的,idea的datasource并没有dm的数据库
那么可以用mybatis-plus?
mp从3.2.0之后可以支持达梦数据库了
但是我并不想为了实现一个简单的代码生成功能,去进行强行依赖.
然后就花了两天时间面向百度自己写了一个代码生成器.
(不能只会用,也了解了一下原理,各位同学多多指教)
2.代码生成原理
代码生成是基于数据库进行的,简单的分为以下5个步骤:
1.查询对应的业务表信息以及业务表字段信息(比如字段描述,字段类型,字段约束...)
2.将表信息与字段信息封装为对象,并通过该信息,解析出对应的生产代码需要的信息(比如表的字段名解析为java变量名create_time->createTime,又比如字段的数据类型解析成java数据类型 varchar->String........)
3.准备模板文件,模板文件主要是提供关键的固定代码(比如xml头部固定的写法<?xml version="1.0" encoding="UTF-8" ?>)
)以及模板语法进行动态代码的替换写入(比如类名,方法名....)
4.模板渲染,将准备好的代码生成信息渲染到模板里,进行动态的生成
5.将渲染好的内容,进行写入到指定路径(一般是写入到当前项目下的路径)
3. 模板引擎
生成代码首先需要数据源,mybatis或者jdbc都可以,只要能查出表与字段的信息即可
模板引擎也有很多Velocity、Freemarker、Beetl等,这里推荐是用更简单一点的Velocity
4.直接上代码
环境依赖于spring+mybatis 这里不赘述
模板依赖依赖
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
1.常量代码
GenConstants.java
package xyz.hashdog.gen.constants;
/**
*代码生成常量
* @author: th
* @date: 2020/1/14 18:05
*/
public class GenConstants
{
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/** 数据库字符串类型 */
public static final String[] COLUMNTYPE_STR = { "CHAR", "VARCHAR", "NARCHAR", "VARCHAR2", "TINYTEXT", "TEXT",
"MEDIUMTEXT", "LONGTEXT" };
/** 数据库时间类型 */
public static final String[] COLUMNTYPE_TIME = { "DATETIME", "TIME", "DATE", "TIMESTAMP" };
/** 数据库数字类型 */
public static final String[] COLUMNTYPE_NUMBER = { "TINYINT", "SMALLINT", "MEDIUMINT", "INT", "NUMBER", "INTEGER",
"BIGINT", "FLOAT", "FLOAT", "DOUBLE", "DECIMAL" };
/** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
/** 页面不需要显示的列表字段 */
public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time" };
/** 页面不需要查询字段 */
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time", "remark" };
/** 字符串类型 */
public static final String TYPE_STRING = "String";
/** 整型 */
public static final String TYPE_INTEGER = "Integer";
/** 长整型 */
public static final String TYPE_LONG = "Long";
/** 浮点型 */
public static final String TYPE_DOUBLE = "Double";
/** 高精度计算类型 */
public static final String TYPE_BIGDECIMAL = "BigDecimal";
/** 时间类型 */
public static final String TYPE_DATE = "Date";
/** 需要 */
public static final String REQUIRE = "1";
}
2.工具代码
StringUtils.java
/**
* Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
*/
package xyz.hashdog.util;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
* @author ThinkGem
* @version 2013-05-22
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils {
private static final char SEPARATOR = '_';
private static final String CHARSET_NAME = "UTF-8";
/**
* 转换为字节数组
* @param str
* @return
*/
public static byte[] getBytes(String str){
if (str != null){
try {
return str.getBytes(CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
return null;
}
}else{
return null;
}
}
/**
* 转换为Boolean类型
* 'true', 'on', 'y', 't', 'yes' or '1' (case insensitive) will return true. Otherwise, false is returned.
*/
public static Boolean toBoolean(final Object val){
if (val == null){
return false;
}
return BooleanUtils.toBoolean(val.toString()) || "1".equals(val.toString());
}
/**
* 转换为字节数组
* @param bytes
* @return
*/
public static String toString(byte[] bytes){
try {
return new String(bytes, CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
return EMPTY;
}
}
/**
* 如果对象为空,则使用defaultVal值
* see: ObjectUtils.toString(obj, defaultVal)
* @param obj
* @param defaultVal
* @return
*/
public static String toString(final Object obj, final String defaultVal) {
return obj == null ? defaultVal : obj.toString();
}
/**
* 是否包含字符串
* @param str 验证字符串
* @param strs 字符串组
* @return 包含返回true
*/
public static boolean inString(String str, String... strs){
if (str != null){
for (String s : strs){
if (str.equals(trim(s))){
return true;
}
}
}
return false;
}
/**
* 替换掉HTML标签方法
*/
public static String replaceHtml(String html) {
if (isBlank(html)){
return "";
}
String regEx = "<.+?>";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(html);
String s = m.replaceAll("");
return s;
}
/**
* 替换为手机识别的HTML,去掉样式及属性,保留回车。
* @param html
* @return
*/
public static String replaceMobileHtml(String html){
if (html == null){
return "";
}
return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
}
/**
* 缩略字符串(不区分中英文字符)
* @param str 目标字符串
* @param length 截取长度
* @return
*/
public static String abbr(String str, int length) {
if (str == null) {
return "";
}
try {
StringBuilder sb = new StringBuilder();
int currentLength = 0;
for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
currentLength += String.valueOf(c).getBytes("GBK").length;
if (currentLength <= length - 3) {
sb.append(c);
} else {
sb.append("...");
break;
}
}
return sb.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
public static String abbr2(String param, int length) {
if (param == null) {
return "";
}
StringBuffer result = new StringBuffer();
int n = 0;
char temp;
boolean isCode = false; // 是不是HTML代码
boolean isHTML = false; // 是不是HTML特殊字符,如
for (int i = 0; i < param.length(); i++) {
temp = param.charAt(i);
if (temp == '<') {
isCode = true;
} else if (temp == '&') {
isHTML = true;
} else if (temp == '>' && isCode) {
n = n - 1;
isCode = false;
} else if (temp == ';' && isHTML) {
isHTML = false;
}
try {
if (!isCode && !isHTML) {
n += String.valueOf(temp).getBytes("GBK").length;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (n <= length - 3) {
result.append(temp);
} else {
result.append("...");
break;
}
}
// 取出截取字符串中的HTML标记
String temp_result = result.toString().replaceAll("(>)[^<>]*(<?)",
"$1$2");
// 去掉不需要结素标记的HTML标记
temp_result = temp_result
.replaceAll(
"</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>",
"");
// 去掉成对的HTML标记
temp_result = temp_result.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>",
"$2");
// 用正则表达式取出标记
Pattern p = Pattern.compile("<([a-zA-Z]+)[^<>]*>");
Matcher m = p.matcher(temp_result);
List<String> endHTML = Lists.newArrayList();
while (m.find()) {
endHTML.add(m.group(1));
}
// 补全不成对的HTML标记
for (int i = endHTML.size() - 1; i >= 0; i--) {
result.append("</");
result.append(endHTML.get(i));
result.append(">");
}
return result.toString();
}
/**
* 转换为Double类型
*/
public static Double toDouble(Object val){
if (val == null){
return 0D;
}
try {
return Double.valueOf(trim(val.toString()));
} catch (Exception e) {
return 0D;
}
}
/**
* 转换为Float类型
*/
public static Float toFloat(Object val){
return toDouble(val).floatValue();
}
/**
* 转换为Long类型
*/
public static Long toLong(Object val){
return toDouble(val).longValue();
}
/**
* 转换为Integer类型
*/
public static Integer toInteger(Object val){
return toLong(val).intValue();
}
/**
* 获得i18n字符串
*/
public static String getMessage(String code, Object[] args) {
LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class);
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
Locale localLocale = localLocaleResolver.resolveLocale(request);
return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale);
}
/**
* 获得用户远程地址
*/
public static String getRemoteAddr(HttpServletRequest request){
String remoteAddr = request.getHeader("X-Real-IP");
if (isNotBlank(remoteAddr)) {
remoteAddr = request.getHeader("X-Forwarded-For");
}else if (isNotBlank(remoteAddr)) {
remoteAddr = request.getHeader("Proxy-Client-IP");
}else if (isNotBlank(remoteAddr)) {
remoteAddr = request.getHeader("WL-Proxy-Client-IP");
}
return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
}
/**
* 驼峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toCamelCase(String s) {
if (s == null) {
return null;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == SEPARATOR) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* 驼峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toCapitalizeCamelCase(String s) {
if (s == null) {
return null;
}
s = toCamelCase(s);
return s.substring(0, 1).toUpperCase() + s.substring(1);
}
/**
* 驼峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toUnderScoreCase(String s) {
if (s == null) {
return null;
}
StringBuilder sb = new StringBuilder();
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
boolean nextUpperCase = true;
if (i < (s.length() - 1)) {
nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
}
if ((i > 0) && Character.isUpperCase(c)) {
if (!upperCase || !nextUpperCase) {
sb.append(SEPARATOR);
}
upperCase = true;
} else {
upperCase = false;
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 转换为JS获取对象值,生成三目运算返回结果
* @param objectString 对象串
* 例如:row.user.id
* 返回:!row?'':!row.user?'':!row.user.id?'':row.user.id
*/
public static String jsGetVal(String objectString){
StringBuilder result = new StringBuilder();
StringBuilder val = new StringBuilder();
String[] vals = split(objectString, ".");
for (int i=0; i<vals.length; i++){
val.append("." + vals[i]);
result.append("!"+(val.substring(1))+"?'':");
}
result.append(val.substring(1));
return result.toString();
}
public static String decodeStr(String str) throws UnsupportedEncodingException {
return new String(str.getBytes("iso-8859-1"), "utf-8");
}
/**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public static String convertToCamelCase(String name)
{
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty())
{
// 没必要转换
return "";
}
else if (!name.contains("_"))
{
// 不含下划线,仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String[] camels = name.split("_");
for (String camel : camels)
{
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty())
{
continue;
}
// 首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
return result.toString();
}
}
GenUtils.java
package xyz.hashdog.gen.util;
import xyz.hashdog.gen.bean.GenTable;
import xyz.hashdog.gen.bean.GenTableColumn;
import xyz.hashdog.gen.constants.GenConstants;
import xyz.hashdog.util.StringUtils;
import org.apache.velocity.texen.util.FileUtil;
import java.util.Arrays;
import java.util.List;
/**
*代码生成工具
* @author: th
* @date: 2020/1/14 18:05
*/
public class GenUtils
{
/**
*初始化表的字段信息
* @author: th
* @date: 2020/1/14 18:06
* @param column 字段信息
* @param table 表信息
* @return: void
*/
public static void initColumnField(GenTableColumn column, GenTable table)
{
String dataType = getDbType(column.getColumnType());
String columnName = column.getColumnName();
// 设置java字段名
column.setJavaField(StringUtils.toCamelCase(columnName));
if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType))
{
column.setJavaType(GenConstants.TYPE_STRING);
}
else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType))
{
column.setJavaType(GenConstants.TYPE_DATE);
}
else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType))
{
// 如果是浮点型
String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ",");
if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0)
{
column.setJavaType(GenConstants.TYPE_DOUBLE);
}
// 如果是整形
else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10)
{
column.setJavaType(GenConstants.TYPE_INTEGER);
}
// 长整形
else
{
column.setJavaType(GenConstants.TYPE_LONG);
}
}
// 插入字段(默认所有字段都需要插入)
column.setIsInsert(GenConstants.REQUIRE);
// 编辑字段
if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName) && !column.isPk())
{
column.setIsEdit(GenConstants.REQUIRE);
}
// 列表字段
if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !column.isPk())
{
column.setIsList(GenConstants.REQUIRE);
}
// 查询字段
if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk())
{
column.setIsQuery(GenConstants.REQUIRE);
}
}
/**
*校验数组是否包含指定值
* @author: th
* @date: 2020/1/14 18:07
* @param arr 数组
* @param targetValue 指定值
* @return: boolean
*/
public static boolean arraysContains(String[] arr, String targetValue)
{
return Arrays.asList(arr).contains(targetValue);
}
/**
*根据包路径获取模块名称(取最后一个)
* @author: th
* @date: 2020/1/14 18:08
* @param packageName 包路径
* @return: java.lang.String
*/
public static String getModuleName(String packageName)
{
int lastIndex = packageName.lastIndexOf(".");
int nameLength = packageName.length();
String moduleName = StringUtils.substring(packageName, lastIndex + 1, nameLength);
return moduleName;
}
/**
*根据表名获取业务名称(去掉表前缀)
* @author: th
* @date: 2020/1/14 18:08
* @param tableName 表名
* @return: java.lang.String
*/
public static String getBusinessName(String tableName)
{
int lastIndex = tableName.indexOf("_");
int nameLength = tableName.length();
String businessName = StringUtils.substring(tableName, lastIndex + 1, nameLength);
return StringUtils.toCamelCase(businessName);
}
/**
*表名转换为java类名,驼峰命名
* @author: th
* @date: 2020/1/14 18:09
* @param tableName 表名
* @param isRemovePre 是否去掉表前缀
* @return: java.lang.String
*/
public static String convertClassName(String tableName,boolean isRemovePre)
{
String str = "";
if(isRemovePre){
int lastIndex = tableName.indexOf("_");
int nameLength = tableName.length();
str = StringUtils.substring(tableName, lastIndex + 1, nameLength);
}else{
str=tableName;
}
return StringUtils.convertToCamelCase(str);
}
/**
*获取数据库字段类型
* @author: th
* @date: 2020/1/14 18:10
* @param columnType
* @return: java.lang.String
*/
public static String getDbType(String columnType)
{
if (StringUtils.indexOf(columnType, "(") > 0)
{
return StringUtils.substringBefore(columnType, "(");
}
else
{
return columnType;
}
}
/**
*获取字段长度
* @author: th
* @date: 2020/1/14 18:10
* @param columnType
* @return: java.lang.Integer
*/
public static Integer getColumnLength(String columnType)
{
if (StringUtils.indexOf(columnType, "(") > 0)
{
String length = StringUtils.substringBetween(columnType, "(", ")");
return Integer.valueOf(length);
}
else
{
return 0;
}
}
/**
*获取空数组
* @author: th
* @date: 2020/1/14 18:11
* @param length
* @return: java.lang.String[]
*/
public static String[] emptyList(int length)
{
String[] values = new String[length];
for (int i = 0; i < length; i++)
{
values[i] = StringUtils.EMPTY;
}
return values;
}
/**
*设置主键信息(查找带组件的字段)
* @author: th
* @date: 2020/1/14 18:11
* @param table 表信息
* @param columns 字段信息
* @return: void
*/
public static void setPkColumn(GenTable table, List<GenTableColumn> columns)
{
for (GenTableColumn column : columns)
{
if (column.isPk())
{
table.setPkColumn(column);
break;
}
}
if (null==table.getPkColumn())
{
table.setPkColumn(columns.get(0));
}
}
/**
*创建目录
* @author: th
* @date: 2020/1/14 19:19
* @param fileName 文件路径
* @return: void
*/
public static void mkdir(String fileName) {
int lastIndex = fileName.lastIndexOf("/");
String dir = StringUtils.substring(fileName, 0, lastIndex);
FileUtil.mkdir(dir);
}
}
VelocityInitializer.java
package xyz.hashdog.gen.util;
import java.util.Properties;
import xyz.hashdog.gen.constants.GenConstants;
import org.apache.velocity.app.Velocity;
/**
*VelocityEngine初始化工厂
* @author: th
* @date: 2020/1/14 18:12
*/
public class VelocityInitializer
{
/**
* 初始化vm方法
*/
public static void initVelocity()
{
Properties p = new Properties();
try
{
// 加载classpath目录下的vm文件
p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 定义字符集
p.setProperty(Velocity.ENCODING_DEFAULT, GenConstants.UTF8);
p.setProperty(Velocity.OUTPUT_ENCODING, GenConstants.UTF8);
// 初始化Velocity引擎,指定配置Properties
Velocity.init(p);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
VelocityUtils.java
package xyz.hashdog.gen.util;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import xyz.hashdog.gen.bean.GenTable;
import xyz.hashdog.gen.bean.GenTableColumn;
import xyz.hashdog.gen.constants.GenConstants;
import xyz.hashdog.util.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.velocity.VelocityContext;
/**
*模板引擎操作工具
* @author: th
* @date: 2020/1/14 18:12
*/
public class VelocityUtils
{
/** 项目空间路径 */
private static final String PROJECT_PATH = "/src/main/java";
/** mybatis空间路径 */
private static final String MYBATIS_PATH = "/src/main/resources/mapper";
/**
* 设置模板替换数据
* @param genTable
* @return
*/
public static VelocityContext prepareContext(GenTable genTable)
{
String packageName = genTable.getPackageName();
String functionName = genTable.getFunctionName();
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("tableName", genTable.getTableName());
velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】");
velocityContext.put("ClassName", genTable.getClassName());
velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
velocityContext.put("moduleName", genTable.getModuleName());
velocityContext.put("businessName", genTable.getBusinessName());
velocityContext.put("basePackage", getPackagePrefix(packageName));
velocityContext.put("packageName", packageName);
velocityContext.put("author", StringUtils.isNotEmpty(genTable.getFunctionAuthor())?genTable.getFunctionAuthor():getAuthor() );
velocityContext.put("datetime", DateFormatUtils.format(new Date(),"yyyy-MM-dd"));
velocityContext.put("pkColumn", genTable.getPkColumn());
velocityContext.put("importList", getImportList(genTable.getColumns()));
velocityContext.put("columns", genTable.getColumns());
velocityContext.put("table", genTable);
return velocityContext;
}
/**
*根据字段类型,获取需要导入的依赖
* @author: th
* @date: 2020/1/14 18:14
* @param columns 字段信息
* @return: java.util.HashSet<java.lang.String>
*/
public static HashSet<String> getImportList(List<GenTableColumn> columns)
{
HashSet<String> importList = new HashSet<String>();
for (GenTableColumn column : columns)
{
if ( GenConstants.TYPE_DATE.equals(column.getJavaType()))
{
importList.add("java.util.Date");
}
else if ( GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType()))
{
importList.add("java.math.BigDecimal");
}
}
return importList;
}
/**
*获取包前缀
* @author: th
* @date: 2020/1/14 18:15
* @param packageName 包路径
* @return: java.lang.String
*/
public static String getPackagePrefix(String packageName)
{
int lastIndex = packageName.lastIndexOf(".");
String basePackage = StringUtils.substring(packageName, 0, lastIndex);
return basePackage;
}
/**
*获取模板路径
* @author: th
* @date: 2020/1/14 18:15
* @param
* @return: java.util.List<java.lang.String>
*/
public static List<String> getTemplateList()
{
List<String> templates = new ArrayList<String>();
templates.add("vm/java/bean.java.vm");
templates.add("vm/java/dao.java.vm");
templates.add("vm/java/service.java.vm");
templates.add("vm/java/serviceImpl.java.vm");
templates.add("vm/java/controller.java.vm");
templates.add("vm/xml/mapper.xml.vm");
return templates;
}
/**
*获取写入文件路径
* @author: th
* @date: 2020/1/14 18:16
* @param template 模板
* @param genTable 表信息
* @return: java.lang.String
*/
public static String getFileName(String template, GenTable genTable)
{
// 文件名称
String fileName = "";
// 包路径
String packageName = genTable.getPackageName();
// 模块名
String moduleName = genTable.getModuleName();
// 大写类名
String className = genTable.getClassName();
String pjPath=getOutputDir();
String javaPath =pjPath+PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
String mybatisPath = pjPath+MYBATIS_PATH ;
if (template.contains("bean.java.vm"))
{
fileName = javaPath+"/bean/"+className+".java" ;
}
else if (template.contains("dao.java.vm"))
{
fileName = javaPath+"/dao/"+className+"Dao.java" ;
}
else if (template.contains("service.java.vm"))
{
fileName = javaPath+"/service/I"+className+"Service.java" ;
}
else if (template.contains("serviceImpl.java.vm"))
{
fileName = javaPath+"/service/impl/"+className+"ServiceImpl.java" ;
}
else if (template.contains("controller.java.vm"))
{
fileName = javaPath+"/controller/"+className+"Controller.java" ;
}
else if (template.contains("mapper.xml.vm"))
{
fileName = mybatisPath+"/"+className+"Mapper.xml" ;
}
return fileName;
}
/**
*获取当前项目路径
* @author: th
* @date: 2020/1/14 18:16
* @param
* @return: java.lang.String
*/
public static String getOutputDir() {
return System.getProperty("user.dir").replace("\\","/");
}
/**
*获取当前系统用户名
* @author: th
* @date: 2020/1/14 18:17
* @param
* @return: java.lang.String
*/
public static String getAuthor(){
return System.getProperty("user.name");
}
}
3.实体类
GenTable.java
package xyz.hashdog.gen.bean;
import org.hibernate.validator.constraints.NotBlank;
import java.util.List;
import javax.validation.Valid;
/**
*表映射对象
* @author: th
* @date: 2020/1/14 18:00
*/
public class GenTable
{
private static final long serialVersionUID = 1L;
/** 表名称 */
@NotBlank(message = "表名称不能为空")
private String tableName;
/** 表描述 */
@NotBlank(message = "表描述不能为空")
private String tableComment;
/** 实体类名称(首字母大写) */
@NotBlank(message = "实体类名称不能为空")
private String className;
/** 生成包路径 */
@NotBlank(message = "生成包路径不能为空")
private String packageName;
/** 生成模块名 */
@NotBlank(message = "生成模块名不能为空")
private String moduleName;
/** 生成业务名 */
@NotBlank(message = "生成业务名不能为空")
private String businessName;
/** 生成功能名 */
@NotBlank(message = "生成功能名不能为空")
private String functionName;
/** 生成作者 */
@NotBlank(message = "作者不能为空")
private String functionAuthor;
/** 主键信息 */
private xyz.hashdog.gen.bean.GenTableColumn pkColumn;
/** 表列信息 */
@Valid
private List<xyz.hashdog.gen.bean.GenTableColumn> columns;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getTableComment() {
return tableComment;
}
public void setTableComment(String tableComment) {
this.tableComment = tableComment;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public String getBusinessName() {
return businessName;
}
public void setBusinessName(String businessName) {
this.businessName = businessName;
}
public String getFunctionName() {
return functionName;
}
public void setFunctionName(String functionName) {
this.functionName = functionName;
}
public String getFunctionAuthor() {
return functionAuthor;
}
public void setFunctionAuthor(String functionAuthor) {
this.functionAuthor = functionAuthor;
}
public xyz.hashdog.gen.bean.GenTableColumn getPkColumn() {
return pkColumn;
}
public void setPkColumn(xyz.hashdog.gen.bean.GenTableColumn pkColumn) {
this.pkColumn = pkColumn;
}
public List<xyz.hashdog.gen.bean.GenTableColumn> getColumns() {
return columns;
}
public void setColumns(List<xyz.hashdog.gen.bean.GenTableColumn> columns) {
this.columns = columns;
}
}
GenTableColumn.java
package xyz.hashdog.gen.bean;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.NotBlank;
/**
*表字段信息映射对象
* @author: th
* @date: 2020/1/14 18:01
*/
public class GenTableColumn
{
private static final long serialVersionUID = 1L;
/** 列名称 */
private String columnName;
/** 列描述 */
private String columnComment;
/** 列类型 */
private String columnType;
/** JAVA类型 */
private String javaType;
/** JAVA字段名 */
@NotBlank(message = "Java属性不能为空")
private String javaField;
/** 是否主键(1是) */
private String isPk;
/** 是否必填(1是) */
private String isRequired;
/** 是否为插入字段(1是) */
private String isInsert;
/** 是否编辑字段(1是) */
private String isEdit;
/** 是否列表字段(1是) */
private String isList;
/** 是否查询字段(1是) */
private String isQuery;
/** 排序 */
private Integer sort;
public boolean isPk()
{
return isPk(this.isPk);
}
public boolean isPk(String isPk)
{
return isPk != null && StringUtils.equals("1", isPk);
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public String getColumnComment() {
return columnComment;
}
public void setColumnComment(String columnComment) {
this.columnComment = columnComment;
}
public String getColumnType() {
return columnType;
}
public void setColumnType(String columnType) {
this.columnType = columnType;
}
public String getJavaType() {
return javaType;
}
public void setJavaType(String javaType) {
this.javaType = javaType;
}
public String getJavaField() {
return javaField;
}
public void setJavaField(String javaField) {
this.javaField = javaField;
}
public String getIsPk() {
return isPk;
}
public void setIsPk(String isPk) {
this.isPk = isPk;
}
public String getIsRequired() {
return isRequired;
}
public void setIsRequired(String isRequired) {
this.isRequired = isRequired;
}
public String getIsInsert() {
return isInsert;
}
public void setIsInsert(String isInsert) {
this.isInsert = isInsert;
}
public String getIsEdit() {
return isEdit;
}
public void setIsEdit(String isEdit) {
this.isEdit = isEdit;
}
public String getIsList() {
return isList;
}
public void setIsList(String isList) {
this.isList = isList;
}
public String getIsQuery() {
return isQuery;
}
public void setIsQuery(String isQuery) {
this.isQuery = isQuery;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
}
4.service与serviceImpl
IGenTableService.java
package xyz.hashdog.gen.service;
import xyz.hashdog.gen.bean.GenTable;
import java.util.List;
import java.util.Map;
/**
*表信息服务层
* @author: th
* @date: 2020/1/14 18:02
*/
public interface IGenTableService
{
/**
*根据模式名,表面获取表信息与字段信息
* @author: th
* @date: 2020/1/13 14:37
* @param schemaName
* @param tableName
* @return: java.util.List<gen.bean.GenTable>
*/
GenTable selectDbTableByST(String schemaName, String tableName);
}
IGenTableColumnService
package xyz.hashdog.gen.service;
import xyz.hashdog.gen.bean.GenTableColumn;
import java.util.List;
/**
*表字段信息服务层
* @author: th
* @date: 2020/1/14 18:02
*/
public interface IGenTableColumnService
{
/**
*根据表名查询表字段信息
* @author: th
* @date: 2020/1/14 10:27
* @param schemaName
* @param tableName
* @return: java.util.List<xyz.hashdog.gen.bean.GenTableColumn>
*/
List<GenTableColumn> selectDbTableColumnsByName(String schemaName,String tableName);
}
GenTableServiceImpl.java
package xyz.hashdog.gen.service.impl;
import xyz.hashdog.gen.bean.GenTable;
import xyz.hashdog.gen.dao.GenTableColumnMapper;
import xyz.hashdog.gen.dao.GenTableMapper;
import xyz.hashdog.gen.service.IGenTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*表信息服务层实现
* @author: th
* @date: 2020/1/14 18:03
*/
@Service
public class GenTableServiceImpl implements IGenTableService
{
@Autowired
private GenTableMapper genTableMapper;
@Autowired
private GenTableColumnMapper genTableColumnMapper;
@Override
public GenTable selectDbTableByST(String schemaName, String tableName) {
return genTableMapper.selectDbTableByST( schemaName, tableName);
}
}
GenTableColumnServiceImpl.java
package xyz.hashdog.gen.service.impl;
import xyz.hashdog.gen.bean.GenTableColumn;
import xyz.hashdog.gen.dao.GenTableColumnMapper;
import xyz.hashdog.gen.service.IGenTableColumnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
*表字段信息服务层实现
* @author: th
* @date: 2020/1/14 18:03
*/
@Service
public class GenTableColumnServiceImpl implements IGenTableColumnService
{
@Autowired
private GenTableColumnMapper genTableColumnMapper;
@Override
public List<GenTableColumn> selectDbTableColumnsByName(String schemaName, String tableName) {
return genTableColumnMapper.selectDbTableColumnsByName(schemaName,tableName);
}
}
5.dao
GenTableMapper.java
package xyz.hashdog.gen.dao;
import xyz.hashdog.gen.bean.GenTable;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
*表信息持久层
* @author: th
* @date: 2020/1/14 18:04
*/
public interface GenTableMapper
{
/**
*根据模式名与表名获取表信息
* @author: th
* @date: 2020/1/13 14:48
* @param schemaName
* @param tableName
* @return: gen.bean.GenTable
*/
GenTable selectDbTableByST(@Param("schemaName") String schemaName, @Param("tableName")String tableName);
}
GenTableColumnMapper.java
package xyz.hashdog.gen.dao;
import xyz.hashdog.gen.bean.GenTableColumn;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
*表字段信息持久层
* @author: th
* @date: 2020/1/14 18:04
*/
public interface GenTableColumnMapper
{
/**
*根据模式名与表名查询表字段信息
* @author: th
* @date: 2020/1/14 10:29
* @param schemaName
* @param tableName
* @return: java.util.List<xyz.hashdog.gen.bean.GenTableColumn>
*/
List<GenTableColumn> selectDbTableColumnsByName(@Param("schemaName") String schemaName, @Param("tableName")String tableName);
}
6.mapper
GenTableMapper.xml
<?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="xyz.hashdog.gen.dao.GenTableMapper">
<!--根据模式名与表名获取表信息-->
<select id="selectDbTableByST" resultType="xyz.hashdog.gen.bean.GenTable">
SELECT
table_name,
comments AS tableComment
FROM
DBA_TAB_COMMENTS
WHERE
Table_Name = #{tableName}
AND OWNER = #{schemaName}
</select>
</mapper>
GenTableColumnMapper.xml
<?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="xyz.hashdog.gen.dao.GenTableColumnMapper">
<!--根据模式名与表名查询表字段信息-->
<select id="selectDbTableColumnsByName" resultType="xyz.hashdog.gen.bean.GenTableColumn">
SELECT
a.column_name AS columnName,
CONCAT(a.data_type,'(',a.data_length,')') AS columnType,
case when a.nullable='N' then 1 ELSE 0 end as isRequired,
a.column_id as sort,
b.comments AS columnComment,
case when d.constraint_type='P' then 1 else 0 end as isPk
FROM
dba_tab_columns a
left join dba_col_comments b on a.owner=b.owner and a.table_name=b.table_name and a.column_name=b.column_name
left join (select a.owner,a.table_name,a.column_name,b.constraint_type from dba_cons_columns a
inner join dba_constraints b on a.constraint_name = b.constraint_name) d on a.owner=d.owner and a.table_name=d.table_name and a.column_name=d.column_name
where a.Table_Name=#{tableName} and a.owner=#{schemaName}
</select>
</mapper>
7.模板文件
bean.java.vm
package ${packageName}.bean;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
#foreach ($import in $importList)
import ${import};
#end
/**
* ${functionName}对象 ${tableName}
*
* @author ${author}
* @date ${datetime}
*/
public class ${ClassName}
{
private static final long serialVersionUID = 1L;
#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
/** $column.columnComment */
#if($column.list)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#end
private $column.javaType $column.javaField;
#end
#end
#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
#if($column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
public void set${AttrName}($column.javaType $column.javaField)
{
this.$column.javaField = $column.javaField;
}
public $column.javaType get${AttrName}()
{
return $column.javaField;
}
#end
#end
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
#foreach ($column in $columns)
#if($column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
.append("${column.javaField}", get${AttrName}())
#end
.toString();
}
}
controller.java.vm
package ${packageName}.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ieslab.iocp.base.Result;
import ${packageName}.bean.${ClassName};
import ${packageName}.service.I${ClassName}Service;
/**
* ${functionName}Controller
*
* @author ${author}
* @date ${datetime}
*/
@Controller
@RequestMapping("/${moduleName}/${businessName}")
public class ${ClassName}Controller
{
@Autowired
private I${ClassName}Service ${className}ServiceImpl;
/**
* 新增保存${functionName}
*/
@RequestMapping("/add")
@ResponseBody
public Result addSave(${ClassName} ${className})
{
return Result.success(${className}ServiceImpl.insert${ClassName}(${className}));
}
/**
* 修改保存${functionName}
*/
@RequestMapping("/edit")
@ResponseBody
public Result editSave(${ClassName} ${className})
{
return Result.success(${className}ServiceImpl.update${ClassName}(${className}));
}
/**
* 删除${functionName}
*/
@RequestMapping( "/remove")
@ResponseBody
public Result remove(String ids)
{
return Result.success(${className}ServiceImpl.delete${ClassName}ByIds(ids));
}
}
dao.java.vm
package ${packageName}.dao;
import ${packageName}.bean.${ClassName};
import java.util.List;
/**
* ${functionName}Mapper接口
*
* @author ${author}
* @date ${datetime}
*/
public interface ${ClassName}Dao
{
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int insert${ClassName}(${ClassName} ${className});
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int update${ClassName}(${ClassName} ${className});
/**
* 批量删除${functionName}
*
* @param ${pkColumn.javaField}s 需要删除的数据ID
* @return 结果
*/
public int delete${ClassName}ByIds(String[] ${pkColumn.javaField}s);
}
service.java.vm
package ${packageName}.service;
import ${packageName}.bean.${ClassName};
import java.util.List;
/**
* ${functionName}Service接口
*
* @author ${author}
* @date ${datetime}
*/
public interface I${ClassName}Service
{
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int insert${ClassName}(${ClassName} ${className});
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int update${ClassName}(${ClassName} ${className});
/**
* 批量删除${functionName}
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int delete${ClassName}ByIds(String ids);
}
serviceImpl.java.vm
package ${packageName}.service.impl;
import java.util.List;
#foreach ($column in $columns)
#if($column.javaField == 'createTime' || $column.javaField == 'updateTime')
import com.ruoyi.common.utils.DateUtils;
#break
#end
#end
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ${packageName}.dao.${ClassName}Dao;
import ${packageName}.bean.${ClassName};
import ${packageName}.service.I${ClassName}Service;
/**
* ${functionName}Service业务层处理
*
* @author ${author}
* @date ${datetime}
*/
@Service
public class ${ClassName}ServiceImpl implements I${ClassName}Service
{
@Autowired
private ${ClassName}Dao ${className}Mapper;
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
@Override
public int insert${ClassName}(${ClassName} ${className})
{
#foreach ($column in $columns)
#if($column.javaField == 'createTime')
${className}.setCreateTime(DateUtils.getNowDate());
#end
#end
return ${className}Mapper.insert${ClassName}(${className});
}
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
@Override
public int update${ClassName}(${ClassName} ${className})
{
#foreach ($column in $columns)
#if($column.javaField == 'updateTime')
${className}.setUpdateTime(DateUtils.getNowDate());
#end
#end
return ${className}Mapper.update${ClassName}(${className});
}
/**
* 删除${functionName}对象
*
* @param ids 需要删除的数据ID
* @return 结果
*/
@Override
public int delete${ClassName}ByIds(String ids)
{
return ${className}Mapper.delete${ClassName}ByIds(ids.split(","));
}
}
mapper.xml.vm
<?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="${packageName}.dao.${ClassName}Dao">
<resultMap type="${packageName}.bean.${ClassName}" id="${ClassName}Result">
#foreach ($column in $columns)
<result property="${column.javaField}" column="${column.columnName}" />
#end
</resultMap>
<insert id="insert${ClassName}" parameterType="${packageName}.bean.${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end>
insert into ${tableName}
<trim prefix="(" suffix=")" suffixOverrides=",">
#foreach($column in $columns)
#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment)
<if test="$column.javaField != null #if($column.javaType == 'String' ) and $column.javaField != ''#end">$column.columnName,</if>
#end
#end
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
#foreach($column in $columns)
#if($column.columnName != $pkColumn.columnName || !$pkColumn.increment)
<if test="$column.javaField != null #if($column.javaType == 'String' ) and $column.javaField != ''#end">#{$column.javaField},</if>
#end
#end
</trim>
</insert>
<update id="update${ClassName}" parameterType="${packageName}.bean.${ClassName}">
update ${tableName}
<trim prefix="SET" suffixOverrides=",">
#foreach($column in $columns)
#if($column.columnName != $pkColumn.columnName)
<if test="$column.javaField != null #if($column.javaType == 'String' ) and $column.javaField != ''#end">$column.columnName = #{$column.javaField},</if>
#end
#end
</trim>
where ${pkColumn.columnName} = #{${pkColumn.javaField}}
</update>
<delete id="delete${ClassName}ByIds" parameterType="String">
delete from ${tableName} where ${pkColumn.columnName} in
<foreach item="${pkColumn.javaField}" collection="array" open="(" separator="," close=")">
#{${pkColumn.javaField}}
</foreach>
</delete>
</mapper>
8.junit启动类
package test.gen;
import xyz.hashdog.gen.bean.GenTable;
import xyz.hashdog.gen.bean.GenTableColumn;
import xyz.hashdog.gen.constants.GenConstants;
import xyz.hashdog.gen.service.IGenTableColumnService;
import xyz.hashdog.gen.service.IGenTableService;
import xyz.hashdog.gen.util.GenUtils;
import xyz.hashdog.gen.util.VelocityInitializer;
import xyz.hashdog.gen.util.VelocityUtils;
import xyz.hashdog.util.StringUtils;
import org.apache.commons.lang.reflect.FieldUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.texen.util.FileUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.List;
/**
*代码生成
* @author: th
* @date: 2020/1/14 18:18
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/springContext.xml"})
public class TestGen {
@Autowired
private IGenTableService genTableServiceImpl;
@Autowired
private IGenTableColumnService genTableColumnServiceImpl;
/**
* 后台代码生成(bean,controller,service,serviceImpl,dao,mapper)
* 生成到指定包路径下(该包路径不存在则自动创建,如果该路径下已有同名文件,会被替换)
*/
@Test
public void create(){
//表名(必填)
String tableName="user";
//模式名(必填)
String schemaName="system";
//生成包路径(必填)
String packageName = "xyz.hashdog.system";
//作者,默认为当前系统用户
String author = "";
//是否去除表前缀,默认false不去除
boolean isRemovePre=false;
run(tableName,schemaName,packageName,author,isRemovePre);
}
public void run (String tableName, String schemaName,String packageName,String author,boolean isRemovePre){
//获取表信息
GenTable table = genTableServiceImpl.selectDbTableByST(schemaName,tableName);
table.setPackageName(packageName);
table.setModuleName(GenUtils.getModuleName(packageName));
table.setBusinessName(GenUtils.getBusinessName(table.getTableName()));
table.setFunctionName(table.getTableComment());
table.setFunctionAuthor(author);
table.setClassName(GenUtils.convertClassName(table.getTableName(),isRemovePre));
//获取字段信息
List<GenTableColumn> genTableColumns = genTableColumnServiceImpl.selectDbTableColumnsByName(schemaName,tableName);
for (GenTableColumn column : genTableColumns)
{
GenUtils.initColumnField(column, table);
}
GenUtils.setPkColumn(table, genTableColumns);
table.setColumns(genTableColumns);
//初始化模板引擎
VelocityInitializer.initVelocity();
VelocityContext context = VelocityUtils.prepareContext(table);
// 获取模板列表
List<String> templates = VelocityUtils.getTemplateList();
for (String template : templates)
{
// 渲染模板
Template tpl = Velocity.getTemplate(template, GenConstants.UTF8);
PrintWriter writer = null;
try
{
//获取写入路径,写入
String fileName = VelocityUtils.getFileName(template, table);
GenUtils.mkdir(fileName);
writer = new PrintWriter(fileName);
tpl.merge(context, writer);
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
writer.close();
}
}
}
}
5.代码结构
单独写了一个gen模块,专用于代码生成
模板文件放在resources下
junit代码位置
用junit可以直接运行进行代码生成,前提环境是spring+mybatis,如果与需求,可以写个controller,通过页面用户操作进行代码生成,可以自由扩展