达梦数据库代码生成(基于velocity)

目录

基于velocity达梦数据库代码生成

1.前言

2.代码生成原理

3. 模板引擎

4.直接上代码

5.代码结构


基于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 &copy; 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特殊字符,如&nbsp;
		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,通过页面用户操作进行代码生成,可以自由扩展

发布了22 篇原创文章 · 获赞 21 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/corleone_4ever/article/details/103989169