jfinal的generator对sqlite的扩展支持
2016-04-14 00:00
190 查看
摘要: 写测试小项目时,发现jfinal自带的model生成工具在sqlite中使用由较大的问题,于是对其进行了简单的扩展,使其不会一味的将所有字段建成String类型,并对其进行date类型伪支持
首先是参数设置页,和demo差不多
然后是MetaBuilder扩展,数据库以date或time结尾的integer类型字段,会映射为Date类型。
接着是Generator扩展,更新了部分方法,同时将不适宜的构造方法标注为过时。
最后是BaseModelGenerator扩展,添加Date类型时的getset方法支持。
下面以一个简单表进行演示不同:
先看一下默认生成的basemodel中的样子
再看一下修改后的样子
差别反正很好看出来的
首先是参数设置页,和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")); } }
差别反正很好看出来的
相关文章推荐
- 初识SQLITE3数据库
- 将 Ghost 从 SQLite3 数据库迁移到 MySQL 数据库
- SQLite3 命令行操作指南
- jfinal与bootstrap的登录跳转实战演习
- SQLITE3 使用总结
- SQLite3中自增主键相关知识总结
- ubuntu下使用SQLite3的基本命令
- Android SQLite3多线程操作问题研究总结
- Android开发之sqlite3命令行简单使用方法
- Python标准库之sqlite3使用实例
- Python SQLite3数据库操作类分享
- Python操作sqlite3快速、安全插入数据(防注入)的实例
- JFinal Dao 集成到 Spring
- JFinal常见问题汇总
- 使用Freesql简单地实现多条件查询
- JFinal使用Freemarker作为展示层中的国际化配置使用
- 生成jFinal的动态条件查询语句的工具类 3ff8
- JFinal项目之自动删除日志文件功能
- JFinal学习-Excel导出
- jfinal 调用 存储过程,并将结果返回