13.5.Apache OJB

优质
小牛编辑
129浏览
2023-12-01

13.5. Apache OJB

Apache OJB (http://db.apache.org/ojb) 提供了不同的API级别,例如ODMG和JDO。 除了通过JDO支持OJB,Spring同样为OJB的低层次的 PersistenceBroker API作为数据访问提供支持。 相应的整合与支持的类位于 org.springframework.orm.ojb 包中。

13.5.1. 在Spring环境中建立OJB

与Hibernate或者JDO相比,OJB并没有使用工厂模式进行资源管理,PersistenceBroker 必须通过从一个静态的 PersistenceBrokerFactory 类中获得。 这个工厂类根据一个位于classpath目录下的OJB.properties配置文件进行初始化。

除了对OJB的默认的初始化方式进行支持,Spring还提供了一个 LocalOjbConfigurer 的类。 它允许使用受到Spring管理的 DataSource 实例作为OJB链接的提供者。 DataSource 实例则在OJB资源描述器(配置文件)中进行描述,通过"jcd-alias"的定义完成:每个别名都与受Spring管理的同名的bean匹配。

<beans>

  <bean id="dataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
  </bean>

  <bean id="ojbConfigurer"/>

  ...
</beans>
<descriptor-repository version="1.0">

  <jdbc-connection-descriptor jcd-alias="dataSource" default-connection="true" ...>
  ...
  </jdbc-connection-descriptor>

  ...
</descriptor-repository>

一个 PersistenceBroker 此时可以通过标准的OJB的API打开,并指定一个对应的“PBKey”。 这通常通过对应的"jcd-alias"定义来完成(或者依赖于默认的连接)。

13.5.2. PersistenceBrokerTemplatePersistenceBrokerDaoSupport

每个基于OJB的DAO都将通过一个"PBKey"以bean方式进行配置,配置通过Setter注入方式完成。这样的DAO能够通过OJB的静态的 PersistenceBrokerFactory 类直接操作普通的OJB API进行编程。 当然你可以更愿意使用Spring的 PersistenceBrokerTemplate

<beans>
  ...

  <bean id="myProductDao">
    <property name="jcdAlias" value="dataSource"/> <!-- can be omitted (default) -->
  </bean>

</beans>
public class ProductDaoImpl implements ProductDao {

    private String jcdAlias;

    public void setJcdAlias(String jcdAlias) {
  this.jcdAlias = jcdAlias;
    }

    public Collection loadProductsByCategory(final String category) throws DataAccessException {
  PersistenceBrokerTemplate pbTemplate =
    new PersistenceBrokerTemplate(new PBKey(this.jcdAlias);
  return (Collection) pbTemplate.execute(new PersistenceBrokerCallback() {
public Object doInPersistenceBroker(PersistenceBroker pb)
  throws PersistenceBrokerException {

    Criteria criteria = new Criteria();
    criteria.addLike("category", category + "%");
    Query query = new QueryByCriteria(Product.class, criteria);

    List result = pb.getCollectionByQuery(query);
    // do some further stuff with the result list
    return result;
}
  });
    }
}

一个回调的实现能够有效地在任何OJB数据访问中使用。PersistenceBrokerTemplate 会确保当前的 PersistenceBroker 对象的正确打开和关闭,并自动参与到事务管理中去。 Template实例不仅是线程安全的,同时它也是可重用的。因而他们可以作为外部对象的实例变量而被持有。对于那些简单的诸如 getObjectByIdgetObjectByQuerystoredelete 操作的调用,PersistenceBrokerTemplate 提供可选择的快捷函数来替换这种回调的实现。 不仅如此,Spring还提供了一个简便的 PersistenceBrokerDaoSupport 基类,这个类提供了 setJcdAlias 方法来接受一个OJB JCD的别名,同时提供了 getPersistenceBrokerTemplate 方法给子类使用。 综合了这些,对于那些典型的业务需求,就有了一个非常简单的DAO实现:

public class ProductDaoImpl extends PersistenceBrokerDaoSupport implements ProductDao {

    public Collection loadProductsByCategory(String category) throws DataAccessException {
  Criteria criteria = new Criteria();
  criteria.addLike("category", category + "%");
  Query query = new QueryByCriteria(Product.class, criteria);

  return getPersistenceBrokerTemplate().getCollectionByQuery(query);
    }
}

作为不使用Spring的 PersistenceBrokerTemplate 来实现DAO的替代解决方案,你依然可以通过在原生OJB API的级别对那些基于Spring的DAO进行编程,此时你必须明确地打开和关闭一个 PersistenceBroker。 正如在相应的Hibernate章节描述的一样,这种做法的主要优点在于你的数据访问代码可以在整个过程中抛出checked exceptions。PersistenceBrokerDaoSupport 为这种情况提供了多种函数支持,包括获取和释放一个具备事务管理功能的 PersistenceBroker 和相关的异常转化。

13.5.3. 事务管理

将事务管理纳入到Service操作的执行中,你可以使用Spring通用的声明式的事务管理功能,例如:

<?xml version="1.0" encoding="UTF-8"?>
<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  ...

  <bean id="myTxManager">
    <property name="jcdAlias" value="dataSource"/>
  </bean>

  <bean id="myProductService">
    <property name="productDao" ref="myProductDao"/>
  </bean>

  <aop:config>
    <aop:pointcut id="productServiceMethods" expression="execution(* product.ProductService.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
  </aop:config>

  <tx:advice id="txAdvice" transaction-manager="myTxManager">
    <tx:attributes>
<tx:method name="increasePrice*" propagation="REQUIRED"/>
<tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/>
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
  </tx:advice>

</beans>

注意OJB的 PersistenceBroker 级别的API并不跟踪加载的对象的变化。 因而,一个 PersistenceBroker 的事务非常有必要成为一个简单的在 PersistenceBroker 级别的事务而仅仅加入一个为持久对象而设置的一级缓存。 此时,懒式加载无论在 PersistenceBroker 打开或者关闭时都将工作得很好。这一点与Hibernate和JDO相比有很大得不同。(懒式加载仅仅对于 Session 或者 PersistenceManager 各自保持打开时才有效)。

PersistenceBrokerTransactionManager 能够将一个OJB事务暴露给访问相同的JDBC DataSource 的JDBC访问代码。 前提条件是,所需要暴露事务的 DataSource 必须被明确指定,它无法被自动检测到。