春节的收获,写了个很简单的OR Mapping层

春节的收获,写了个很简单的OR Mapping层

写这个 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 语句。

 

接下来,我主要是要完成进一步的功能测试和性能测试。但上班后时间可能不是太充裕,我希望能在三月中旬完成,我会在这里继续记录我的测试情况。

你可能感兴趣的:(春节的收获,写了个很简单的OR Mapping层)