针对jfinal的Generator进行扩展

主要实现代码如下:
package com.nlm.web.generator;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.sql.DataSource;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.generator.ColumnMeta;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import com.jfinal.plugin.activerecord.generator.TypeMapping;

public class MyMetaBuilder extends MetaBuilder {
	
	protected Set<String> includedTableNamePrefixes = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
	
	protected TypeMapping typeMapping = new TypeMapping();

	public MyMetaBuilder(DataSource dataSource) {
		super(dataSource);
	}
	
	public void addIncludedTableNamePrefixes(String... includedTableNamePrefixes) {
		if (includedTableNamePrefixes != null) {
			for (String tableNamePrefix : includedTableNamePrefixes) {
				this.includedTableNamePrefixes.add(tableNamePrefix);
			}
		}
	}
	
	public void setMyTypeMapping(TypeMapping typeMapping) {
		this.typeMapping = typeMapping;
	}

	protected void buildTableNames(List<TableMeta> ret) throws SQLException {
		ResultSet rs = dbMeta.getTables(conn.getCatalog(), null, null, new String[]{"TABLE", "VIEW"});
		boolean included = true;
		int i = 0;
		while (rs.next()) {
			included = false;
			i = 0;
			String tableName = rs.getString("TABLE_NAME");
			for(String prefix : includedTableNamePrefixes){
				i++;
				if(tableName.startsWith(prefix)){
					included = true;
					break;
				}
			}
			if(!included && i > 0){
				continue;
			}
			if (excludedTables.contains(tableName)) {
				System.out.println("Skip excluded table :" + tableName);
			}
			else {
				TableMeta tableMeta = new TableMeta();
				tableMeta.name = tableName;
				tableMeta.remarks = rs.getString("REMARKS");
				// 移除表名前缀仅用于生成 modelName、baseModelName。tableMeta.name 表名自身不受影响
				if (removedTableNamePrefixes != null) {
					for (String prefix : removedTableNamePrefixes) {
						if (tableName.startsWith(prefix)) {
							tableName = tableName.replaceFirst(prefix, "");
							break;
						}
					}
				}
				tableMeta.modelName = StrKit.firstCharToUpperCase(StrKit.toCamelCase(tableName));
				tableMeta.baseModelName = "Base" + tableMeta.modelName;
				ret.add(tableMeta);
			}
		}
		rs.close();
	}

	
	/**
	 * 文档参考:
	 * http://dev.mysql.com/doc/connector-j/en/connector-j-reference-type-conversions.html
	 * 
	 * JDBC 与时间有关类型转换规则,mysql 类型到 java 类型如下对应关系:
	 * DATE				java.sql.Date
	 * DATETIME			java.sql.Timestamp
	 * TIMESTAMP[(M)]	java.sql.Timestamp
	 * TIME				java.sql.Time
	 * 
	 * 对数据库的 DATE、DATETIME、TIMESTAMP、TIME 四种类型注入 new java.util.Date()对象保存到库以后可以达到“秒精度”
	 * 为了便捷性,getter、setter 方法中对上述四种字段类型采用 java.util.Date,可通过定制 TypeMapping 改变此映射规则
	 */
	protected void buildColumnMetas(TableMeta tableMeta) throws SQLException {
		Map<String,String> remarksMap = new HashMap<String,String>();
		ResultSet rs = dbMeta.getColumns(conn.getCatalog(), null, tableMeta.name, null);
		String name = null;
		String remarks = null;
		while (rs.next()) {
			name = rs.getString("COLUMN_NAME");			// 名称
			remarks = rs.getString("REMARKS");			// 备注
			if (null == remarks)
				remarks = "";
			remarksMap.put(name, remarks);			
		}
		rs.close();
		String sql = dialect.forTableBuilderDoBuild(tableMeta.name);
		Statement stm = conn.createStatement();
		rs = stm.executeQuery(sql);
		ResultSetMetaData rsmd = rs.getMetaData();
		for (int i=1; i<=rsmd.getColumnCount(); i++) {
			ColumnMeta cm = new ColumnMeta();
			cm.name = rsmd.getColumnName(i);
			String colClassName = rsmd.getColumnClassName(i);
			String typeStr = typeMapping.getType(colClassName);
			if (typeStr != null) {
				cm.javaType = typeStr;
			}
			else {
				int type = rsmd.getColumnType(i);
				if (type == Types.BINARY || type == Types.VARBINARY || type == Types.BLOB) {
					cm.javaType = "byte[]";
				}
				else if (type == Types.CLOB || type == Types.NCLOB) {
					cm.javaType = "java.lang.String";
				}
				else {
					cm.javaType = "java.lang.String";
				}
			}
			if(remarksMap.containsKey(cm.name)){
				cm.remarks = remarksMap.get(cm.name);
			}
			tableMeta.columnMetas.add(cm);
		}
		rs.close();
		stm.close();
	}
	
}

      注意:要是MetaBuilder类的typeMapping修饰为protected就能更完美了

