随笔-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 阅读(1511) 评论(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 谢了  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: