寫這個
OR Mapping
層的初衷是因為一個朋友租了個虛擬主機(jī),并試圖開發(fā)一個小系統(tǒng)來擴(kuò)展自己公司的業(yè)務(wù),但因為虛擬主機(jī)的限制,不能使用他熟悉的
Hibernate
,他有不想寫繁瑣的
JDBC
,于是要我?guī)兔懸粋€簡單的
OR Mapping
層。根據(jù)他的具體要求,我將這個小引擎的目標(biāo)定為:
1.?
在
JDBC API
上建立簡單的包裝。
2.?
優(yōu)化代碼,使資源占用(
CPU, RAM
)盡量少
3.?
不支持事務(wù)處理
4.?
不支持分布式應(yīng)用
5.?
只支持
MySQL
和
ProgressSQL
兩種數(shù)據(jù)庫
6.?
不需要配置文件
7.?
盡量少的第三方包依賴
8.?
實體間關(guān)系只處理一對一和一對多兩種情況,并且只提供延遲加載方式
9.?
內(nèi)置
Connection Pool
?
經(jīng)過三天的努力,基本的功能已經(jīng)實現(xiàn),再經(jīng)過測試后,準(zhǔn)備三月中旬交給朋友用。整個引擎只需要一個
jar
文件,
100k
左右(不需要其它第三方包,當(dāng)然,數(shù)據(jù)庫的
JDBC
驅(qū)動還是需要的
^O^
),使用起來也比較簡單。對于簡單的實體來說,只需要通過注釋指定相對應(yīng)的表和字段就可以了。下面用一個簡單的
Book
對象來說明:
?
首先需要定義一個簡單實體對象,并加入注釋(支持
Java 5
以上環(huán)境)
?
@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
方法省略)
?
?
然后再調(diào)用引擎的相關(guān)新增,修改,刪除方法就來完成數(shù)據(jù)維護(hù)工作,
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.?
基于條件的修改(忽略主鍵,按條件進(jìn)行批量更改)
?
?????? 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.?
基于條件的刪除(忽略主鍵,按條件進(jìn)行批量刪除)
?
?????? 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);
?????? }
?
處理一對一或一對多的實體關(guān)系,需要用到
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
方法省略)
??
???
}
?
除了以上的根據(jù)實體對象來進(jìn)行操作的方法外,也提供不依賴于實體的簡單的
JDBC
包裝方法,這時需要用
DataSet
對象來接受查詢結(jié)果,用
HashMap
來傳遞參數(shù)。例如執(zhí)行一個查詢:
?
??? 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
方法直接執(zhí)行
SQL
語句。
?
接下來,我主要是要完成進(jìn)一步的功能測試和性能測試。但上班后時間可能不是太充裕,我希望能在三月中旬完成,我會在這里繼續(xù)記錄我的測試情況。
posted on 2007-02-25 08:20
Jini 閱讀(1527)
評論(13) 編輯 收藏 所屬分類:
數(shù)據(jù)庫相關(guān)