【问题标题】:Swappable data layer using spring ioc使用spring ioc的可交换数据层
【发布时间】:2011-03-16 16:00:34
【问题描述】:

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

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

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

所以我将拥有用于休眠的 DAO。 然后是一个 DaoHibernateFactory,看起来像:

public class DaoHibernateFactory implements DaoFactory
{


     public UserDao GetUserDao() {

          return new UserHibernateDao();
     }


}

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

这有意义吗?有什么建议吗?

【问题讨论】:

    标签: java spring dependency-injection spring-mvc


    【解决方案1】:

    我会为每个实现使用单独的配置文件,而不是使用工厂。这样,spring 可以为您注入您的 DAO,而您不必调用或维护额外的工厂类。

    例如:

    休眠数据.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 中的文件来换出实现。

    【讨论】:

      【解决方案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 将被“休眠”取代。这种技术的另一个优点是 SpringPropertyPlaceHolder 还可以从环境中获取属性,它可以优先于 app.properties 使用(取决于配置参数,查找 javadocs 以获取详细信息)

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

      备选方案 2:

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

      【讨论】:

      • 感谢@Arthur。 @Blankman,如果您考虑到大多数弹簧配置无论如何都使用带有某些属性文件的属性占位符配置器这一事实,这并不太复杂。这是一次性设置。
      【解决方案3】:

      如果你认为你需要写一个工厂,我会说你严重忽略了这一点。在这种情况下,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);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-02-16
        • 2012-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-03
        • 2019-05-20
        • 1970-01-01
        相关资源
        最近更新 更多