设为首页 收藏本站
查看: 554|回复: 0

[经验分享] Apache Common DBUtils源码研究(1)

[复制链接]

尚未签到

发表于 2017-1-7 10:36:21 | 显示全部楼层 |阅读模式
  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()));

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-325013-1-1.html 上篇帖子: OpenCMS 文件上传 Apache Jakarta Commons-FileUpload 下篇帖子: 如何导入apache DS的数据
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表