在com.jfinal.plugin.activerecord.generator包中,提供了一个Generator工具,可自动生成 Model、BaseModel、MappingKit、DataDictionary 四类文件。
Generator类的构造器源码:
public Generator(DataSource dataSource, String baseModelPackageName, String baseModelOutputDir, String modelPackageName, String modelOutputDir) {
this(dataSource, new BaseModelGenerator(baseModelPackageName, baseModelOutputDir), new ModelGenerator(modelPackageName, baseModelPackageName, modelOutputDir));
}
一共有5个参数,其中
dataSource:表示数据源
baseModelPackageName:BaseModel所使用的包名
baseModelOutputDir:BaseModel文件输出路径
modelPackageName:Model所使用的包名
modelOutputDir:Model文件输出路径
MappingKit和DataDictionary默认和Model的文件保存路径一致。
生成器工具源码:
package com.tinytime.demo.jfinal3.generate;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.druid.DruidPlugin;
import javax.sql.DataSource;
/**
* 生成器
*
* @date 2018/9/29 16:03
*/
public class JFinalGenerator {
public static DataSource getDataSource() {
PropKit.use("config.properties");
DruidPlugin druidPlugin = new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("username"), PropKit.get("password"));
druidPlugin.start();
return druidPlugin.getDataSource();
}
public static void main(String[] args) {
System.out.println("WebRootPath=" + PathKit.getWebRootPath());
String baseOutputDir = PathKit.getWebRootPath() + "/src/main/java/";
// model 所使用的modelPackageName包名 (MappingKit 默认使用的包名)
String modelPackageName = "com.tinytime.demo.jfinal3.model";
// model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
String modelOutputDir = baseOutputDir + "com/tinytime/demo/jfinal3/model";
// base model 所使用的包名
String baseModelPackageName = modelPackageName + ".base";
// base model 文件保存路径
String baseModelOutputDir = modelOutputDir + "/base";
System.out.println("baseModelOutputDir=" + baseModelOutputDir);
// 创建生成器
Generator generator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
// 添加不需要生成的表名
generator.addExcludedTable("");
// 设置是否在 Model 中生成 service 对象
generator.setGenerateDaoInModel(false);
// 设置是否生成链式 setter 方法
generator.setGenerateChainSetter(true);
// 设置是否生成字典文件
generator.setGenerateDataDictionary(false);
// 设置需要被移除的表名前缀用于生成modelName。例如表名 "prefix_user",移除前缀 "prefix_"后生成的model名为 "User"而非 PrefixUser
generator.setRemovedTableNamePrefixes("t_");
// 生成
generator.generate();
}
}
数据源配置:
config.properties
jdbcUrl=jdbc:mysql://localhost/tinytime-demo-jfinal3?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
username=root
password=123456
jdbc.sql
DROP DATABASE IF EXISTS `tinytime-demo-jfinal3`;
CREATE DATABASE `tinytime-demo-jfinal3` CHARACTER SET utf8 COLLATE utf8_general_ci;
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID主键',
`user_name` varchar(20) DEFAULT NULL COMMENT '用户姓名',
`user_email` varchar(20) DEFAULT NULL COMMENT '用户邮箱',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_general_ci;
创建DRUD数据源:
public static DataSource getDataSource() {
PropKit.use("config.properties");
DruidPlugin druidPlugin = new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("username"), PropKit.get("password"));
druidPlugin.start();
return druidPlugin.getDataSource();
}
通过JFinalGenerator工具生成的代码:
Model
package com.tinytime.demo.jfinal3.model;
import com.tinytime.demo.jfinal3.model.base.BaseUser;
/**
* Generated by JFinal.
*/
@SuppressWarnings("serial")
public class User extends BaseUser {
}
BaseModel
package com.tinytime.demo.jfinal3.model.base;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.IBean;
/**
* Generated by JFinal, do not modify this file.
*/
@SuppressWarnings({"serial", "unchecked"})
public abstract class BaseUser> extends Model implements IBean {
public M setUserId(java.lang.Long userId) {
set("user_id", userId);
return (M)this;
}
public java.lang.Long getUserId() {
return getLong("user_id");
}
public M setUserName(java.lang.String userName) {
set("user_name", userName);
return (M)this;
}
public java.lang.String getUserName() {
return getStr("user_name");
}
public M setUserEmail(java.lang.String userEmail) {
set("user_email", userEmail);
return (M)this;
}
public java.lang.String getUserEmail() {
return getStr("user_email");
}
}
MappingKit
package com.tinytime.demo.jfinal3.model;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
/**
* Generated by JFinal, do not modify this file.
*
* Example:
* public void configPlugin(Plugins me) {
* ActiveRecordPlugin arp = new ActiveRecordPlugin(...);
* _MappingKit.mapping(arp);
* me.add(arp);
* }
*
*/
public class _MappingKit {
public static void mapping(ActiveRecordPlugin arp) {
arp.addMapping("t_user", "user_id", User.class);
}
}
在实际应用中,将MappingKit配置在configPlugin中,就不需要通过arp.addMapping一个一个配置了,非常方便。
/**
* 配置插件
*
* @param plugins
*/
public void configPlugin(Plugins plugins) {
ActiveRecordPlugin arPlugin = new ActiveRecordPlugin(druidPlugin);
arPlugin.setShowSql(true);
_MappingKit.mapping(arPlugin);
plugins.add(arPlugin);
}
当数据库表结构变化时,再次运行JFinalGenerator工具即可,所有的Model、BaseModel、MappingKit、DataDictionary会重新生成。
JFinal的Generator生成的MappingKit默认为_MappingKit.java,怎么能设置成别的类名呢?能否让MappingKit类不和Model在同一个输出目录?
其实,JFinal的Generator提供了相关API
generator.setMappingKitClassName("MappingKit");
generator.setMappingKitPackageName("com.tinytime.demo.jfinal3.kit");
generator.setMappingKitOutputDir(baseOutputDir + "com/tinytime/demo/jfinal3/kit");
不过,建议还是采用JFinal默认的生成方式,因为我在实际使用的过程中,发现如果MappingKit放到其它包,当存在Model类冲突时(例如,要生成User.java,但是依赖中别的包也有User类),MappingKit里面的Model import代码无法自动生成,还需人工介入。
参考资料:
JFinal官方文档Generator与JavaBean :http://www.jfinal.com/doc/5-4