您的位置:首页 > 数据库

jfinal的generator对sqlite的扩展支持

2016-04-14 00:00 190 查看
摘要: 写测试小项目时,发现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