您的位置:首页 > 其它

针对jfinal的Generator进行扩展

2016-01-11 11:31 113 查看
摘要: 主要实现了以下几个方面:
1、BaseModel中增加注释(表名、表备注、字段备注)
2、增加根据表名前缀过滤生成表
3、增加mappingKitClassName参数设置
4、增加BaseModel继承自定义的BaseModel,方便以后扩展

主要实现代码如下:
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;
S
7fe8
tring 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");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息