一个java代码生成器的简单实现

一个java代码生成器的简单实现最近,一直跟着公司技术牛人在搞大数据相关的东西,主要涉及的是环境搭建,同时也了解下整个hadoop生态系统相关的东西,真是让我大开眼界,这个在之后的博文中再来与大家分享。今天,笔者给大家介绍一个代码生成器,这个是笔者的主管写的,写的确实不错,主要是基于公司的jqueryeasyUI+springMVC+myBatis这套框架写的,可以根据一个数据库表生成model、mapper.xml

大家好,又见面了,我是你们的朋友全栈君。

最近,一直跟着公司技术牛人在搞大数据相关的东西,主要涉及的是环境搭建,同时也了解下整个hadoop生态系统相关的东西,真是让我大开眼界,这个在之后的博文中再来与大家分享。
今天,笔者给大家介绍一个代码生成器,这个是笔者的主管写的,写的确实不错,主要是基于公司的jquery easyUI + springMVC + myBatis这套框架写的,可以根据一个数据库表生成model、mapper.xml、dao接口以及service、controller、jsp页面等相关的东西,包含增删改查等操作,节省开发时间。然后,笔者在此代码生成器上修改了几个bug,同时兼容了一下mysql。
这个代码生成器工具使用的核心是freemarker,一个用Java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。
下面,笔者开始进行核心代码的介绍。
首先,我们必须指定哪张表,然后通过jdbc获取这个表的信息以及表字段相关的信息。
这里,将所有的配置写入config.properties:

###数据库表与model的映射
taskhistory=TaskHistory

###数据源配
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://172.31.26.156:3306/test
username=root
password=root
db=mysql

###每个用户对应一个同名的schema,注意配置,不然会搜索每个schema
schemaPattern=root
tableNamePattern=%taskhistory
sEQNamePattern=%TM0101_SE

###model包名
modelPackage=com.qiyongkang.sys.model
###model保存文件路径
modelSavePath=D:\\develop\\model\\

###mapper接口包名
mapperPackage=com.qiyongkang.sys.dao
###mapper接口保存文件路径
mapperSavePath=D:\\develop\\dao\\

###mapper.xml的文件路径
mapperXmlSavePath=D:\\develop\\mapping\\oracle\\

###service的包名
servicePackage=com.qiyongkang.sys.service.impl

###service的保存文件路径
serviceSavePath=D:\\develop\\service\\impl\\

###service interface的包名
serviceInterfacePackage=com.qiyongkang.sys.service
###service interface的保存文件路径
serviceInterfaceSavePath=D:\\develop\\service\\

###control包名
controllerPackage=com.qiyongkang.sys.ctrl

###control文件路径
controllerSavePath=D:\\develop\\ctrl\\

###junit包名
junitPackage=com.qiyongkang.test.system.service

###junit文件路径
junitSavePath=D:\\develop\\test\\java\\com\\qiyongkang\\test\\system\\service\\

###js文件路径
jsHomeSavePath=D:\\develop\\WebContent\\js\\modules\\system\\

###jsp文件路径
jspHomeSavePath=D:\\develop\\WebContent\\WEB-INF\\views\\system\\

###是否生成model
modelFlag=true

###是否生成mapper
mapperFlag=true

###是否生成mapper.xml
mapperXmlFlag=true

###是否生成service
serviceFlag=true

###是否生成service接口
serviceImplFlag=true

###是否生成control
controlFlag=true

###是否生成junit
junitFlag=false

###是否生成easyUIJs
easyUIJsFlag=false

###是否生成easyUIJsp
easyUIJspFlag=false

###是否生成extJs
extJsFlag=false

###备份文件路径
fileBakPath=D:\\develop\\bakFile\\

##项目名称
projectName=qyk_testSpringMVC

然后,再来看看获取数据库信息相关的代码:

