使用WebsharpDAO实现O/R Mapping和持久层

转载 2006年06月04日 20:34:00

1.         WebsharpDAO能够做什么

WebsharpDAO封装了对象同数据库之间的交互,可以方便的执行一些常用的数据库和对象交互的任务。
WebsharpDAO是一个非常简单的框架,他的目的不是设计一个如JDO、Hibernate一样的完整的解决方案,而是设计一个可用的方案,能够解决开发过程中的一般问题。他比JDO和Hibernate简单很多,使用也方便很多。在接口设计上,也参考了JDO的标准,或者,可以把他看成一个JDO的一个Mini版本。

可以从以下网址下载全部源代码和示例工程:

http://www.uml.org.cn/opensource/websharp/

 

2.         主要接口

PersistenceManager接口,操纵对象同数据库进行交互的主要接口:

public interface PersistenceManager

{

     void close() throws SQLException;

     boolean isClosed() throws SQLException;

     Transaction currentTransaction();

 

     void persistNewObject(PersistenceCapable pc) throws SQLException;

     void updateObject(PersistenceCapable pc) throws SQLException;

     void deleteObject(PersistenceCapable pc) throws SQLException;

     void reload(PersistenceCapable pc) throws SQLException;

 

     PersistenceCapable findObjectByPrimaryKey(Object id, PersistenceCapable pc) throws SQLException;

 

     Query newQuery();

     Query newQuery(Class entityType);

     Query newQuery(Class entityType, String filter);

     Query newQuery(Class entityType,String filter,ArrayList paramColletion);

 

     Connection getConnection();

}

Transaction接口,操纵事务处理:

public interface Transaction

{

     void begin() throws SQLException;

     void commit() throws SQLException;

     void rollback() throws SQLException;

     PersistenceManager getPersistenceManager();

}

Query接口,查询对象:

public interface Query

{

     Class getEntityType();

     void setEntityType(Class entityType);

     String getFilter();

     void setFilter(String filter);

   

     ArrayList getParameters();

     void setParameters(ArrayList array);

     void addParameter(Object param);

     String getOrdering();

     void setOrdering(String ordering);

     public boolean IgnoreCache=true;

     PersistenceCapable[] queryObject() throws SQLException;

     PersistenceManager getPersistenceManager();

 

     boolean isClosed();

     void close ();

     SqlOperator getSqlOperator();

     void setSqlOperator(SqlOperator conn);

}

 

SqlOperator接口,封装了一些常用的数据库操纵功能:

public interface SqlOperator

{

     ResultSet executeQuery(String sql) throws SQLException;

     ResultSet executeQuery(String sql,ArrayList parameters) throws SQLException;

     RowSet executeRowSet(String sql) throws SQLException;

     RowSet executeRowSet(String sql,ArrayList parameters) throws SQLException;

     int executeUpdate(String sql) throws SQLException;

     int executeUpdate(String sql,ArrayList parameters) throws SQLException;

     void close() throws SQLException;

     boolean isClosed() throws SQLException;

     Connection getConnection();

}

 

PersistenceCapable接口,所有的实体类都必须实现这个接口:

public interface PersistenceCapable

{

     public String[] getFields();   //字段列表

     public String[] getKeyFields();  //关键字

     public String getTableName();   //对应的表名

}

 

 

3.         实体类的编写规范:

a)       为了方便实现,实体类同数据库表是一一对应的。

b)       所有的实体类都必须实现PersistenceCapable接口。例如,Product类可以表示如下:

public class Product implements PersistenceCapable

{

     public Product()

     {

         super();

     }

     public String[] getFields()

     {

         return new

String[]{"ProductID" ,"Name" ,"UnitName" ,"Description" ,"Price" ,"CurrentCount" };

     }

 

public String[] getKeyFields()

     {

         return new String[]{"PRODUCTID"};

     }

     public String getTableName()

     {

         return "Product";

     }

    

     private String productID = "";

