jfinal的generator对sqlite的扩展支持
博客专区 > chmin 的博客 > 博客详情
jfinal的generator对sqlite的扩展支持
chmin 发表于2年前
jfinal的generator对sqlite的扩展支持
  • 发表于 2年前
  • 阅读 98
  • 收藏 1
  • 点赞 1
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 写测试小项目时,发现jfinal自带的model生成工具在sqlite中使用由较大的问题,于是对其进行了简单的扩展,使其不会一味的将所有字段建成String类型,并对其进行date类型伪支持

首先是参数设置页,和demo差不多

package top.chmin.config;

import javax.sql.DataSource;

import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.dialect.Sqlite3Dialect;
import com.jfinal.plugin.c3p0.C3p0Plugin;

/**
 * chmin
 */
public class MySqliteModelGenerator {
	protected StringBuilder basePack = new StringBuilder();
	protected StringBuilder basePath = new StringBuilder();
	protected StringBuilder modelPack = new StringBuilder();
	protected StringBuilder modelPath = new StringBuilder();

	/**
	 * 获取数据库数据源
	 * 
	 * @return
	 */
	public DataSource getDataSource() {
		PropKit.use("config.txt");
		C3p0Plugin cp = new C3p0Plugin(PropKit.get("jdbcurl"),
				PropKit.get("username"), PropKit.get("password"),
				PropKit.get("driverClass"));
		cp.start();
		return cp.getDataSource();
	}

	/**
	 * 依次输入model所在的包,如top.chmin.model则输入generator("top","chmin","model")
	 * 
	 * @param pack
	 */
	public void generator(String... pack) {
		modelPath.append(PathKit.getWebRootPath()).append("/../src/");

		for (int i = 0; i < pack.length; i++) {
			modelPack.append(pack[i]);
			modelPath.append(pack[i]);
			if (i != pack.length - 1) {
				modelPack.append(".");
				modelPath.append("/");
			}
		}

		basePack.append(modelPack.toString()).append(".").append("base");
		basePath.append(modelPath.toString()).append("/").append("base");
		SqliteGenerator gernerator = new SqliteGenerator(getDataSource(),
				basePack.toString(), basePath.toString(), modelPack.toString(),
				modelPath.toString());
		gernerator.setGenerateDaoInModel(true);
		gernerator.setDialect(new Sqlite3Dialect());
		gernerator.addExcludedTable("sqlite_sequence");
		gernerator.generate();
	}

	public static void main(String[] args) {
		new MySqliteModelGenerator().generator("top", "chmin", "model");
	}
}

然后是MetaBuilder扩展,数据库以date或time结尾的integer类型字段,会映射为Date类型。

package top.chmin.config;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import com.jfinal.plugin.activerecord.generator.ColumnMeta;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;

/**
 * chmin 2016年4月14日 下午3:22:15
 */
public class SqliteMetaBuilder extends MetaBuilder {

	public SqliteMetaBuilder(DataSource dataSource) {
		super(dataSource);
	}
	
	@override
	protected void buildColumnMetas(TableMeta tableMeta) throws SQLException {
		String sql = dialect.forTableBuilderDoBuild(tableMeta.name);
		Statement stm = conn.createStatement();
		ResultSet 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);
			int type = rsmd.getColumnType(i);
			// 修改的部分开始
			if (type == Types.INTEGER) {
				if (dateOrTime(cm.name)) {
					cm.javaType = "Date";
				} else {
					cm.javaType = "Integer";
				}
			} else {
				cm.javaType = "String";
			}
			// 修改的部分结束
			cm.attrName = buildAttrName(cm.name);

			tableMeta.columnMetas.add(cm);
		}

		rs.close();
		stm.close();
	}

	protected boolean dateOrTime(String string) {
		if (string.length() > 4) {
			string = string.substring(string.length() - 4);
			if ("date".equalsIgnoreCase(string)
					|| "time".equalsIgnoreCase(string)) {
				return true;
			}
		}
		return false;
	}
}

接着是Generator扩展,更新了部分方法,同时将不适宜的构造方法标注为过时。

package top.chmin.config;

import java.util.List;

import javax.sql.DataSource;

import com.jfinal.plugin.activerecord.generator.BaseModelGenerator;
import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.activerecord.generator.ModelGenerator;
import com.jfinal.plugin.activerecord.generator.TableMeta;

/**
 * chmin 2016年4月14日 下午2:59:43
 */
