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