package com.nlm.web.generator;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.generator.BaseModelGenerator;
import com.jfinal.plugin.activerecord.generator.ColumnMeta;
import com.jfinal.plugin.activerecord.generator.TableMeta;

public class MyBaseModelGenerator extends BaseModelGenerator {
	
	public MyBaseModelGenerator(String baseModelPackageName, String baseModelOutputDir) {
		super(baseModelPackageName, baseModelOutputDir);
		importTemplate =
				"import com.nlm.web.model.BaseModel;%n" +
				"import com.jfinal.plugin.activerecord.IBean;%n%n";
		classDefineTemplate =
				"/**%n" +
				" * Generated by JFinal, do not modify this file.%n" +
				" * tableName: %s,remarks: %s%n" +
				" */%n" +
				"@SuppressWarnings(\"serial\")%n" +
				"public abstract class %s<M extends %s<M>> extends BaseModel<M> implements IBean {%n%n";
		setterTemplate =
				"\t/**%n" +
				"\t * %s%n"+
				"\t * @param %s%n" +
				"\t */%n" +
				"\tpublic void %s(%s %s) {%n" +
					"\t\tset(\"%s\", %s);%n" +
				"\t}%n%n";
		getterTemplate =
				"\t/**%n" +
				"\t * %s%n"+
				"\t * @return %n" +
				"\t */%n" +
				"\tpublic %s %s() {%n" +
					"\t\treturn get(\"%s\");%n" +
				"\t}%n%n";
	}
	
	protected void genClassDefine(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(classDefineTemplate, tableMeta.name,tableMeta.remarks,tableMeta.baseModelName, tableMeta.baseModelName));
	}
	
	protected void genSetMethodName(ColumnMeta columnMeta, StringBuilder ret) {
		String setterMethodName = "set" + StrKit.firstCharToUpperCase(StrKit.toCamelCase(columnMeta.name));
		String attrName = StrKit.toCamelCase(columnMeta.name);
		String setter = String.format(setterTemplate, columnMeta.remarks,attrName,setterMethodName, columnMeta.javaType, attrName, columnMeta.name, attrName);
		ret.append(setter);
	}
	
	protected void genGetMethodName(ColumnMeta columnMeta, StringBuilder ret) {
		String getterMethodName = "get" + StrKit.firstCharToUpperCase(StrKit.toCamelCase(columnMeta.name));
		String getter = String.format(getterTemplate, columnMeta.remarks,columnMeta.javaType, getterMethodName, columnMeta.name);
		ret.append(getter);
	}

}



package com.nlm.web.generator;

import java.util.List;

import javax.sql.DataSource;