     public String getProductID()

     {

         return productID;

     }

     public void setProductID(String productID)

     {

         this.productID = productID;

     }

    

     private String name = "";

     public String getName()

     {

         return name;

     }

     public void setName(String name)

     {

         this.name = name;

     }

    

     private String unitName = "";

     public String getUnitName()

     {

         return unitName;

     }

     public void setUnitName(String unitName)

     {

         this.unitName = unitName;

     }

    

     private String description = "";

     public String getDescription()

     {

         return description;

     }

     public void setDescription(String description)

     {

         this.description = description;

     }

    

     private double price = 0;

     public double getPrice()

     {

         return price;

     }

     public void setPrice(double price)

     {

         this.price = price;

     }

    

     private double currentCount = 0;

     public double getCurrentCount()

     {

         return currentCount;

     }

     public void setCurrentCount(double currentCount)

     {

         this.currentCount = currentCount;

     }

    

}

 

 

c)        属性必须同字段一一对应。例如,有一个ProductName字段,则必须有相应的getset方法,注意getset方法的大小写和getFields()方法中的大小写一致。

 

4.         使用PersistenceManager存取对象

使用PersistenceManager存取对象的过程是:

1)  实例化一个PersistenceManager对象。要实例化一个PersistenceManager对象,请通过PersistenceManagerFactorycreatePersistenceManager方法。下面是一个例子:

PersistenceManager pm = null;

        try

        {

               pm = PersistenceManagerFactory.instance().createPersistenceManager();

               ……;

}

2)  实例化一个实体对象:

Product  p = new Product();

p.ProductID = …….

3)  调用PersistenceManager相应的方法:

pm.persistNewObject(p);

或者:

pm.updateObject(dept);

或者

pm.deleteObject(dept);

4)  关闭PersistenceManager

pm.close();

下面是一个完整的例子:

ProductForm productForm = (ProductForm)form;

Product p = new Product();

p.setProductID(productForm.getProductID());

p.setName(productForm.getName());

p.setUnitName(productForm.getUnitName());

p.setPrice(productForm.getPrice().doubleValue());

p.setCurrentCount(productForm.getCurrentCount().doubleValue());

p.setDescription(productForm.getDescription());

try

{

     PersistenceManager pm = 

                       PersistenceManagerFactory.instance().createPersistenceManager();

     pm.persistNewObject(p);

     pm.close();

}

catch (Exception e)

{

     errors.add("name", new ActionError("id"));

}

 

5.         使用事务处理

事务处理通过Transaction接口来进行。

try

{

     PersistenceManager pm = 

                       PersistenceManagerFactory.instance().createPersistenceManager();

     Transaction trans = pm.currentTransaction();

     trans.begin();

     pm.persistNewObject(p);

     trans.commit();

}

catch (Exception e)

{

     trans.rollback();

}

finally

{

     pm.close();

}

 

6.         进行对象的查询

查询对象可以通过两种方式进行:

1)  根据主关键字查询单个对象

可以通过PersistenceManagerfindObjectByPrimaryKey方法来进行。下面是一个例子:

         DEPT dept = new DEPT();

         PersistenceManager pm = null;

         try

         {

              pm = PersistenceManagerFactory.instance().createPersistenceManager();

              pm.findObjectByPrimaryKey(new Integer(90), dept);

              pm.close();

              System.out.println(dept.getDEPTNO());

              System.out.println(dept.getDNAME());

              System.out.println(dept.getLOC());

         }

         catch (Exception e)

         {

              System.out.println(e.toString());

         }

 

2)  根据条件查询一组对象