package com.codegenerator.framework.service.impl;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import com.codegenerator.core.utils.ConfigUtil;
import com.codegenerator.framework.model.ColumnInfo;
import com.codegenerator.framework.model.ConnectConfig;
import com.codegenerator.framework.model.ModelInfo;
import com.codegenerator.framework.model.TableInfo;
import com.codegenerator.framework.service.DataBaseService;
public class DataBaseServiceImpl implements DataBaseService {
private static Logger logger = LogManager.getLogger(DataBaseServiceImpl.class);
@Override
public List<ModelInfo> loadModelInfo(ConnectConfig connectConfig) {
ModelInfo.tableNamePex = connectConfig.getTableNamePattern();
logger.info("表前缀:{}", ModelInfo.tableNamePex);
ModelInfo.sEQNamePex = connectConfig.getsEQNamePattern();
logger.info("序列前缀:{}", ModelInfo.sEQNamePex);
List<ModelInfo> mList = new ArrayList<ModelInfo>();
DriverManagerDataSource dataSource = new DriverManagerDataSource();
logger.info("驱动类:{}", connectConfig.getDriverClassName());
dataSource.setDriverClassName(connectConfig.getDriverClassName());
logger.info("url:{}", connectConfig.getUrl());
dataSource.setUrl(connectConfig.getUrl());
logger.info("userName:{}", connectConfig.getUsername());
dataSource.setUsername(connectConfig.getUsername());
logger.info("password:{}", connectConfig.getPassword());
dataSource.setPassword(connectConfig.getPassword());
Properties pro = connectConfig.getConnectionPros();
logger.info("设置连接属性:{}", pro.stringPropertyNames());
dataSource.setConnectionProperties(pro);
Connection conn = null;
//表查询结果集
ResultSet tableRS = null;
try {
conn = dataSource.getConnection();
DatabaseMetaData dbMetaData = conn.getMetaData();
logger.info("Catalog:{}", connectConfig.getCatalog());
logger.info("SchemaPattern:{}", connectConfig.getSchemaPattern());
logger.info("TableNamePattern:{}", connectConfig.getTableNamePattern());
logger.info("Types:{}", Arrays.toString(connectConfig.getTypes()));
//获取表的结果集
tableRS = dbMetaData.getTables(connectConfig.getCatalog(), connectConfig.getSchemaPattern(), connectConfig.getTableNamePattern(),
connectConfig.getTypes());
while (tableRS.next()) {
String tableName = tableRS.getString("TABLE_NAME");
logger.info("tableName:{}", tableName);
if (tableName.indexOf("$") == -1 && !connectConfig.getExclusionMap().containsKey(tableName)) {
if (ConfigUtil.getConfig(tableName) == null) {
continue;
}
ModelInfo modelInfo = new ModelInfo();
TableInfo tableInfo = new TableInfo();
tableInfo.setName(tableName);
logger.info("表{}的注释:{}", tableName, tableRS.getString("REMARKS"));
tableInfo.setRemark(tableRS.getString("REMARKS"));
logger.info("表{}的类型:{}", tableName, tableRS.getString("TABLE_TYPE"));
tableInfo.setType(tableRS.getString("TABLE_TYPE"));
//获取列的结果集
ResultSet columnRS = dbMetaData.getColumns(null, connectConfig.getSchemaPattern(), tableName, "%");
List<ColumnInfo> ciList = new ArrayList<ColumnInfo>();
while (columnRS.next()) {
String columnName = columnRS.getString("COLUMN_NAME");
logger.info("字段名称:{}", columnName);
String columnType = columnRS.getString("TYPE_NAME").toUpperCase();
logger.info("字段类型:{}", columnType);
String columnRemark = columnRS.getString("REMARKS");
logger.info("字段注释:{}", columnRemark);
int len = columnRS.getInt("COLUMN_SIZE");
logger.info("字段长度:{}", len);
int precision = columnRS.getInt("DECIMAL_DIGITS");
logger.info("字段类型精度:{}", precision);
if (columnName == null || "".equals(columnName)) {
continue;
}
ColumnInfo ci = new ColumnInfo();
ci.setName(columnName);
ci.setType(columnType);
ci.setRemark(columnRemark);
ci.setLen(len);
ci.setPrecision(precision);
ciList.add(ci);
}
tableInfo.setColumnList(ciList);
modelInfo.setmTable(tableInfo, connectConfig.getIdMap());
mList.add(modelInfo);
columnRS.close();
}
}
tableRS.close();
} catch (Exception e) {
e.printStackTrace();
logger.error("获取表、字段相关信息异常。。", e);
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return mList;
}
}

这里,是将获取到的信息用ModelInfo.java这个实体封装:

package com.codegenerator.framework.model;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import com.codegenerator.core.utils.ConfigUtil;
import com.codegenerator.core.utils.StringUtil;
import com.codegenerator.framework.flt.service.ModelFtlService;
import com.codegenerator.framework.service.TypeHandler;
public class ModelInfo implements ModelFtlService { 

private String className;
private String packageName;
private String savePath;
private TableInfo mTable;
private String fileName;
private String remark;
public static String tableNamePex;
public static String sEQNamePex;
private String idCol;
private String idPro;
private String idColType;
private String idProType;
private String[] cols;
private String[] pros;
private String[] jdbcTypes;
private String[] javaTypes;
private Map<String, TypeHandler> dtoProMap = new HashMap<String, TypeHandler>();
private Map<String, TypeHandler> modelProMap = new HashMap<String, TypeHandler>();
private String name;
private String sEQName;
private String dtoFileName;
public Map<String, TypeHandler> getDtoProMap() {
return dtoProMap;
}
public void setDtoProMap(Map<String, TypeHandler> dtoProMap) {
this.dtoProMap = dtoProMap;
}
public String getDtoFileName() {
return dtoFileName;
}
public void setDtoFileName(String dtoFileName) {
this.dtoFileName = dtoFileName;
}
public String[] getJdbcTypes() {
return jdbcTypes;
}
public void setJdbcTypes(String[] jdbcTypes) {
this.jdbcTypes = jdbcTypes;
}
public String[] getJavaTypes() {
return javaTypes;
}
public void setJavaTypes(String[] javaTypes) {
this.javaTypes = javaTypes;
}
public static String getsEQNamePex() {
return sEQNamePex;
}
public static void setsEQNamePex(String sEQNamePex) {
ModelInfo.sEQNamePex = sEQNamePex;
}
public String getsEQName() {
return sEQName;
}
public void setsEQName(String sEQName) {
this.sEQName = sEQName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getCols() {
return cols;
}
public void setCols(String[] cols) {
this.cols = cols;
}
public String[] getPros() {
return pros;
}
public void setPros(String[] pros) {
this.pros = pros;
}
public void setmTable(TableInfo mTable) {
this.mTable = mTable;
}
public static String getTableNamePex() {
return tableNamePex;
}
public static void setTableNamePex(String tableNamePex) {
ModelInfo.tableNamePex = tableNamePex;
}
public String getIdColType() {
return idColType;
}
public void setIdColType(String idColType) {
this.idColType = idColType;
}
public String getIdProType() {
return idProType;
}
public void setIdProType(String idProType) {
this.idProType = idProType;
}
public void setIdCol(String idCol) {
this.idCol = idCol;
}
public void setIdPro(String idPro) {
this.idPro = idPro;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public TableInfo getmTable() {
return mTable;
}
public void setmTable(TableInfo mTable, Map<String, String> idMap) {
String tableName = ConfigUtil.getConfig(mTable.getName());
if (tableName == null || "".equals(tableName)) {
return;
}
this.mTable = mTable;
if (this.className == null) {
setClassName(StringUtil.getClassName(mTable.getName(), tableNamePex));
}
if (this.sEQName == null) {
setsEQName(StringUtil.getSEQName(mTable.getName(), tableNamePex, sEQNamePex));
}
if (this.fileName == null) {
setFileName(getClassName() + ".java");
}
if (this.dtoFileName == null) {
setDtoFileName(getClassName() + "Dto.java");
}
if (this.remark == null) {
setRemark(mTable.getRemark());
}
if (this.name == null) {
setName(StringUtil.getClassAlias(mTable.getName(), tableNamePex));
}
ColumnInfo col = null;
boolean hasConfig = idMap.containsKey(mTable.getName());
List<ColumnInfo> colList = mTable.getColumnList();
int len = colList.size() - 1;
cols = new String[len];
pros = new String[len];
jdbcTypes = new String[len];
javaTypes = new String[len];
len = 0;
for (ColumnInfo ci : colList) {
if ((hasConfig && idMap.get(mTable.getName()).equalsIgnoreCase(ci.getName()))
|| ci.getName().equalsIgnoreCase("id")) {
//主键
col = ci;
} else {
if (ci.getName() != null) {
cols[len] = ci.getName();
pros[len] = ci.getPropertyInfo().getName();
// jdbcTypes[len] = ci.getPropertyInfo().getJdbcType();
javaTypes[len] = ci.getPropertyInfo().getClassName();
// if ("TIMESTAMP".equalsIgnoreCase(jdbcTypes[len])) { 

// TypeHandler mHandler = new DateHandler(ci.getPropertyInfo(), ci);
// dtoProMap.put(cols[len], mHandler);
// modelProMap.put(pros[len], mHandler);
// }
len++;
}
}
}
if (col != null) {
setIdCol(col.getName());
setIdPro(col.getPropertyInfo().getName());
setIdColType(col.getType());
setIdProType(col.getPropertyInfo().getClassName());
}
}
public void setClassName(String className) {
this.className = className;
}
@Override
public String getPackageStr() {
return "package " + getPackageName() + ";";
}
@Override
public String getImportStr() {
StringBuffer sb = new StringBuffer("\r\n");
Map<String, String> imMap = new HashMap<String, String>();
List<ColumnInfo> cifs = mTable.getColumnList();
for (ColumnInfo cif : cifs) {
PropertyInfo pi = cif.getPropertyInfo();
String imStr = "import " + pi.getPackageName() + "." + pi.getClassName() + ";\r\n";
if (pi.getPackageName() != null && !imMap.containsKey(imStr)) {
sb.append(imStr);
imMap.put(imStr, imStr);
}
}
String imStr = "import java.util.Date;\r\n";
if (modelProMap.size() > 0 && !imMap.containsKey(imStr)) {
sb.append(imStr);
imMap.put(imStr, imStr);
}
return sb.length() > 0 ? sb.toString() : null;
}
@SuppressWarnings("rawtypes")
@Override
public String getPropertiesStr() {
StringBuffer sb = new StringBuffer("\r\n");
List<ColumnInfo> cifs = mTable.getColumnList();
for (ColumnInfo cif : cifs) {
PropertyInfo pi = cif.getPropertyInfo();
sb.append(" /**\r\n");
sb.append(" *" + pi.getRemark() + "\r\n");
sb.append(" */\r\n");
sb.append(" private " + pi.getClassName() + " " + pi.getName() + ";\r\n");
}
Set set = modelProMap.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
String key = (String) it.next();
sb.append(" /**\r\n");
sb.append(" *查询起始时间\r\n");
sb.append(" */\r\n");
sb.append(" private Date " + key + "Before;\r\n");
sb.append(" /**\r\n");
sb.append(" *查询截止时间\r\n");
sb.append(" */\r\n");
sb.append(" private Date " + key + "After;\r\n");
}
return sb.length() > 0 ? sb.toString() : null;
}
@SuppressWarnings("rawtypes")
@Override
public String getMethodStr() {
StringBuffer sb = new StringBuffer("\r\n");
List<ColumnInfo> cifs = mTable.getColumnList();
for (ColumnInfo cif : cifs) {
PropertyInfo pi = cif.getPropertyInfo();
sb.append("\r\n /** \r\n *设置 :" + pi.getRemark() + "\r\n */\r\n");
sb.append(" public void set" + StringUtils.capitalize(pi.getName()) + "(" + pi.getClassName() + " "
+ pi.getName() + ") {\r\n");
sb.append(" this." + pi.getName() + " = " + pi.getName() + ";\r\n");
sb.append(" }\r\n");
sb.append("\r\n /** \r\n *获取 :" + pi.getRemark() + "\r\n */\r\n");
if ("boolean".equalsIgnoreCase(pi.getClassName())) {
sb.append(" public " + pi.getClassName() + " is" + StringUtils.capitalize(pi.getName()) + "() {\r\n");
} else {
sb.append(" public " + pi.getClassName() + " get" + StringUtils.capitalize(pi.getName()) + "() {\r\n");
}
sb.append(" return this." + pi.getName() + ";\r\n");
sb.append(" }\r\n");
}
Set set = modelProMap.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
String key = (String) it.next();
getMetStr(key, sb);
}
return sb.length() > 0 ? sb.toString() : null;
}
@Override
public String getClassName() {
return this.className;
}
@Override
public String getIdCol() {
return this.idCol;
}
@Override
public String getIdPro() {
return this.idPro;
}
@Override
public String getDtoClassBody() {
StringBuilder proStr = new StringBuilder();
StringBuilder metStr = new StringBuilder();
for (Entry<String, TypeHandler> entry : dtoProMap.entrySet()) {
proStr.append(entry.getValue().getProStr());
metStr.append(entry.getValue().getMetStr());
}
return proStr.toString() + "\r\n" + metStr.toString();
}
public String getDtoSavePath() {
return getSavePath() + "Dto\\";
}
public String getAuthorStr() {
return System.getProperty("user.name");
}
public String getMetStr(String key, StringBuffer sb) {
sb.append("\r\n /** \r\n *获取 :" + key + "Before\r\n */\r\n");
sb.append(" public Date get" + StringUtils.capitalize(key) + "Before() {\r\n");
sb.append(" return this." + key + "Before;\r\n");
sb.append(" }\r\n");
sb.append("\r\n /** \r\n *设置 :" + key + "Before\r\n */\r\n");
sb.append(" public void set" + StringUtils.capitalize(key) + "Before(Date " + key + "Before) {\r\n");
sb.append(" this." + key + "Before = " + key + "Before;\r\n");
sb.append(" }\r\n\r\n");
sb.append("\r\n /** \r\n *获取 :" + key + "After\r\n */\r\n");
sb.append(" public Date get" + StringUtils.capitalize(key) + "After() {\r\n");
sb.append(" return this." + key + "After;\r\n");
sb.append(" }\r\n");
sb.append("\r\n /** \r\n *设置 :" + key + "After\r\n */\r\n");
sb.append(" public void set" + StringUtils.capitalize(key) + "After(Date " + key + "After) {\r\n");
sb.append(" this." + key + "After = " + key + "After;\r\n");
sb.append(" }\r\n");
return sb.toString();
}
@Override
public String toString() {
return "ModelInfo [className=" + className + ", packageName=" + packageName + ", savePath=" + savePath
+ ", mTable=" + mTable + ", fileName=" + fileName + ", remark=" + remark + ", idCol=" + idCol
+ ", idPro=" + idPro + ", idColType=" + idColType + ", idProType=" + idProType + ", cols="
+ Arrays.toString(cols) + ", pros=" + Arrays.toString(pros) + ", jdbcTypes="
+ Arrays.toString(jdbcTypes) + ", javaTypes=" + Arrays.toString(javaTypes) + ", dtoProMap=" + dtoProMap
+ ", modelProMap=" + modelProMap + ", name=" + name + ", sEQName=" + sEQName + ", dtoFileName="
+ dtoFileName + "]";
}
}

然后,还有一点笔者需要说明一下,就是代码生成器 jdbc类型和数据库类型的对应。
我们可以统一起来,像什么char可以用varchar或者int代替,bool可以用int代替,浮点型可以用varchar代替
oracle:
NUMBER -> Long
LONG -> Long
VARCHAR2->String
Date->Date java.uti.Date

mysql:
bigint -> Long
int -> Long
varchar -> String
DateTime -> Date java.uti.Date

这样便统一起来了。
接下来,获取到数据库表和字段的信息后,就要生成代码了,这里笔者就介绍一下如何生成Mapper.xml这个文件的,因为这个代码生成器的东西比较多,无法一一列举,但是核心思想都是一样的。
首先,必须准备一个模板,也是就是说,你想生成啥,就得准备一个相应的模板。
mapperXml.ftl.mysql:

<?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="${m.packageName}.${m.className}">
<resultMap type="${m.resMapClsName}" id="${m.resBeaName}ResultMap">
${m.resMapStr}
</resultMap>
<insert id="addEntity" parameterType="${m.resMapClsName}" useGeneratedKeys="true" keyProperty="${m.idPro}">
INSERT INTO ${m.tableName}
(${m.insertColsStr})
VALUES
(${m.insertColsVal})
</insert>
<delete id="delEntity" parameterType="long">
delete from ${m.tableName}
<where>
${m.idCol} = ${m.escape}{${m.idPro}}
</where>
</delete>
<delete id="delBatchEntity" parameterType="String">
delete from ${m.tableName}
<where>
<if test="ids != null">
${m.idCol} in 
(
<foreach collection="ids" index="index" separator="," item="item" >
${m.escape}{item}
</foreach>
)
</if>
</where>
</delete>
<update id="editEntity" parameterType="${m.resMapClsName}">
update ${m.tableName}
<set>
${m.editSetStr}
</set>
where ${m.idCol} = ${m.escape}{${m.idPro}}
</update>
<select id="count" resultType="long" parameterType="${m.resMapClsName}">
SELECT count(1) from ${m.tableName}
<where>
${m.countWhereStr}
</where>
</select>
<select id="list" resultMap="${m.resBeaName}ResultMap" parameterType="${m.resMapClsName}">
SELECT 
${m.listColsStr}
FROM
${m.tableName} t
<where> 
${m.listWhereStr}
</where>
<if test="sort !=null and sort !=''">
ORDER BY ${m.escapeNew}{sort} ${m.escapeNew}{order}
</if>
</select>
<select id="getEntityById" parameterType="long" resultType="${m.resMapClsName}">
SELECT 
${m.listColsStr}
FROM ${m.tableName} t
WHERE ${m.idCol} = ${m.escape}{${m.idPro}}
</select>
</mapper>

然后, 使freemarkjar便 中的m代表一个传入进来的对象,m.后边的东西就是此对象的属性或者方法。
下面,我们来看看相应的代码:

package com.codegenerator.framework.model;
import com.codegenerator.core.utils.ConfigUtil;
import com.codegenerator.framework.flt.service.MapperFtlService;
public class MapperInfo implements MapperFtlService { 

private String className;
private String packageName;
private String savePath;
private String xmlSavePath;
private String fileName;
private String remark;
private ModelInfo modelInfo;
public static MapperInfo loadFrom(ModelInfo modelInfo) {
MapperInfo mapInfo = new MapperInfo();
mapInfo.setSavePath(ConfigUtil.getConfig("mapperSavePath"));
mapInfo.setXmlSavePath(ConfigUtil.getConfig("mapperXmlSavePath"));
mapInfo.setPackageName(ConfigUtil.getConfig("mapperPackage"));
mapInfo.setModelInfo(modelInfo);
return mapInfo;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public ModelInfo getModelInfo() {
return modelInfo;
}
@Override
public String getXmlFileName() {
return getFileName().replace("Mapper.java", "Mapper.xml");
}
@Override
public String getPackageStr() {
return "package " + getPackageName() + ";";
}
// @Override
// public String getResMapStr() { 

// StringBuffer sb = new StringBuffer();
// sb.append("<id property=\""+getIdPro()+"\" column=\""+getIdCol()+"\"
// />\r\n");
// String[] cols = this.modelInfo.getCols();
// String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
// int len = cols.length;
// for(int i=0;i<len;i++){ 

// if(pros[i] !=null){ 

// sb.append(" <result property=\""+pros[i]+"\" column=\""+cols[i]+"\"
// />\r\n");
// }
// }
// return sb.toString();
// }
@Override
public String getResMapStr() {
StringBuffer sb = new StringBuffer();
sb.append("<id property=\"" + getIdPro() + "\" column=\"" + getIdPro() + "\" />\r\n");
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
if (pros[i] != null) {
sb.append(" <result property=\"" + pros[i] + "\" column=\"" + pros[i] + "\" />\r\n");
}
}
return sb.toString();
}
@Override
public String getTableName() {
return this.modelInfo.getmTable().getName();
}
@Override
public String getSeqName() {
return this.modelInfo.getsEQName();
}
@Override
public String getInsertColsStr() {
StringBuffer sb = new StringBuffer();
//判断数据库
String db = ConfigUtil.getConfig("db");
//mysql是不需要加主键
if ("oracle".equalsIgnoreCase(db)) {
sb.append(getIdCol());
}
String[] cols = this.modelInfo.getCols();
// String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
// String[] javaTypes = this.modelInfo.getJdbcTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
if (cols[i] != null) {
if (i == 0) {
sb.append(cols[i]);
} else {
sb.append("," + cols[i]);
}
}
}
return sb.toString();
}
@Override
public String getInsertColsVal() {
StringBuffer sb = new StringBuffer();
//判断数据库
String db = ConfigUtil.getConfig("db");
//mysql是不需要加主键
if ("oracle".equalsIgnoreCase(db)) {
sb.append("#{" + this.modelInfo.getIdPro() + "}");
}
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
// String[] javaTypes = this.modelInfo.getJdbcTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
if (pros[i] != null) {
if (i == 0) {
sb.append("#{" + pros[i] + "}");
} else {
sb.append("," + "#{" + pros[i] + "}");
}
}
}
return sb.toString();
}
@Override
public String getDelWhereStr() {
StringBuffer sb = new StringBuffer();
sb.append("<if test=\"" + getIdPro() + " != null\">");
sb.append(getIdCol() + " = #{" + getIdPro() + "}");
sb.append("</if>\r\n");
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
// String[] javaTypes = this.modelInfo.getJdbcTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
String handStr = null;
if (this.modelInfo.getDtoProMap().containsKey(cols[i])) {
handStr = this.modelInfo.getDtoProMap().get(cols[i]).getWhereStr(" ", null);
}
if (handStr != null) {
sb.append(handStr);
} else {
sb.append(" <if test=\"" + pros[i] + " != null\">");
sb.append(" AND " + cols[i] + " = #{" + pros[i] + "}");
sb.append("</if>\r\n");
}
}
return sb.toString();
}
@Override
public String getIdCol() {
return this.modelInfo.getIdCol();
}
@Override
public String getIdPro() {
return this.modelInfo.getIdPro();
}
@Override
public String getEscape() {
return "#";
}
@Override
public String getEscapeNew() {
return "$";
}
@Override
public String getEditSetStr() {
StringBuffer sb = new StringBuffer();
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
// String[] javaTypes = this.modelInfo.getJdbcTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
if (pros[i] != null) {
sb.append((i == 0 ? "" : " ") + "<if test=\"" + pros[i] + " != null\">" + cols[i] + "=#{"
+ pros[i] + "}" + (i == (len - 1) ? "" : ",") + "</if>\r\n");
}
}
return sb.toString();
}
@Override
public String getEditsSetStr() {
StringBuffer sb = new StringBuffer();
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
// String[] javaTypes = this.modelInfo.getJdbcTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
sb.append((i == 0 ? "" : " ") + "<if test=\"" + getMbeanName() + "." + pros[i] + " != null\">"
+ cols[i] + "=#{" + getMbeanName() + "." + pros[i] + "}" + (i == (len - 1) ? "" : ",")
+ "</if>\r\n");
}
return sb.toString();
}
@Override
public String getListWhereStr() {
StringBuffer sb = new StringBuffer();
sb.append("<if test=\"" + getIdPro() + " != null\">");
sb.append(getIdCol() + " = #{" + getIdPro() + "}");
sb.append("</if>\r\n");
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
String[] javaTypes = this.modelInfo.getJavaTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
if (cols[i] != null) {
String handStr = null;
if (this.modelInfo.getDtoProMap().containsKey(cols[i])) {
handStr = this.modelInfo.getDtoProMap().get(cols[i]).getWhereStr(" ", null);
}
if (handStr != null) {
sb.append(handStr);
} else {
//这里注意,如果属性类型为String类型,才需要加!=''
if (javaTypes[i].equalsIgnoreCase("String")) {
sb.append(" <if test=\"" + pros[i] + " != null and " + pros[i] + " !='' \">");
sb.append(" AND " + cols[i] + " = #{" + pros[i] + "}");
sb.append("</if>\r\n");
} else {
sb.append(" <if test=\"" + pros[i] + " != null\">");
sb.append(" AND " + cols[i] + " = #{" + pros[i] + "}");
sb.append("</if>\r\n");
}
}
}
}
sb.append(" <if test=\"isExport !=null and isExport =='true'\">\r\n");
sb.append(" AND t.COMMAND_FILE_ID IN (\r\n");
sb.append(
" <foreach collection=\"ids\" index=\"index\" separator=\",\" item=\"item\" >\r\n");
sb.append(" ${item}\r\n");
sb.append(" </foreach>\r\n");
sb.append(" )\r\n");
sb.append(" </if>\r\n");
return sb.toString();
}
@Override
public String getListColsStr() {
StringBuffer sb = new StringBuffer();
sb.append("t." + getIdCol() + " AS " + getIdPro() + ",\r\n");
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
// String[] javaTypes = this.modelInfo.getJdbcTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
if (cols[i] != null) {
sb.append(" t." + cols[i] + " AS " + pros[i] + (i == (len - 1) ? "" : ",\r\n"));
}
}
return sb.toString();
}
@Override
public String getCountWhereStr() {
StringBuffer sb = new StringBuffer();
sb.append("<if test=\"" + getIdPro() + " != null\">");
sb.append(getIdCol() + " = #{" + getIdPro() + "}");
sb.append("</if>\r\n");
String[] cols = this.modelInfo.getCols();
String[] pros = this.modelInfo.getPros();
// String[] jdbcTypes = this.modelInfo.getJdbcTypes();
String[] javaTypes = this.modelInfo.getJavaTypes();
int len = cols.length;
for (int i = 0; i < len; i++) {
if (cols[i] != null) {
String handStr = null;
if (this.modelInfo.getDtoProMap().containsKey(cols[i])) {
handStr = this.modelInfo.getDtoProMap().get(cols[i]).getWhereStr(" ", null);
}
if (handStr != null) {
sb.append(handStr);
} else {
//这里注意,如果属性类型为String类型,才需要加!=''
if (javaTypes[i].equalsIgnoreCase("String")) {
sb.append(" <if test=\"" + pros[i] + " != null and " + pros[i] + " !='' \">");
sb.append(" AND " + cols[i] + " = #{" + pros[i] + "}");
sb.append("</if>\r\n");
} else {
sb.append(" <if test=\"" + pros[i] + " != null\">");
sb.append(" AND " + cols[i] + " = #{" + pros[i] + "}");
sb.append("</if>\r\n");
}
}
}
}
return sb.toString();
}
@Override
public String getMclssName() {
return this.modelInfo.getClassName() + "Dto";
}
@Override
public String getMbeanName() {
return this.modelInfo.getClassName().toLowerCase();
}
@Override
public String getMclssFullName() {
return this.modelInfo.getPackageName() + ".dto." + this.modelInfo.getClassName() + "Dto";
}
@Override
public String getResMapClsName() {
return this.modelInfo.getPackageName() + "." + this.modelInfo.getClassName();
}
@Override
public String getResClsName() {
return this.modelInfo.getClassName();
}
@Override
public String getResBeaName() {
String resBeaName = this.modelInfo.getClassName();
resBeaName = resBeaName.toLowerCase().substring(0, 1) + resBeaName.substring(1);
return resBeaName;
}
@Override
public String getAuthorStr() {
return System.getProperty("user.name");
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public void setModelInfo(ModelInfo modelInfo) {
this.modelInfo = modelInfo;
if (this.className == null) {
setClassName(modelInfo.getClassName() + "Mapper");
}
if (this.fileName == null) {
setFileName(modelInfo.getFileName().replace(".java", "Mapper.java"));
}
if (this.remark == null) {
setRemark(modelInfo.getRemark());
}
}
public String getXmlSavePath() {
return xmlSavePath;
}
public void setXmlSavePath(String xmlSavePath) {
this.xmlSavePath = xmlSavePath;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
@Override
public String getImportStr() {
StringBuilder sb = new StringBuilder();
sb.append("import " + this.modelInfo.getPackageName() + "." + this.modelInfo.getClassName() + ";\r\n");
// sb.append("import
// "+this.modelInfo.getPackageName()+".dto."+this.modelInfo.getClassName()+"Dto;");
return sb.toString();
}
}

这个就是传入给m的对象,然后,再来看看是如何传的,首先我们必须把这个model的属性值根据获取的数据库表字段信息给设置好。

package com.codegenerator.framework.service.impl;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import com.codegenerator.core.utils.ConfigUtil;
import com.codegenerator.core.utils.FileUtil;
import com.codegenerator.core.utils.StringUtil;
import com.codegenerator.framework.model.MapperInfo;
import com.codegenerator.framework.service.MapperService;
public class MapperServiceImpl implements MapperService { 

private final static String MAPPER_FTL = "mapper.ftl";
private final static String MAPPER_XML_FTL = "mapperXml.ftl";
private final static String MAPPER_XML_FTL_MYSQL = "mapperXml.ftl.mysql";
@Override
public String createMapper(MapperInfo mapInfo) {
String temp = FileUtil.loadFtlStr(MAPPER_FTL, this.getClass());
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("m", mapInfo);
paramMap.put("time", Calendar.getInstance().getTime());
String modelStr = StringUtil.getProcessValue(paramMap, temp);
return modelStr;
}
@Override
public void saveMapper(MapperInfo mapInfo) {
FileUtil.writeFile(mapInfo.getSavePath(), mapInfo.getFileName(), createMapper(mapInfo));
}
@Override
public String createMapperXml(MapperInfo mapInfo) {
String temp = null;
//判断数据库
String db = ConfigUtil.getConfig("db");
if ("mysql".equalsIgnoreCase(db)) {
temp = FileUtil.loadFtlStr(MAPPER_XML_FTL_MYSQL, this.getClass());
} else {
temp = FileUtil.loadFtlStr(MAPPER_XML_FTL, this.getClass());
}
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("m", mapInfo);
paramMap.put("time", Calendar.getInstance().getTime());
String modelStr = StringUtil.getProcessValue(paramMap, temp);
return modelStr;
}
@Override
public void saveMapperXml(MapperInfo mapInfo) {
FileUtil.writeFile(mapInfo.getXmlSavePath(), mapInfo.getXmlFileName(), createMapperXml(mapInfo));
}
}

这里我们可以看到有一个put的方法把m放入到map中去了,这个m就是之前的那个对象。然后,我们再来看看StringUtil.getProcessValue(paramMap, temp)这个方法干了啥。

public static String getProcessValue(Map<String, Object> parms, String temp) {
try {
Template template = new Template("", new StringReader("<#escape x as (x)!>" + temp + "</#escape>"),
configuration);
StringWriter sw = new StringWriter();
template.process(parms, sw);
return sw.toString();
} catch (Exception ex) {
return null;
}
}

这个就是利用了freemarker的功能,它会自动将属性值以及方法返回的值替换到${m.*}对应的地方。
接下来,只要将此得到的String写入文件即可。
好了,核心的步骤就说到这儿啦。不同的项目框架,都要修改模板和相应的代码,所以此代码生成器也有它的局限性,但是核心的思想是一样的。
这个项目代码,我重新架构了一遍,放在github上了,https://github.com/zhoulychn/winit-mybatis-generator/tree/michael,有兴趣的小伙伴可以去了解下。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/131321.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号