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写法差不多,就不用分享例子代码了~
到这里就结束了!!! 老项目有用得到的话,点个赞呗~ 当然不一定是因为老项目才这样用,高版本有时候想扩展点东西的话,也可以这样用对吧!

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