隨筆-8  評論-39  文章-0  trackbacks-0

          寫這個 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 閱讀(1529) 評論(13)  編輯  收藏 所屬分類: 數據庫相關

          評論:
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-25 09:45 | alysa
          收藏先~  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-25 13:34 | BeanSoft
          呵呵, 哥們也很勤奮啊!  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-25 14:30 | 不好說
          寫得是真的太丑陋了!而且是極其惡心!  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層[未登錄] 2007-02-25 14:45 | jini
          @不好說

          呵呵,能說得具體一點嗎?怎么丑陋,哪里惡心啦?  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-25 16:32 | zhyiwww
          思路值得借鑒  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-25 16:33 | zhyiwww
          @jini
          :)  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層[未登錄] 2007-02-25 16:51 | jini
          @zhyiwww

          謝謝!相互學習,共同進步!  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-25 17:24 | bean
          我前些天也寫了個差不多的
          最近懶了,沒繼續寫。  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層[未登錄] 2007-02-25 17:39 | jini
          @bean

          我也是被朋友威逼利誘才放棄假期寫的,估計過幾天交完差也就不管了,呵呵...  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-27 15:32 | 肖林
          思路不錯!  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-02-27 21:52 | Jini
          @肖林

          謝謝鼓勵 :)  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-03-13 11:46 | xfans
          能公布代碼么  回復  更多評論
            
          # re: 春節的收獲,寫了個很簡單的OR Mapping層 2007-03-13 11:49 | xfans
          想學習下相關的知識,能把代碼發給我,讓我學習下么?
          xfans12000◎163。com 謝了  回復  更多評論
            
          主站蜘蛛池模板: 鹤庆县| 景泰县| 永嘉县| 安阳县| 贵德县| 肇东市| 宁化县| 滕州市| 丁青县| 十堰市| 盐源县| 广水市| 全州县| 沂南县| 阿巴嘎旗| 门源| 天柱县| 建平县| 沙坪坝区| 宣城市| 定边县| 绥棱县| 揭东县| 兴和县| 桐柏县| 宁夏| 岗巴县| 樟树市| 宁远县| 南投县| 泗阳县| 钟祥市| 邵阳市| 施甸县| 揭东县| 双桥区| 阳西县| 溧水县| 卢龙县| 谢通门县| 中卫市|