JFinal使用技巧-_MappingKit表字段类关系映射

上周末应好友之邀写了一个 JF 多租户的 demo。在编写租户ActiveRecordPlugin时出现一个小灵感,以前我们自己使用的是一个模板数据库,用来做 Db启动 映射表字段类关系。
 (PS:以前JF低版本有些方法未开放,也有写过一个插件https://jfinal.com/share/2508 )。
在 JF 高版本中这些set 方法已经开放可调用了。废话不多说了,上码:
还是官网的JFinal demo for maven 5.0.0  https://jfinal.com/download/now?file=jfinal_demo_for_maven-5.0.0.zip 

1、自定义 mapping_kit_template.jf 模板:

package #(mappingKitPackageName);

import com.jfinal.plugin.activerecord.*;

/**
 * Generated by JFinal, do not modify this file.
 * <pre>
 * Example:
 * public void configPlugin(Plugins me) {
 *     arp = new ActiveRecordPlugin(new NullDataSource(){
 *            public Connection getConnection() throws SQLException {
 *               return dbp.getDataSource().getConnection();
 *            }
 *         });
 *     #(mappingKitClassName).mapping(arp);
 *     me.add(arp);
 * }
 * </pre>
 */
 @SuppressWarnings("unchecked")
public class #(mappingKitClassName) {

    public static void mapping(ActiveRecordPlugin arp) {
        Config config = arp.getConfig();
    #for (tableMeta : tableMetas)
        #(tableMeta.name)(config);
    #end
    }

#for (tableMeta : tableMetas)
    private static void #(tableMeta.name)(Config config) {
        #if (tableMeta.primaryKey.contains(","))
        // Composite Primary Key order: #(tableMeta.primaryKey)
        #end
        Table t = new Table("#(tableMeta.name)", "#(tableMeta.primaryKey)", #(tableMeta.modelName).class);
        t.setColumnTypeMap(config.getContainerFactory().getAttrsMap());
    #for(cm : tableMeta.columnMetas)
        t.setColumnType("#(cm.name)", #(cm.javaType).class);
    #end
        config(config, t);
    }
#end

    private static void config(Config config, Table t) {
       TableMapping.me().putTable(t);
       CPI.addModelToConfigMapping(t.getModelClass(), config);
    }
}


2、修改 _JFinalDemoGenerator.java   设置自定义模板 setMappingKitTemplate

// 自定义 _MappingKit 模板 支持免启动JF映射ColumnType
generator.setMappingKitTemplate("/generator/mapping_kit_template.jf");
      
// 生成
generator.generate();


3、配置ActiveRecordPlugin 的方式:JFinalConfig 子类DemoConfig:  

public void configPlugin(Plugins me) {
    DruidPlugin dp = new DruidPlugin("jdbc:mysql://localhost/db_name", "userName", "password");
    me.add(dp);
    ActiveRecordPlugin arp = new ActiveRecordPlugin(new NullDataSource(){
        public Connection getConnection() throws SQLException {
           return dp.getDataSource().getConnection();
        }
    });
    // 所有映射在 MappingKit 中自动化搞定
    _MappingKit.mapping(arp);
    me.add(arp);

}

可以看到 以前是 new ActiveRecordPlugin(dp) , 现在是用new NullDataSource包裹了一下。

4、运行 _JFinalDemoGenerator.java 生成新的 _MappingKit 类代码,看效果:

...
@SuppressWarnings("unchecked")
public class _MappingKit {

    public static void mapping(ActiveRecordPlugin arp) {
        Config config = arp.getConfig();
        blog(config);
    }

    private static void blog(Config config) {
        Table t = new Table("blog", "id", Blog.class);
        t.setColumnTypeMap(config.getContainerFactory().getAttrsMap());
        t.setColumnType("id", java.lang.Integer.class);
        t.setColumnType("title", java.lang.String.class);
        t.setColumnType("content", java.lang.String.class);
        config(config, t);
    }

    private static void config(Config config, Table t) {
       TableMapping.me().putTable(t);
       CPI.addModelToConfigMapping(t.getModelClass(), config);
    }
}

可以看到 以前的 arp.addMapping("blog", "id", Blog.class);  被改为了调用 blog(config);方法
(也可把该代码生成到 BlogBaseModel中去,_MappingKit调用类方法,这个看自己喜好了)

该方法把从数据库查询字段关系类映射到setColumnType,变为了 Java 执行setColumnType 字段与类关系代码。
好处很多,比如启动项目更快了,git代码仓库也有字段记录了,阅读代码更明晰了。。。

PS:https://jfinal.com/app/10057  官网Demo改造的多租户模式代码示例

评论区

JFinal

2024-12-25 14:38

利用生成器,避免了启动时数据库的访问,非常好的创新

aifei 也用了这种方式,启动速度更快了

杜福忠

2024-12-25 15:10

aifei ~ 一飞冲天!

jiren

2024-12-27 09:03

@JFinal 詹总 aifei什么情况了, 有相关介绍否

JFinal

2024-12-27 09:48

@jiren 80% 开发完了,有些功能在打磨

jiren

2024-12-27 10:34

@JFinal 非常非常期待, 搞起搞起

hamy

2025-01-03 16:27

上面提供的模型文件需加上第四步图中的:
t.setColumnTypeMap(config.getContainerFactory().getAttrsMap());
很关键,不加会columnTypeMap未初始化报错。

杜福忠

2025-01-03 17:04

@hamy 👍细心,我当时写完模板,执行生成后就发现掉了一行t.setColumnTypeMap(config.getContainerFactory().getAttrsMap()); 顺手在_MappingKit里加了,并做了项目加载测试。但是忘记加模板里了😄

热门分享

扫码入社