JFinal使用技巧-V3.4版本扩展增强Record内部方法

RT,需求背景:有老项目扩展一点功能,老项目使用的JDK7,并且由于内部代码写法的问题,升级JDK8有问题,比如各种object强转数组类型异常之类的问题写法,并且这样的写法有点多,改造起来人力成本和稳定性都不能接受。
对于新版本JFInal用惯了Record.getXX系列,自动转换类型这个功能,再回到以前的写法。老报错,这个是不能忍受的。
那么咱们来扩展一下内部升级一下就OK了, 享受新版本的各种便利,有不用担心项目的稳定性! 话 不 多 说 了, 上 石马  ~

首先自建一个MyRecord 覆盖想要升级的方法即可:

package com.momathink.common.config.activerecord;

import com.jfinal.plugin.activerecord.Record;

import java.math.BigDecimal;

public class MyRecord extends Record {

    @Override
    public BigDecimal getBigDecimal(String column){
        Object n = getColumns().get(column);
        if (n instanceof BigDecimal) {
            return (BigDecimal)n;
        } else if (n != null) {
            return new BigDecimal(n.toString());
        } else {
            return BigDecimal.ZERO;
        }
    }
    //其他方法代码此处省略可自行复制:https://gitee.com/jfinal/jfinal/blob/master/src/main/java/com/jfinal/plugin/activerecord/Record.java

}

 然后再建一个 MyRecordBuilder 里面new MyRecord()即可:

package com.momathink.common.config.activerecord;

import com.jfinal.plugin.activerecord.*;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MyRecordBuilder extends RecordBuilder {
    public List<Record> build(Config config, ResultSet rs) throws SQLException {
        List<Record> result = new ArrayList<Record>();
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        String[] labelNames = new String[columnCount + 1];
        int[] types = new int[columnCount + 1];
        buildLabelNamesAndTypes(rsmd, labelNames, types);
        while (rs.next()) {
            Record record = new MyRecord();
            CPI.setColumnsMap(record, config.getContainerFactory().getColumnsMap());
            Map<String, Object> columns = record.getColumns();
            for (int i=1; i<=columnCount; i++) {
                Object value;
                if (types[i] < Types.BLOB) {
                    value = rs.getObject(i);
                } else {
                    if (types[i] == Types.CLOB) {
                        value = ModelBuilder.me.handleClob(rs.getClob(i));
                    } else if (types[i] == Types.NCLOB) {
                        value = ModelBuilder.me.handleClob(rs.getNClob(i));
                    } else if (types[i] == Types.BLOB) {
                        value = ModelBuilder.me.handleBlob(rs.getBlob(i));
                    } else {
                        value = rs.getObject(i);
                    }
                }

                columns.put(labelNames[i], value);
            }
            result.add(record);
        }
        return result;
    }


}

再ActiveRecordPlugin中注册一下即可:

ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);

MysqlDialect dialect = new MysqlDialect();
dialect.setRecordBuilder(new MyRecordBuilder());

arp.setDialect(dialect);


到这里就结束了!

再补充一点其他的知识点:

Db查询的时候,数据库类型自动转换,这个也是高版本JFInal的便利,低版本是没有的,顺便扩展一下:
也先自建一个 MyDbPro

package com.momathink.common.config.activerecord;


import com.jfinal.plugin.activerecord.DbPro;

import java.math.BigDecimal;

public class MyDbPro extends DbPro {
    static final Object[] NULL_PARA_ARRAY = new Object[0];

    public MyDbPro(String configName) {
        super(configName);
    }

    @Override
    public java.math.BigDecimal queryBigDecimal(String sql, Object... paras) {
        Object n = queryColumn(sql, paras);
        if (n instanceof BigDecimal) {
            return (BigDecimal) n;
        } else if (n != null) {
            return new BigDecimal(n.toString());
        } else {
            return BigDecimal.ZERO;
        }
    }

    @Override
    public java.math.BigDecimal queryBigDecimal(String sql) {
        Object n = queryColumn(sql, NULL_PARA_ARRAY);
        if (n instanceof BigDecimal) {
            return (BigDecimal) n;
        } else if (n != null) {
            return new BigDecimal(n.toString());
        } else {
            return BigDecimal.ZERO;
        }
    }
}

再建一个MyDbProFactory

package com.momathink.common.config.activerecord;

import com.jfinal.plugin.activerecord.DbPro;
import com.jfinal.plugin.activerecord.IDbProFactory;

public class MyDbProFactory implements IDbProFactory {
    public DbPro getDbPro(String configName) {
        return new MyDbPro(configName);
    }
}

再ActiveRecordPlugin中注册一下即可:

ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
arp.setDbProFactory(new MyDbProFactory());

到这里就结束了!

Model ? 我们有BaseModel层,所以直接覆盖就可以了, 和MyRecord写法差不多,就不用分享例子代码了~

到这里就结束了!!! 老项目有用得到的话,点个赞呗~ 当然不一定是因为老项目才这样用,高版本有时候想扩展点东西的话,也可以这样用对吧!

评论区

JFinal

2021-04-06 16:48

通过 RecordBuilder 来定制 Record 这个以前从来没人想到过,我自己也一直以为只能扩展 Model

这招太美妙了,非常实用的创新,不得不赞 👍👍👍

chcode

2021-04-06 17:39

这个扩展厉害了

杜福忠

2021-04-06 18:11

@JFinal @chcode 👍 还是得益JFInal的灵活DIY 筒约而不简单~

jiren

2021-04-06 18:56

我是来看图的

zzutligang

2021-04-06 23:52

赞一个!

小徐同学

2021-04-07 08:46

l745230

2021-04-07 10:59

老项目的受难者,还好我已经脱离苦海,紧跟最新版的步伐 ^_^

杜福忠

2021-04-07 11:24

@l745230 👍对,自有产品项目必须紧跟新版本迭代,并且还要做到推动JF未来发展才会正循环!

zeroabc

2021-04-07 15:41

喵啊

要输就输给追求

2021-04-08 08:44

点赞加收藏了这😁