import com.jfinal.plugin.activerecord.dialect.Dialect;
import com.jfinal.plugin.activerecord.generator.BaseModelGenerator;
import com.jfinal.plugin.activerecord.generator.DataDictionaryGenerator;
import com.jfinal.plugin.activerecord.generator.MappingKitGenerator;
import com.jfinal.plugin.activerecord.generator.ModelGenerator;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import com.jfinal.plugin.activerecord.generator.TypeMapping;

public class MyGenerator {
	
	protected MyMetaBuilder metaBuilder;
	protected BaseModelGenerator baseModelGenerator;
	protected ModelGenerator modelGenerator;
	protected MappingKitGenerator mappingKitGenerator;
	protected DataDictionaryGenerator dataDictionaryGenerator;
	protected boolean generateDataDictionary = false;
	
	/**
	 * 构造 Generator,生成 BaseModel、Model、MappingKit 三类文件,其中 MappingKit 输出目录与包名与 Model相同
	 * @param dataSource 数据源
	 * @param baseModelPackageName base model 包名
	 * @param baseModelOutputDir base mode 输出目录
	 * @param modelPackageName model 包名
	 * @param modelOutputDir model 输出目录
	 */
	public MyGenerator(DataSource dataSource, String baseModelPackageName, String baseModelOutputDir, String modelPackageName, String modelOutputDir) {
		this(dataSource, new MyBaseModelGenerator(baseModelPackageName, baseModelOutputDir),new ModelGenerator(modelPackageName, baseModelPackageName, modelOutputDir));
		this.mappingKitGenerator = new MappingKitGenerator(modelPackageName, modelOutputDir);
		this.dataDictionaryGenerator = new DataDictionaryGenerator(dataSource, modelOutputDir);
	}
	
	/**
	 * 构造 Generator,只生成 baseModel
	 * @param dataSource 数据源
	 * @param baseModelPackageName base model 包名
	 * @param baseModelOutputDir base mode 输出目录
	 */
	public MyGenerator(DataSource dataSource, String baseModelPackageName, String baseModelOutputDir) {
		this(dataSource, new MyBaseModelGenerator(baseModelPackageName, baseModelOutputDir));
	}
	
	public MyGenerator(DataSource dataSource, BaseModelGenerator baseModelGenerator) {
		if (dataSource == null)
			throw new IllegalArgumentException("dataSource can not be null.");
		if (baseModelGenerator == null)
			throw new IllegalArgumentException("baseModelGenerator can not be null.");
		this.metaBuilder = new MyMetaBuilder(dataSource);
		this.baseModelGenerator = baseModelGenerator;
		this.modelGenerator = null;
		this.mappingKitGenerator = null;
		this.dataDictionaryGenerator = null;
	}
	
	/**
	 * 使用指定 BaseModelGenerator、ModelGenerator 构造 Generator 
	 * 生成 BaseModel、Model、MappingKit 三类文件,其中 MappingKit 输出目录与包名与 Model相同
	 */
	public MyGenerator(DataSource dataSource, BaseModelGenerator baseModelGenerator, ModelGenerator modelGenerator) {
		if (dataSource == null)
			throw new IllegalArgumentException("dataSource can not be null.");
		if (baseModelGenerator == null)
			throw new IllegalArgumentException("baseModelGenerator can not be null.");
		if (modelGenerator == null)
			throw new IllegalArgumentException("modelGenerator can not be null.");
		this.metaBuilder = new MyMetaBuilder(dataSource);
		this.baseModelGenerator = baseModelGenerator;
		this.modelGenerator = modelGenerator;
		this.mappingKitGenerator = null;
		this.dataDictionaryGenerator = null;
	}
	
	/**
	 * 设置 MetaBuilder,便于扩展自定义 MetaBuilder
	 */
	public void setMetaBuilder(MyMetaBuilder metaBuilder) {
		if (metaBuilder != null)
			this.metaBuilder = metaBuilder;
	}
	
	public void setTypeMapping(TypeMapping typeMapping) {
		this.metaBuilder.setTypeMapping(typeMapping);
	}
	
