小酒一杯品源码-DbUtils代码解读
来源:互联网 发布:js输入框输入数据事件 编辑:程序博客网 时间:2024/04/28 02:04
ORM一直是Web开发一个热点话题,DbUtils则是给出了一个相当简洁的答案。DbUtils的嵌套也不深,而且主动的API调用也非常符合程序员的思维(Hibernate和iBatis这种隐藏了大多数细节的框架,连找到个入口都要费半天劲)。
话说最常用的CRUD,使用JDBC最痛的无非是将ResultSet转换为JavaBean。DbUtils则是正好命中这个要害,使用ResultSetHandler
机制来解决这个问题。
之前用过Spring JDBC Template,差不多也是这个机制。DbUtils
的亮点则是BeanHandler
,可以无需手写转换函数,自动根据class生成一个handler。
BeanProcessor
的核心代码做了几件事:
提取Bean的字段信息,结果集的字段信息,并作映射;
对Bean的字段做类型转换
字段映射的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 <= cols; col++) {
String columnName = rsmd.getColumnLabel(col);
if
(
null
== columnName ||
0
== columnName.length()) {
columnName = rsmd.getColumnName(col);
}
String propertyName = columnToPropertyOverrides.get(columnName);
if
(propertyName ==
null
) {
propertyName = columnName;
}
for
(
int
i =
0
; i < props.length; i++) {
if
(propertyName.equalsIgnoreCase(props[i].getName())) {
columnToProperty[col] = i;
break
;
}
}
}
return
columnToProperty;
}
这里ResultSetMetaData
和PropertyDescriptor
分别是JDBC和Bean API里获取的元信息。
对字段做类型转换的代码比较多,主要方法是callSetter
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private
void
callSetter(Object target, PropertyDescriptor prop, Object value)
throws
SQLException {
Method setter = prop.getWriteMethod();
if
(setter ==
null
) {
return
;
}
Class<?>[] params = setter.getParameterTypes();
// convert types for some popular ones
if
(value
instanceof
java.util.Date) {
final
String targetType = params[
0
].getName();
if
(
"java.sql.Date"
.equals(targetType)) {
value =
new
java.sql.Date(((java.util.Date) value).getTime());
}
else
if
(
"java.sql.Time"
.equals(targetType)) {
value =
new
java.sql.Time(((java.util.Date) value).getTime());
}
else
if
(
"java.sql.Timestamp"
.equals(targetType)) {
value =
new
java.sql.Timestamp(((java.util.Date) value).getTime());
}
}
// Don't call setter if the value object isn't the right type
if
(
this
.isCompatibleType(value, params[
0
])) {
setter.invoke(target,
new
Object[]{value});
}
else
{
throw
new
SQLException(
"Cannot set "
+ prop.getName() +
": incompatible types, cannot convert "
+ value.getClass().getName() +
" to "
+ params[
0
].getName());
// value cannot be null here because isCompatibleType allows null
}
}
这里省略了一些异常的捕获。this.isCompatibleType
方法里有一些关于基本类型和装箱类型的转换。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private
boolean
isCompatibleType(Object value, Class<?> type) {
// Do object check first, then primitives
if
(value ==
null
|| type.isInstance(value)) {
return
true
;
}
else
if
(type.equals(Integer.TYPE) && value
instanceof
Integer) {
return
true
;
}
else
if
(type.equals(Long.TYPE) && value
instanceof
Long) {
return
true
;
}
else
if
(type.equals(Double.TYPE) && value
instanceof
Double) {
return
true
;
}
else
if
(type.equals(Float.TYPE) && value
instanceof
Float) {
return
true
;
}
else
if
(type.equals(Short.TYPE) && value
instanceof
Short) {
return
true
;
}
else
if
(type.equals(Byte.TYPE) && value
instanceof
Byte) {
return
true
;
}
else
if
(type.equals(Character.TYPE) && value
instanceof
Character) {
return
true
;
}
else
if
(type.equals(Boolean.TYPE) && value
instanceof
Boolean) {
return
true
;
}
return
false
;
}
至此,一个ResultSet至Bean的转换就完成了,还是相当简洁的。
0 0
- 小酒一杯品源码-DbUtils代码解读
- 小程序之豆瓣电影源码解读
- 劝叔更尽一杯酒
- DBUtils源码分析
- DbUtils源码解析
- commons-dbutils源码学习
- 一杯红酒配代码的异步思考
- 关于DBUtils中QueryRunner的一些解读.
- 关于DBUtils中QueryRunner的一些解读
- 关于DBUtils中QueryRunner的一些解读
- 一杯清茶!细品人生!
- UniversalImageLoader源码解读03-一些无关紧要的小类
- Commons DbUtils源码阅读五
- Commons DbUtils源码阅读三
- Commons DbUtils源码阅读二
- Commons DbUtils源码阅读一
- dbutils源码的基本结构
- 源码解读
- Leetcode Find Peak Element
- python计算时间间隔(精确到微妙)
- 搭建GCM项目——服务端和客户端(三)
- ftp脚本 实现非交互模式上传文件
- Python基础04
- 小酒一杯品源码-DbUtils代码解读
- 获得堆栈增长方向的一种方法
- Java DES 加密和解密源码
- MS SQL 2005 连接 sybase ASA 数据库远程链接问题
- 任意n张图像拼接_效果很好_计算机视觉大作业1终版
- c#利用office组件导出
- 三种方法求连续子数组的最大和
- Android Studio 1.0.1 + Genymotion安卓模拟器打造高效安卓开发环境
- Android高效加载大图、多图解决方案,有效避免程序OOM