可以通过Query接口来完成这个功能。下面是一个例子:

         PersistenceManager pm = null;

         try

         {

              pm = PersistenceManagerFactory.instance().createPersistenceManager();

              Query q = pm.newQuery(DEPT.class);

              q. setFilter(DEPTNO > 10);

              PersistenceCapable[] depts = q.queryObject();

              for(int i=0;i<depts.length;i++)

              {

                   System.out.print(i);

                   System.out.print("/t");

                   System.out.print(((DEPT)depts[i]).getDEPTNO());

                   System.out.print("/t");

                   System.out.print(((DEPT)depts[i]).getDNAME());

                   System.out.print("/t");

                   System.out.println(((DEPT)depts[i]).getLOC());

              }

         }

         catch (Exception e)

         {

              System.out.println(e.toString());

         }

      

7.         数据库连接的获取

有些时候,我们也需要直接使用数据库连接来进行一些对数据库的操作。在一个项目中,应该总是通过ConnectionFactory来获取一个连接。

可以使用如下语句获取一个默认的数据库连接:

Connection conn = ConnectionFactory.getConnection()

也可以通过指明一个DataSource名称来获取一个特定的连接:

Connection conn = ConnectionFactory.getConnection(dataSourceName)

获取连接后,你可以象使用通常的数据库连接一样使用得到的连接。

Connection连接的一些参数,必须在ApplicationResources.properties文件中设置。其格式是:

db_fromdatasource=false                     是否使用DataSource

db_datasourcename=                         DataSource的名称

db_url=jdbc:oracle:thin:@newtest            数据库连接的URL

db_driver=oracle.jdbc.driver.OracleDriver   JDBC驱动程序

db_user=user                                数据库用户名

db_password=pwd                             数据库密码

 

 

8.         SqlOperator的使用

也可以通过ConnectionFactory获取一个SqlOperatorSqlOperator的定义见前面的内容。下面是两种获取的方法:

SqlOperator operator = ConnectionFactory. getSqlOperator()

SqlOperator operator = ConnectionFactory. getSqlOperator(dataSourceName)

下面通过SqlOperator执行一个查询,返回一个ResultSet

String sql = SELECT * FROM Product WHERE Price > ? ;

ArrayList parameters = new ArrayList(1);

parameters.add(100);

SqlOperator operator = ConnectionFactory.getSqlOperator()

ResultSet rst = operator.executeQuery(sql, params);

……

operator.close();

也可以通过SqlOperator返回一个RowSet。返回RowSet的使用方法同ResultSet一样。

RowSetResultSet一样,也是一个数据集,只不过它是可以断开连接,并且可以前后滚动的数据集。当在层之间传输数据集的时候,请尽量使用RowSet,这样,我们就可以在业务逻辑层得到一个数据集,然后马上断开数据库连接,然后把数据集传递到界面层。

关于SqlOperator的其他方法,请参考前面的接口说明。

9.         Tomcat数据库连接池的配置

首先,在项目的web.xml文件中添加一个名为“Websharp/DataSourceName”的环境变量,指明使用的DataSource的名称。格式如下:

<web-app>

……

     <env-entry>

         <env-entry-name>org/websharp/dao/DataSourceName</env-entry-name>

         <env-entry-value>jdbc/newtest</env-entry-value>

         <env-entry-type>java.lang.String</env-entry-type>

     </env-entry>

</web-app>

然后,在TomcatServer.xml文件中添加相应的连接池设置:

<Context docBase="daotest" path="/daotest" reloadable="true" source="com.ibm.etools.webtools.server:daotest">

     <Resource auth="SERVLET" name="jdbc/newtest" type="javax.sql.DataSource"/>

     <ResourceParams name="jdbc/newtest">

         <parameter>

              <name>factory</name>

              <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

         </parameter>

         <parameter><name>username</name><value>scott</value></parameter>

         <parameter><name>password</name><value>tiger</value></parameter>

         <parameter><name>driverClassName</name>

                   <value>oracle.jdbc.driver.OracleDriver</value>

         </parameter>

         <parameter><name>url</name>

                   <value>jdbc:oracle:thin:@newtest </value>

         </parameter>

         <parameter><name>maxActive</name><value>20</value></parameter>

         <parameter><name>maxIdle</name><value>10</value></parameter>

         <parameter><name>maxWait</name><value>-1</value></parameter>

     </ResourceParams>

</Context>

 

进行如上配置后,就可以使用ConnectionFactorygetConnection方法正确的从连接池中获取数据库连接了。

使用WebsharpDAO实现O/R Mapping和持久层

1.         WebsharpDAO能够做什么WebsharpDAO封装了对象同数据库之间的交互,可以方便的执行一些常用的数据库和对象交互的任务。WebsharpDAO是一个非常简单的框架,他...
  • sunny_y_m
  • sunny_y_m
  • 2004年12月23日 12:44
  • 1366

深入理解O/R Mapping

什么是O/R Mapping? 广义上,ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换。 狭义上,ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据...
  • nszkadrgg
  • nszkadrgg
  • 2013年01月06日 09:54
  • 837

小评几种O/R Mapping工具

LLBLGen Pro  满意度: 撞头度:        作为一个商业组件,可以说它是一个令我不知所措的一个工具,它提供的功能超出了我的想象,犹其在易用性上,提供了一个非常漂亮的界面,可以很自由的制...
  • zhiyang202
  • zhiyang202
  • 2005年07月19日 10:43
  • 1033

对O/R Mapping 框架的一点想法

     目前的O/R Mapping框架有很多,如 Hibernate,ibatis,JDO等等。它们无一例外都有一个特点,就是用静态数据类管理数据。例如:一个Order 表,必须为其创建一个Ord...
  • henryqqq
  • henryqqq
  • 2007年09月29日 17:36
  • 526

优秀的O-R Mapping工具--TOPLink使用简介

 TopLink 是位居第一的 Java 对象关系可持续性体系结构,原署WebGain公司的产品,现在被Oracle收购,并重新包装为 Oracle AS TopLink。TOPLink为在关系数据库...
  • zaowei21
  • zaowei21
  • 2004年12月25日 14:35
  • 1649

C# 之 O/R Mapping 对象关系

 在我们的系统中,存在大量的需要进行持久化存储的对象,这些对象可能是各种各样的业务单据,也可能是我们的系统配置信息等。另外一些属于内存中使用而不需要进行持久化存储的对象,不属于我们的讨论范围。而在支持...
  • lwslws
  • lwslws
  • 2008年09月12日 07:29
  • 795

我的 O/R Mapping 之旅(一)

    首先要感谢我所在的 Team 意识到了传统 JDBC 开发的种种不足,转而开始关注 O/R Mapping 领域的成果。说到 O/R Mapping,我认为在对象数据库还没有真正成熟的时候它是...
  • rosen
  • rosen
  • 2004年11月12日 23:30
  • 7122

O/R Mapping与数据模型

说实话,我以前从没考虑这两者之间的关系,只是最近工作当中屡次遇到对这两者误用导致的问题,促使我思考这些问题,我遇到的问题有:1.DBA在建立数据模型时,为了在编码时方便,频繁地在一些进行数据冗余(在项...
  • wangjian5748
  • wangjian5748
  • 2006年04月19日 17:57
  • 866

过程模式之O/R映射映射

       对象方式的基础是用具有数据和行为的对象来构建应用;关系方式的基础是将数据存储在表的行中。在将对象用关系数据库存储时,自然存在对象/关系阻抗不匹配。它们的本质区别使得这两种方式结合的并不完...
  • huankfy
  • huankfy
  • 2007年07月16日 23:08
  • 1625

O/R Mapping性能

我不知道为什么你这么怀疑O/R Mapping的性能,O/R Mapping的性能再差也比CMP强吧。JDO只是一个标准,每个厂商实现的性能各有不同,不好评价。Apache OJB的性能如何,Apac...
  • chensheng913
  • chensheng913
  • 2005年02月02日 16:09
  • 6196
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用WebsharpDAO实现O/R Mapping和持久层
举报原因:
原因补充:

(最多只允许输入30个字)