dbutils最大的好處是在原始的jdbc和笨重的orm框架,如hibernate和ibatis之間取得了平衡,自己又對orm提供了很方便的支持,於是在小項目中是一個好的選擇。
java
對其中最爲關鍵的handler的使用作一些總結。數組
handler就是對獲取到的ResultSet對象進行處理,轉換成程序中易於使用的array,list,map,bean和beanList等等。也是dbutils方便的緣由所在。框架
BeanHandler:將ResultSet對象的一行轉換爲一個Bean。ide
BeanListHandler:將ResultSet對象轉換爲List<bean>。hibernate
AbstractKeyedHandler:將結果轉換爲Map<K,V>的形式,其中,KeyedHandler是將ResultSet的某一列值轉換爲Key,而後其餘轉換爲Map;BeanMapHandler是將某一列轉換爲Key,而後其餘轉爲一個Bean。debug
AbstractListHandler:將ResultSet轉換爲List對象,其元素爲Bean,Map等等。code
可是實際上的轉換是委託給成員變量RowProcessor來處理的,而RowProcessor又將一部分功能委託給內部的BeanProcessor來實現。
orm
BasicRowProcessor對象
BeanProcessorget
它是如何根據傳入的ResultSet和Class類型,來建立相關的bean並填入參數的呢?咱們看看BeanProcessor.toBean()方法:
比較核心的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進行設置。
當咱們的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,使得屬性沒有設置成功!
ps:get和set方法,儘可能使用IDE自動生成比較好。