	/**
	 * 设置 MappingKitGenerator,便于扩展自定义 MappingKitGenerator
	 */
	public void setMappingKitGenerator(MappingKitGenerator mappingKitGenerator) {
		if (mappingKitGenerator != null)
			this.mappingKitGenerator = mappingKitGenerator;
	}
	
	/**
	 * 设置 DataDictionaryGenerator,便于扩展自定义 DataDictionaryGenerator
	 */
	public void setDataDictionaryGenerator(DataDictionaryGenerator dataDictionaryGenerator) {
		if (dataDictionaryGenerator != null)
			this.dataDictionaryGenerator = dataDictionaryGenerator;
	}
	
	/**
	 * 设置数据库方言,默认为 MysqlDialect
	 */
	public void setDialect(Dialect dialect) {
		metaBuilder.setDialect(dialect);
	}
	
	/**
	 * 设置需要被移除的表名前缀,仅用于生成 modelName 与  baseModelName
	 * 例如表名  "osc_account",移除前缀 "osc_" 后变为 "account"
	 */
	public void setRemovedTableNamePrefixes(String... removedTableNamePrefixes) {
		metaBuilder.setRemovedTableNamePrefixes(removedTableNamePrefixes);
	}
	
	/**
	 * 添加不需要处理的数据表
	 */
	public void addExcludedTable(String... excludedTables) {
		metaBuilder.addExcludedTable(excludedTables);
	}
	
	/**
	 * 添加需要处理的数据表的前缀
	 */
	public void addIncludedTableNamePrefixes(String... includedTableNamePrefixes) {
		metaBuilder.addIncludedTableNamePrefixes(includedTableNamePrefixes);
	}
	
	/**
	 * 设置是否在 Model 中生成 dao 对象,默认生成
	 */
	public void setGenerateDaoInModel(boolean generateDaoInModel) {
		if (modelGenerator != null)
			modelGenerator.setGenerateDaoInModel(generateDaoInModel);
	}
	
	/**
	 * 设置是否生成数据字典 Dictionary 文件,默认不生成
	 */
	public void setGenerateDataDictionary(boolean generateDataDictionary) {
		this.generateDataDictionary = generateDataDictionary;
	}
	
	/**
	 * 设置 MappingKit 文件输出目录,默认与 modelOutputDir 相同,
	 * 在设置此变量的同时需要设置 mappingKitPackageName
	 */
	public void setMappingKitOutputDir(String mappingKitOutputDir) {
		if (this.mappingKitGenerator != null)
			this.mappingKitGenerator.setMappingKitOutputDir(mappingKitOutputDir);
	}
	
	/**
	 * 设置 MappingKit 文件包名,默认与 modelPackageName 相同,
	 * 在设置此变的同时需要设置 mappingKitOutputDir
	 */
	public void setMappingKitPackageName(String mappingKitPackageName) {
		if (this.mappingKitGenerator != null)
			this.mappingKitGenerator.setMappingKitPackageName(mappingKitPackageName);
	}
	
	/**
	 * 设置 MappingKit 文件名,默认为_ MappingKit 
	 */
	public void setMappingKitClassName(String mappingKitClassName) {
		if (this.mappingKitGenerator != null)
			this.mappingKitGenerator.setMappingKitClassName(mappingKitClassName);
	}
	
	/**
	 * 设置数据字典 DataDictionary 文件输出目录,默认与 modelOutputDir 相同
	 */
	public void setDataDictionaryOutputDir(String dataDictionaryOutputDir) {
		if (this.dataDictionaryGenerator != null)
			this.dataDictionaryGenerator.setDataDictionaryOutputDir(dataDictionaryOutputDir);
	}
	
