从我当前学习来看,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);