public class SqliteGenerator extends Generator {
	
	protected String modelPackageName;
	protected String modelOutputDir;

	public SqliteGenerator(DataSource dataSource, String baseModelPackageName,
			String baseModelOutputDir, String modelPackageName,
			String modelOutputDir) {
		this(dataSource, new SqliteBaseModelGenerator(baseModelPackageName,
				baseModelOutputDir), new ModelGenerator(modelPackageName,
				baseModelPackageName, modelOutputDir));
		this.modelPackageName = modelPackageName;
		this.modelOutputDir = modelOutputDir;
	}

	@Deprecated
	public SqliteGenerator(DataSource dataSource, String baseModelPackageName,
			String baseModelOutputDir) {
		this(dataSource, new SqliteBaseModelGenerator(baseModelPackageName,
				baseModelOutputDir));
	}

	@Deprecated
	public SqliteGenerator(DataSource dataSource, BaseModelGenerator baseModelGenerator) {
		super(dataSource, baseModelGenerator);
		this.metaBuilder = new SqliteMetaBuilder(dataSource);
	}

	@Deprecated
	public SqliteGenerator(DataSource dataSource,
			BaseModelGenerator baseModelGenerator, ModelGenerator modelGenerator) {
		super(dataSource, baseModelGenerator, modelGenerator);
		this.metaBuilder = new SqliteMetaBuilder(dataSource);
	}

	@Override
	public void generate() {
		this.mappingKitGenerator = new SqliteMappingKitGenerator(modelPackageName, modelOutputDir);
		List<TableMeta> tableMetas = metaBuilder.build();
		if (tableMetas.size() == 0) {
			return ;
		}
		
		baseModelGenerator.generate(tableMetas);
		
		if (modelGenerator != null) {
			modelGenerator.generate(tableMetas);
		}
		
		if (mappingKitGenerator != null) {
			mappingKitGenerator.generate(tableMetas);
		}
		
		if (dataDictionaryGenerator != null && generateDataDictionary) {
			dataDictionaryGenerator.generate(tableMetas);
		}
		
	}
}

最后是BaseModelGenerator扩展,添加Date类型时的getset方法支持。

package top.chmin.config;

import java.util.List;

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;

/**
 * chmin 2016年4月14日 下午3:07:33
 */
public class SqliteBaseModelGenerator extends BaseModelGenerator {
	
	protected String importTemplate =
			"import com.jfinal.plugin.activerecord.Model;%n" +
			"import com.jfinal.plugin.activerecord.IBean;%n%n";
	protected String importTemplate2 =
			"import com.jfinal.plugin.activerecord.Model;%n" +
			"import com.jfinal.plugin.activerecord.IBean;%n" +
			"import java.util.Date;%n%n";
	
	protected String classDefineTemplate =
			"/**%n" +
			" * Generated by JFinal, update by chmin, do not modify this file.%n" +
			" */%n" +
			"@SuppressWarnings(\"serial\")%n" +
			"public abstract class %s<M extends %s<M>> extends Model<M> implements IBean {%n%n";
	
	protected String setterTemplate =
			"\tpublic void %s(%s %s) {%n" +
				"\t\tset(\"%s\", %s);%n" +
			"\t}%n%n";
	protected String setterTemplate2 =
			"\tpublic void %s(%s %s) {%n" +
				"\t\tset(\"%s\", %s.getTime());%n" +
			"\t}%n%n";
	protected String getterTemplate =
			"\tpublic %s %s() {%n" +
				"\t\treturn get(\"%s\");%n" +
			"\t}%n%n";
	protected String getterTemplate2 =
			"\tpublic %s %s() {%n" +
				"\t\treturn new Date(getInt(\"%s\"));%n" +
			"\t}%n%n";
	public SqliteBaseModelGenerator(String baseModelPackageName,
			String baseModelOutputDir) {
		super(baseModelPackageName, baseModelOutputDir);
	}

	@Override
	public void generate(List<TableMeta> tableMetas) {
		for (TableMeta tableMeta : tableMetas)
			genBaseModelContent(tableMeta);
		wirtToFile(tableMetas);
	}
	
