jfinal项目启动时,动态读取表、字段信息,占启动时间较长

jfinal项目在项目启动时,会动态读取数据库表结构,观察源代码主要获取了字段名称与类型,这部分动作占用启动时间80%以上,且在实际环境中数据库几乎不会发生变化,每次启动读取意义不大,若能进行优化,将大幅提高jfinal项目启动速度,体验更好,做到更加极致。

比如在下一个版本中,提供两种实现方式,使用惯用的factory:

1、基于jdbc读取(现方案);

2、基于文件(类似于表主键_MappingKit的方式,基于代码生成,一次生成终生受用,可能会牺牲db操作时对字段的实时检查,如setXXX()等,但是数据库本身会对sql进行检测);

将1作为下个版本的默认实现,将2作为可选方案,若改进后大家觉得2方案更实用,再将来的版本中可以考虑将2作为默认实现,平滑过渡且不影响原始jfinal用户的升级体验。


项目有一百多个表,这一步操作导致了项目需要三十多秒启动时间,而且sql打印了一大堆 select * from t_my_table where 1 = 2 的东西,致使强迫症患者险些入院治疗

仅此建议~纯属乱说~有错勿怪


致敬

评论区

JFinal

2019-03-20 11:35

非常好的建议,预先生成 table mapping 十分容易,以前没有人提起启动时速度时的映射时间加速的事,也就没这一路思脉

当前架构下,_MappingKit.java 已经有了,只需要在 MappingKitGenerator 中添加生成 model 到 table 的映射即可,只是再向前多走一步而已

_MappingKit.java 中多生成一个方法,向 TableMapping 中 put 进映射关系即可

这个建议十分合理,因为如果你 Model、BaseModel 都是生成的,那么已然将映射关系交给了生成器,进一步将 model 到 table 字段的映射也交给生成器也十分合理

JFinal

2019-03-20 11:36

如果这个功能添加上了, 估计项目的启动速度能到 0.3 秒之内

vk567

2019-03-20 11:40

这个建议厉害!

jounzhang

2019-03-25 10:14

@jfinal
自己试着实现了下,做出来了,效果非常非常好,只是jfinal需要小改几处源码,也不知道改的合不合适:
1、com.jfinal.plugin.activerecord.Table类中的setColumnTypeMap方法需要改成public修饰;
2、com.jfinal.plugin.activerecord.DbKit类中的addModelToConfigMapping方法需要改成public修饰;
3、com.jfinal.plugin.activerecord.ActiveRecordPlugin类中的start方法注释掉第228行
//new TableBuilder().build(tableList, config);
4、自定义MappingKit模板,加入相关逻辑
package #(mappingKitPackageName);

import cn.zcltd.c.ant.dao.*;
import com.jfinal.plugin.activerecord.*;

import java.util.HashMap;
import java.util.Map;

/**
* Generated by JFinal, do not modify this file.
*

* Example:
* public void configPlugin(Plugins me) {
* ActiveRecordPlugin arp = new ActiveRecordPlugin(...);
* #(mappingKitClassName).mapping(arp);
* me.add(arp);
* }
*

*/
public class #(mappingKitClassName) {

public static void mapping(ActiveRecordPlugin arp) {
Config config = arp.getConfig();
JavaType javaType = new JavaType();
TableMapping tableMapping = TableMapping.me();
Table table;
Map> tableColumnTypeMap;
#for (tableMeta : tableMetas)

#if (tableMeta.primaryKey.contains(","))
// Composite Primary Key order: #(tableMeta.primaryKey)
#end
arp.addMapping("#(tableMeta.name)", "#(tableMeta.primaryKey)", #(tableMeta.modelName).class);
table = new Table("#(tableMeta.name)", "#(tableMeta.primaryKey)", #(tableMeta.modelName).class);
tableColumnTypeMap = new HashMap<>();
#for (columnMeta : tableMeta.columnMetas)
tableColumnTypeMap.put("#(columnMeta.name)", javaType.getType("#(columnMeta.javaType)"));
#end
table.setColumnTypeMap(tableColumnTypeMap);
tableMapping.putTable(table);
DbKit.addModelToConfigMapping(table.getModelClass(), config);
#end
}
}


改造完后,测试结果如下(启动3次以上取平均值,run、debug模式差不不大):
空白项目 改造前10秒(10.2、10.6、9.8) 改造后3秒(3.2、3.1、2.9)
当前项目 114张表 改造前12秒(11.3、12.6、13.4) 改造后6秒(最快4.8、6.1、6.2)

关键在于自我改动无法发布,其他人的环境无法使用,不知道波总能不能优美的实现此功能

JFinal

2019-03-25 20:41

@jounzhang 做得不错,方向大致如此

改进的空间是: 充分利用现有的代码,例如 TableBuilder 中的逻辑能用上的全用上

jounzhang

2019-03-26 09:35

@JFinal 还原了,不想改源码,不方便下次升级

小徐同学

2019-08-22 15:28

@JFinal 这个做了没- 。-