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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qiyongkang520/article/details/50822010

最近,一直跟着公司技术牛人在搞大数据相关的东西,主要涉及的是环境搭建,同时也了解下整个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,有兴趣的小伙伴可以去了解下。

猜你喜欢

转载自blog.csdn.net/qiyongkang520/article/details/50822010