	@Override
	protected void genBaseModelContent(TableMeta tableMeta) {
		StringBuilder ret = new StringBuilder();
		genPackage(ret);
		genImport(ret, tableMeta);
		genClassDefine(tableMeta, ret);
		for (ColumnMeta columnMeta : tableMeta.columnMetas) {
			genSetMethodName(columnMeta, ret);
			genGetMethodName(columnMeta, ret);
		}
		ret.append(String.format("}%n"));
		tableMeta.baseModelContent = ret.toString();
	}
	
	@Override
	protected void genClassDefine(TableMeta tableMeta, StringBuilder ret) {
		ret.append(String.format(classDefineTemplate, tableMeta.baseModelName, tableMeta.baseModelName));
	}
	
	@Override
	protected void genSetMethodName(ColumnMeta columnMeta, StringBuilder ret) {
		String setterMethodName = "set" + StrKit.firstCharToUpperCase(columnMeta.attrName);
		// 如果 setter 参数名为 java 语言关键字,则添加下划线前缀 "_"
		String argName = javaKeyword.contains(columnMeta.attrName) ? "_" + columnMeta.attrName : columnMeta.attrName;
		String setter = null;
		if("Date".equals(columnMeta.javaType)){
			setter = String.format(setterTemplate2, setterMethodName, columnMeta.javaType, argName, columnMeta.name, argName);
		} else {
			setter = String.format(setterTemplate, setterMethodName, columnMeta.javaType, argName, columnMeta.name, argName);
		}
		ret.append(setter);
	}

	@Override
	protected void genGetMethodName(ColumnMeta columnMeta, StringBuilder ret) {
		String getterMethodName = "get" + StrKit.firstCharToUpperCase(columnMeta.attrName);
		String getter = null;
		if("Date".equals(columnMeta.javaType)){
			getter = String.format(getterTemplate2, columnMeta.javaType, getterMethodName, columnMeta.name);
		} else {
			getter = String.format(getterTemplate, columnMeta.javaType, getterMethodName, columnMeta.name);
		}
		ret.append(getter);
	}
	
	protected void genImport(StringBuilder ret, TableMeta tableMeta) {
		if(hasDate(tableMeta)){
			ret.append(String.format(importTemplate2));
		} else {
			ret.append(String.format(importTemplate));
		}
	}
	
	protected boolean hasDate(TableMeta tableMeta){
		for (ColumnMeta columnMeta: tableMeta.columnMetas){
			if("Date".equals(columnMeta.javaType)){
				return true;
			}
		}
		return false;
	}
}

下面以一个简单表进行演示不同:

DROP TABLE IF EXISTS "main"."login";
CREATE TABLE "login" (
"id"  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"code"  TEXT,
"openid"  TEXT,
"createTime"  INTEGER
);

先看一下默认生成的basemodel中的样子

package top.chmin.model.base;

import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.IBean;

/**
 * Generated by JFinal, do not modify this file.
 */
@SuppressWarnings("serial")
public abstract class BaseLogin<M extends BaseLogin<M>> extends Model<M> implements IBean {

	public void setId(java.lang.String id) {
		set("id", id);
	}

	public java.lang.String getId() {
		return get("id");
	}

	public void setCode(java.lang.String code) {
		set("code", code);
	}

	public java.lang.String getCode() {
		return get("code");
	}

	public void setOpenid(java.lang.String openid) {
		set("openid", openid);
	}

	public java.lang.String getOpenid() {
		return get("openid");
	}

	public void setCreateTime(java.lang.String createTime) {
		set("createTime", createTime);
	}

	public java.lang.String getCreateTime() {
		return get("createTime");
	}

}

再看一下修改后的样子

package top.chmin.model.base;

import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.IBean;
import java.util.Date;

/**
 * Generated by JFinal, update by chmin, do not modify this file.
 */
@SuppressWarnings("serial")
public abstract class BaseLogin<M extends BaseLogin<M>> extends Model<M> implements IBean {

	public void setId(Integer id) {
		set("id", id);
	}

	public Integer getId() {
		return get("id");
	}

	public void setCode(String code) {
		set("code", code);
	}

	public String getCode() {
		return get("code");
	}

	public void setOpenid(String openid) {
		set("openid", openid);
	}

	public String getOpenid() {
		return get("openid");
	}

	public void setCreateTime(Date createTime) {
		set("createTime", createTime.getTime());
	}

	public Date getCreateTime() {
		return new Date(getInt("createTime"));
	}

}

差别反正很好看出来的

标签: Jfinal Geneator Sqlite3
共有 人打赏支持
粉丝 3
博文 8
码字总数 5714
×
chmin
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: