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