	/**
	 * 设置数据字典 DataDictionary 文件输出目录,默认值为 "_DataDictionary.txt"
	 */
	public void setDataDictionaryFileName(String dataDictionaryFileName) {
		if (dataDictionaryGenerator != null)
			dataDictionaryGenerator.setDataDictionaryFileName(dataDictionaryFileName);
	}
	
	public void generate() {
		List<TableMeta> tableMetas = metaBuilder.build();
		if (tableMetas.size() == 0) {
			System.out.println("TableMeta 数量为 0,不生成任何文件");
			return ;
		}
		baseModelGenerator.generate(tableMetas);
		if (modelGenerator != null)	
			modelGenerator.generate(tableMetas);
		if (mappingKitGenerator != null)
			mappingKitGenerator.generate(tableMetas);
		if (dataDictionaryGenerator != null && generateDataDictionary)
			dataDictionaryGenerator.generate(tableMetas);
		System.out.println("Generate complete.");
	}

}

生成例子如下:

package com.nlm.model.base;

import com.nlm.web.model.BaseModel;
import com.jfinal.plugin.activerecord.IBean;

/**
 * Generated by JFinal, do not modify this file.
 * tableName: t_sys_org,remarks: 组织机构表
 */
@SuppressWarnings("serial")
public abstract class BaseOrg<M extends BaseOrg<M>> extends BaseModel<M> implements IBean {

	/**
	 * 主键
	 * @param id
	 */
	public void setId(java.lang.Integer id) {
		set("id", id);
	}

	/**
	 * 主键
	 * @return 
	 */
	public java.lang.Integer getId() {
		return get("id");
	}

	/**
	 * 父节点
	 * @param parentId
	 */
	public void setParentId(java.lang.Integer parentId) {
		set("parentId", parentId);
	}

	/**
	 * 父节点
	 * @return 
	 */
	public java.lang.Integer getParentId() {
		return get("parentId");
	}

	/**
	 * 机构名称
	 * @param name
	 */
	public void setName(java.lang.String name) {
		set("name", name);
	}

	/**
	 * 机构名称
	 * @return 
	 */
	public java.lang.String getName() {
		return get("name");
	}

	/**
	 * 图标
	 * @param icon
	 */
	public void setIcon(java.lang.String icon) {
		set("icon", icon);
	}

	/**
	 * 图标
	 * @return 
	 */
	public java.lang.String getIcon() {
		return get("icon");
	}

	/**
	 * 左支
	 * @param leftVal
	 */
	public void setLeftVal(java.lang.Integer leftVal) {
		set("leftVal", leftVal);
	}

	/**
	 * 左支
	 * @return 
	 */
	public java.lang.Integer getLeftVal() {
		return get("leftVal");
	}

	/**
	 * 右支
	 * @param rightVal
	 */
	public void setRightVal(java.lang.Long rightVal) {
		set("rightVal", rightVal);
	}

	/**
	 * 右支
	 * @return 
	 */
	public java.lang.Long getRightVal() {
		return get("rightVal");
	}

	/**
	 * 排序号
	 * @param orderNo
	 */
	public void setOrderNo(java.lang.Integer orderNo) {
		set("orderNo", orderNo);
	}

	/**
	 * 排序号
	 * @return 
	 */
	public java.lang.Integer getOrderNo() {
		return get("orderNo");
	}

	/**
	 * 显示标志   1-显示  0-隐藏
	 * @param show
	 */
	public void setShow(java.lang.String show) {
		set("show", show);
	}

	/**
	 * 显示标志   1-显示  0-隐藏
	 * @return 
	 */
	public java.lang.String getShow() {
		return get("show");
	}

	/**
	 * 状态 1-有效  0-无效
	 * @param status
	 */
	public void setStatus(java.lang.String status) {
		set("status", status);
	}

	/**
	 * 状态 1-有效  0-无效
	 * @return 
	 */
	public java.lang.String getStatus() {
		return get("status");
	}

}



你可能感兴趣的:(针对jfinal的Generator进行扩展)