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方法正确的从连接池中获取数据库连接了。