dbutils源之handler学习(一)

dbutils最大的好处是在原始的jdbc和笨重的orm框架,如hibernate和ibatis之间取得了平衡,本身又对orm提供了很方便的支持,因而在小项目中是一个好的选择。

对其中最为关键的handler的使用做一些总结。

handler就是对获取到的ResultSet对象进行处理,转换成程序中易于使用的array,list,map,bean和beanList等等。也是dbutils方便的原因所在。

dbutils源之handler学习(一)_第1张图片


BeanHandler:将ResultSet对象的一行转换为一个Bean。

BeanListHandler:将ResultSet对象转换为List<bean>。

AbstractKeyedHandler:将结果转换为Map<K,V>的形式,其中,KeyedHandler是将ResultSet的某一列值转换为Key,然后其他转换为Map;BeanMapHandler是将某一列转换为Key,然后其他转为一个Bean。

AbstractListHandler:将ResultSet转换为List对象,其元素为Bean,Map等等。

但是实际上的转换是委托给成员变量RowProcessor来处理的,而RowProcessor又将一部分功能委托给内部的BeanProcessor来实现。


BasicRowProcessor

BeanProcessor

它是如何根据传入的ResultSet和Class类型,来创建相关的bean并填入参数的呢?我们看看BeanProcessor.toBean()方法:

dbutils源之handler学习(一)_第2张图片

比较核心的mapColumnsToProperties(rsmd,props),它返回一个数组[1..N],数组中的的值是第i列对应在props[]数组中的下标,也就是建立column[i]和props[i]的映射关系。新建bean时,将会把column[i]的值,存储在bean的props[i]对应的属性中。

要注意,对应的那个properName先是从columToPropertyOverrides这个map中获取,如果获取为NULL,就用该列的name当作bean的property name取查找相关的property进行设置。

dbutils源之handler学习(一)_第3张图片

当我们的bean的属性值和column对应列的名称不一样的时候,就可以借助这其中关系来完成映射。

如User对象有(id,myName,myPasswd)

而相应的table为user(user_id, my_name, my_password),这个时候可以实现相关的DO对象,如UserDOProcessor。

可以这样做:

public class UserDOProcessor extends BeanProcessor{
	private BeanProcessor beanProcessor;
	public UserDOProcessor(){
		Map<String, String> columnToPropertyMap = new HashMap<String, String>();
//		key为column name,value为property name
		columnToPropertyMap.put("user_id", "id");
		columnToPropertyMap.put("my_username", "myUsername");
		columnToPropertyMap.put("my_password", "myPassword");
		
		beanProcessor = new BeanProcessor(columnToPropertyMap);
	}
	
	@Override
	public <T> List<T> toBeanList(ResultSet rs, Class<T> type) throws SQLException {
		return beanProcessor.toBeanList(rs, type);
	}
	
	@Override
	public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException {
		return beanProcessor.toBean(rs, type);
	}
}

在最近的一次使用中,发现一个奇怪的bug,开始百思不得其解:根据查询条件,可以查询到相应数量的元组,但是发现bean有的属性为null,有的不为null,感觉很奇怪。

说明column to property的转换并没有完成。然后一路debug下去,发现了原因:设置property的时候,会去寻找合适的set方法进行设置,并没有直接用反射去设置。这样导致,如果没有相关的set方法,将无法正确设置!而我由于使用了链式API,使得属性没有设置成功!

dbutils源之handler学习(一)_第4张图片

ps:get和set方法,尽量使用IDE自动生成比较好。

你可能感兴趣的:(DbUtils)