写这个
OR Mapping
层的初衷是因为一个朋友租了个虚拟主机,并试图开发一个小系统来扩展自己公司的业务,但因为虚拟主机的限制,不能使用他熟悉的
Hibernate
,他有不想写繁琐的
JDBC
,于是要我帮忙写一个简单的
OR Mapping
层。根据他的具体要求,我将这个小引擎的目标定为:
1.
在
JDBC API
上建立简单的包装。
2.
优化代码,使资源占用(
CPU, RAM
)尽量少
3.
不支持事务处理
4.
不支持分布式应用
5.
只支持
MySQL
和
ProgressSQL
两种数据库
6.
不需要配置文件
7.
尽量少的第三方包依赖
8.
实体间关系只处理一对一和一对多两种情况,并且只提供延迟加载方式
9.
内置
Connection Pool
经过三天的努力,基本的功能已经实现,再经过测试后,准备三月中旬交给朋友用。整个引擎只需要一个
jar
文件,
100k
左右(不需要其它第三方包,当然,数据库的
JDBC
驱动还是需要的
^O^
),使用起来也比较简单。对于简单的实体来说,只需要通过注释指定相对应的表和字段就可以了。下面用一个简单的
Book
对象来说明:
首先需要定义一个简单实体对象,并加入注释(支持
Java 5
以上环境)
@DBTable
(name=
"Books"
)
public
class
Book {
@DBColumn
(name=
"id"
,type=
"String"
,isKey=
true
)
private
String
id
;
@DBColumn
(name=
"name"
,type=
"String"
)
private
String
name
;
@DBColumn
(name=
"isdn"
,type=
"String"
)
private
String
isdn
;
@DBColumn
(name=
"price"
, type=
"float"
)
private
float
price
;
public
String getId() {
return
id
;
}
public
void
setId(String id) {
this
.
id
= id;
}
......
(其它的
get, set
方法省略)
然后再调用引擎的相关新增,修改,删除方法就来完成数据维护工作,
1.
新增
DALEngine engine =
new
DALEngine();
Book b =
new
Book();
b.setId(
"123456789"
);
b.setName(
"Think in Java 3 Edition"
);
b.setIsdn(
"123-4567-89"
);
b.setPrice(60.5f);
try
{
engine.create(b);
}
catch
(DALException e) {
log.error(e);
}
}
2.
基于主键的修改
try
{
engine.update(b);
}
catch
(DALException e) {
log.error(e);
}
3.
基于条件的修改(忽略主键,按条件进行批量更改)
HashMap params =
new
HashMap();
params.put(
"price"
, 20f);
try
{
engine.update(b, params,
"WHERE price > ?"
);
}
catch
(DALException e) {
log.error(e);
}
4.
基于主键的删除
try
{
engine.delete(b);
}
catch
(DALException e) {
log.error(e);
}
5.
基于条件的删除(忽略主键,按条件进行批量删除)
HashMap params =
new
HashMap();
params.put(
"price"
, 20f);
try
{
engine.delete(b.getClass(), params,
"WHERE price > ?"
);
}
catch
(DALException e) {
log.error(e);
}
6.
基于主键的查询
Book b =
null
;
HashMap pks =
new
HashMap();
pks.put(
"id"
,
"123456789"
);
try
{
b = engine.get(Book.
class
, pks);
}
catch
(DALException e) {
log.error(e);
}
7.
基于指定条件的查询
Collection<Book> books =
null
;
HashMap params =
new
HashMap();
params.put(
"price"
, 20f);
try
{
books = engine.get(Book.
class
, params,
"WHERE price > ?"
);
}
catch
(DALException e) {
log.error(e);
}
处理一对一或一对多的实体关系,需要用到
One2One
或
One2Many
注释,比如处理
Order
和
OrderDetail
,需要这样定义实体
@DBTable
(name=
"Orders"
)
public
class
Order {
@DBColumn
(name=
"id"
,type=
"String"
,isKey=
true
)
private
String
id
;
@
One2Many(type=
"test.OrderDetail"
column=
"orderId"
cause=
"id"
)
private
Collection
details
;
......(
其它属性
)
pub
lic
Collection getDetails() {
r
eturn
details
;
}
public
void
setDetails(Collection details) {
this
.
details
= details;
}
public
String getId() {
return
id
;
}
public
void
setId(
String
id) {
this
.
id
= id;
}
......
(其它的
get, set
方法省略)
}
@DBTable
(name=
"OrderDetails"
)
public
class
OrderDetail {
@DBColumn
(name=
"id"
,type=
"String"
,isKey=
true
)
private
String
id
;
@
Many2One(name=
"orderId"
,type=
"test.Order"
)
private
Order
order
;
......(
其它属性
)
public
String getId() {
return
id
;
}
public
void
setId(String id) {
this
.
id
= id;
}
public
Order getOrder() {
return
order
;
}
public
void
setOrder(Order order) {
this
.
order
= order;
}
......
(其它的
get, set
方法省略)
}
除了以上的根据实体对象来进行操作的方法外,也提供不依赖于实体的简单的
JDBC
包装方法,这时需要用
DataSet
对象来接受查询结果,用
HashMap
来传递参数。例如执行一个查询:
DataSet dataSet =
null
;
HashMap params =
new
HashMap();
params.put(
"O.Operator"
,
"Tom"
);
try
{
dataSet = engine.select(
"SELECT O.ID, O.Operator, O.DeliveryDate, "
+
"D.ProductId FROM Orders O, OrderDetails D "
+
"WHERE O.id = D.orderId and O.Operator = ?"
, params);
}
catch
(DALException e) {
log.error(e);
}
同样,可以用
DALEngine
的
insert, update, delete
方法直接执行
SQL
语句。
接下来,我主要是要完成进一步的功能测试和性能测试。但上班后时间可能不是太充裕,我希望能在三月中旬完成,我会在这里继续记录我的测试情况。
posted on 2007-02-25 08:20
Jini 阅读(1522)
评论(13) 编辑 收藏 所属分类:
数据库相关