BeanListHandler


BeanListHandler 是可供DBUtils查詢器使用的一個Handler類,它的作用是將查詢結果轉換為一個列表。列表中元素為查詢結果所轉換的JavaBean,Bean的類型為開發者所指定的Class。參考如下這段代碼:

 

public Template[] list(Connection conn, String owner, String catagory) {
        String sql;
        QueryRunner runner = new QueryRunner();
        BeanListHandler<Template> handler = new BeanListHandler<Template>(Template.class);
        sql = "SELECT * FROM GEN_TEMPLATE WHERE OWNER = ? AND CATAGORY = ?";
        try {
                List<Template> aList = runner.query(conn, sql, handler, new Object[] { owner, catagory });
                return aList.toArray(new Template[0]);
        } catch (Exception ex) {
                throw new GenException(ex, "读���模��表�����常�");
        }
}

 

 

  查詢結果每一行都會自動轉換為Template類的實例,並且裝進List作為結果返回。缺省的查詢字段與JavaBean的屬性匹配規則是忽略大小寫后的字符完全匹配。

  通常,數據庫的字段往往會出現2個單詞以上的情況,比如TEMPLATE_ID這個字段名,以下划線作為分隔。對應的JavaBean的屬性名,按照Java的命名規范(駝峰原則),則是templateId。這種情況下,BeanListHandler就無法做TEMPLATE_ID->templateId的映射了。對於這樣的問題,有一種解決辦法就是給查詢結果的顯示字段取別名,如TEMPLATE_ID AS templateId。在字段較少的情況下,這個辦法可以作為權益之計。但是,字段較多的時候,這種辦法就顯得很笨拙了。

  另外一種想法,就是BeanListHandler能夠做TEMPLATE_ID->templateId的映射。

  那么如何使BeanListHandler按照我們的要求做映射呢?打開DBUtils的源代碼,來看下它的內在處理機制。

  BeanListHandler通過handle方法處理查詢結果ResultSet的實例,並返回最終的List實例。handle方法使用RowProcessor作為ResultSet->BeanList的轉換器,調用它的toBeanList方法完成轉換。缺省情況下,BeanListHandler所使用的RowProcessor為ArrayHandler的缺省RowProcessor,其類型是BasicRowProcessor。缺省情況下,BasicRowProcessor使用BeanProcessor作為轉換器,調用它的toBeanList方法。

  總結一下調用次序:

BeanListHandler.handle->BasicRowProcessor.toBeanList->BeanProcessor.toBeanList

 

  原來BeanProcessor.toBeanList是完成這個轉換的關鍵,映射規則的處理機制就藏在這里。

  BeanProcessor.toBeanList的實現機理,大致是以下幾個步驟

1. 循環處理ResultSet每一行記錄
 1.1 得到JavaBean的屬性集合
 1.2 得到ResultSet的元數據集合
 1.3 調用mapColumnsToProperties方法,得到以上2者的映射關系索引集
 1.4 創建JavaBean的實例,並根據1.3得到的索引集,完成行的值到JavaBean屬性的注入

 

  至此我們了解了整個轉換過程,解決方案也相應而生。以BeanProcessor作為父類,實現一個自定義的BeanProcessor子類,並使用自定義的mapColumnsToProperties方法覆蓋父類的方法。代碼如下:

import java.beans.PropertyDescriptor;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Arrays;

import org.apache.commons.dbutils.BeanProcessor;

/**
 * æ�©å±�BeanProcessorç��å¤�ç��æ�¹å¼�ï¼�使å�¶è�½å¤�å¤�ç��å¦�DATA_OBJECT_NAME -> dataObjectNameè¿�æ ·ç��æ� å°�å�³ç³»

 */
public class GenBeanProcess extends BeanProcessor {
        /**
         * æ�¿æ�¢BeanProcessorç��æ� å°�å�³ç³»å¤�ç��
         */
        @Override
        protected int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throws SQLException {
                int cols = rsmd.getColumnCount();
                int[] columnToProperty = new int[cols + 1];
                Arrays.fill(columnToProperty, PROPERTY_NOT_FOUND);
                for (int col = 1; col &lt;= cols; col++) {
                        String columnName = rsmd.getColumnLabel(col);
                        if (null == columnName || 0 == columnName.length()) {
                                columnName = rsmd.getColumnName(col);
                        }
                        for (int i = 0; i &lt; props.length; i++) {
                                if (convert(columnName).equals(props[i].getName())) {
                                        columnToProperty[col] = i;
                                        break;
                                }
                        }
                }
                return columnToProperty;
        }

        /**
         * DATA_OBJECT_NAME -> dataObjectName
         */
        private String convert(String objName) {
                StringBuilder result = new StringBuilder();
                String[] tokens = objName.split("_");
                for (String token : tokens) {
                        if (result.length() == 0)
                                result.append(token.toLowerCase());
                        else
                                result.append(StringUtils.capitalize(token.toLowerCase()));
                }
                return result.toString();
        }
}



 
// å��å°�å¼�å¤´æ ·ä¾�中ç��è¿�å�¥
BeanListHandler<Template> handler = new BeanListHandler<Template>(Template.class);
// ��为
BeanListHandler<Sql> handler = new BeanListHandler<Sql>(Template.class, new BasicRowProcessor(new GenBeanProcess()));

 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM