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字段,则必须有相应的get和set方法,注意get和set方法的大小写和getFields()方法中的大小写一致。 
  
4.         使用PersistenceManager存取对象 
使用PersistenceManager存取对象的过程是: 
1)  实例化一个PersistenceManager对象。要实例化一个PersistenceManager对象,请通过PersistenceManagerFactory的createPersistenceManager方法。下面是一个例子: 
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)  根据主关键字查询单个对象 
可以通过PersistenceManager的findObjectByPrimaryKey方法来进行。下面是一个例子: 
| 
          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获取一个SqlOperator。SqlOperator的定义见前面的内容。下面是两种获取的方法: 
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一样。 
RowSet同ResultSet一样,也是一个数据集,只不过它是可以断开连接,并且可以前后滚动的数据集。当在层之间传输数据集的时候,请尽量使用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>  |   
然后,在Tomcat的Server.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>  |   
  
进行如上配置后,就可以使用ConnectionFactory的getConnection方法正确的从连接池中获取数据库连接了。  
 
  |