从我当前学习来看,IContainerFactory 主要定义Model和Record类对象中, 存储数据映射字段键值的数据类型。本次笔记记录下相关代码。提供的默认实现和三个实现类,如下:
1、默认为HashMap,
static final IContainerFactory defaultContainerFactory = new IContainerFactory() { public Map<String, Object> getAttrsMap() { return new HashMap<String, Object>(); } public Map<String, Object> getColumnsMap() { return new HashMap<String, Object>(); } }
2、OrderedFieldContainerFactory,使用LinkedHashMap,达到查询返回字段和select语句中字段顺序一致。
public Map<String, Object> getAttrsMap() { return new LinkedHashMap(); } public Map<String, Object> getColumnsMap() { return new LinkedHashMap(); }
3、DaoContainerFactory,自定义了DaoMap,在所有get和put等操作数据的方法中,都抛出了异常,达到某一Model和Record只读的效果。
public static final Map<String, Object> daoMap = new DaoMap<Object>(); public static final Set<String> daoSet = new DaoSet(); private DaoContainerFactory() { } public Map<String, Object> getAttrsMap() { return daoMap; } public Map<String, Object> getColumnsMap() { return daoMap; } public static class DaoMap<V> implements Map<String, V> { public V put(String key, V value) { throw new RuntimeException("dao 只允许调用查询方法"); } public V get(Object key) { throw new RuntimeException("dao 只允许调用查询方法"); } }
需要注意的是,DaoContainerFactory不支持被外部调用,仅用于Model的dao()方法
public M dao() { attrs = DaoContainerFactory.daoMap; modifyFlag = DaoContainerFactory.daoSet; return (M)this; }
4、CaseInsensitiveContainerFactory 中的 CaseInsensitiveMap 实现的TreeMap,在对Model对象进行add时,通过convertCase方法对key进行大小写转换,达到key统一大小写的效果。
public CaseInsensitiveContainerFactory() { } public CaseInsensitiveContainerFactory(boolean toLowerCase) { this.toLowerCase = toLowerCase; } public Map<String, Object> getAttrsMap() { return new CaseInsensitiveMap<Object>(); } public Map<String, Object> getColumnsMap() { return new CaseInsensitiveMap<Object>(); } private String convertCase(String key) { if (toLowerCase != null) { return toLowerCase ? key.toLowerCase() : key.toUpperCase(); } else { return key; } }
类方法实现源码如上述,具体运用如:
我们在JFinalConfig的插件配置模块配置 ActiveRecordPlugin 时 setContainerFactory方法即可
public void configPlugin(Plugins me) { DruidPlugin druidPlugin = ... ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin); // arp.setContainerFactory(new CaseInsensitiveContainerFactory()); // arp.setContainerFactory(new OrderedFieldContainerFactory()); }
具体作用的过程是这样的
1、Model对象创建时候,申明了attrs
private Map<String, Object> attrs = createAttrsMap(); private Map<String, Object> createAttrsMap() { Config config = _getConfig(); if (config == null) { return DbKit.brokenConfig.containerFactory.getAttrsMap(); } return config.containerFactory.getAttrsMap(); }
2、写入的时候就是
attrs.put(key, value)
3、查询时候,主要体现在ModelBuild的实现类
Model<?> ar = modelClass.newInstance(); Map<String, Object> attrs = CPI.getAttrs(ar); for (int i=1; i<=columnCount; i++) { Object value; int t = types[i]; if (t < Types.DATE) { if (t == Types.TINYINT) { value = BuilderKit.getByte(rs, i); } else if (t == Types.SMALLINT) { value = BuilderKit.getShort(rs, i); } else { value = rs.getObject(i); } } else { if (t == Types.TIMESTAMP) { value = rs.getTimestamp(i); } else if (t == Types.DATE) { value = rs.getDate(i); } else if (t == Types.CLOB) { value = handleClob(rs.getClob(i)); } else if (t == Types.NCLOB) { value = handleClob(rs.getNClob(i)); } else if (t == Types.BLOB) { value = handleBlob(rs.getBlob(i)); } else { value = rs.getObject(i); } } attrs.put(labelNames[i], value);