使用spring ioc的可交换数据层

时间:2010-07-15 21:16:29

标签: java spring dependency-injection spring-mvc

我为每个表都有DAO,它们都实现了一个接口。

现在我希望能够(可能)交换数据库层实现。

所以我的策略是创建一个DaoFactory,这个DaoFactory将特定于我的DAO的特定实现。

所以我会有休眠的DAO。 然后是一个DaoHibernateFactory,它看起来像:

public class DaoHibernateFactory implements DaoFactory
{


     public UserDao GetUserDao() {

          return new UserHibernateDao();
     }


}

然后在我的所有经理/服务类中,我将使用当前通过spring ioc连接的Dao___Factory。

这有意义吗?建议?

3 个答案:

答案 0 :(得分:5)

我会为每个实现提供单独的配置文件,而不是使用工厂。这样春天可以为你注入你的DAO,你不必打电话或维持一个额外的工厂类。

例如:

冬眠-data.xml中:

<bean id="userDAO" class="com.foo.dao.hibernate.HibernateUserDao">
    ...
</bean>

ibatis的-data.xml中:

<bean id="userDAO" class="com.foo.dao.ibatis.IBatisUserDao">
    ...
</bean>

然后,您可以通过更改-data中包含的web.xml文件来替换实施。

答案 1 :(得分:2)

由于您正在使用依赖注入,因此您应该尝试使用DI框架中提供的开箱布线,而不是编写自己的工厂。

使用SpringPropertyPlaceHolder和Spring命令文件中DAO命名的简单约定可以解决当前问题。

步骤: 1.首先使用一些命名约定来命名各个DAO的ID并在spring文件中配置它们。 例如:

<bean id='hibernateUserDao' class='UserHibernateDao'/>
<bean id='ibatisUserDao' class='UserIbatisDao'/>

这里我们说所有Hibernate Daos都以hibernate开头,所有ibatis Daos都以ibatis等开头。

2.接下来配置Daos的使用者。根据属性确保接线是动态的。

<bean id='daoconsumer' class='some.consumer.class'>
  <property name='dao' ref='${daoImpl}UserDao'/>
</bean>

3.在Spring文件中配置Spring Property占位符后。

<bean id="propertyConfigurator" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:/path/to/app.properties</value>
    </property>
</bean>

4.最后,您使用单行编写app.properties。

daoImpl=hibernate # choose hibernate implementations.

现在,daoImpl将被“hibernate”取代。这种技术的另一个优点是SpringPropertyPlaceHolder也可以从环境中获取属性,它可以优先于app.properties使用(取决于配置参数查找javadocs以获取详细信息)

因此,您可以使用环境属性配置您的应用行为,这可能非常强大。

备选方案2:

您还可以使用Maven配置文件来实现类似的行为。 Maven具有“过滤”资源的能力 - 在这种情况下,它将用一些字符串替换占位符,具体取决于它正在执行的maven配置文件。您可以利用此功能生成适用于给定实现的应用程序包(jar,ear等)(如hibernate,ibatis等)。显然,这不如PropertyPlaceHolder方法灵活,但在某些条件下更可取。

答案 2 :(得分:1)

如果你认为你需要写一个工厂,我会说你很难忽视这一点。在这种情况下,Spring应用程序上下文是工厂:声明式动态对象工厂。使用你工厂的类失去了Spring的优势。

您可以编写通用DAO,这样您就不必维护所有代码。

package hibernate.policy.persistence;

import java.io.Serializable;
import java.util.List;

public interface GenericDao<T, K extends Serializable>
{
    T find(K id);
    List<T> find();
    List<T> find(T example);
    List<T> find(String queryName, String [] paramNames, Object [] bindValues);

    K save(T instance);
    void update(T instance);
    void delete(T instance);
}