使用Spring实现DAO

问题描述:

我在考虑使用依赖注入来实现Objectify DAO,这样我就可以维护我的代码以访问相同的“Dao”,而实现可能在将来从Objectify改为Hibernate-MySQL或MongoDb时不需要我担心在UI或客户端更改任何代码。使用Spring实现DAO

userDAO的是基于这里的例子: http://turbomanage.wordpress.com/2010/01/28/simplify-with-objectify/

UserObjectifyDaoImpl implements Dao<User> { 

private UserDao dao = null; 

public void put(User entity) { 
    if (dao == null) { 
     dao = new UserDao(); 
    } 
    dao.put(entity); 
} 
// other put and set methods 
} 

这样,我有context.xml

<bean id="userDao" class="com.example.server.daoimpl.UserObjectifyDaoImpl"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

如果我需要改变的实施,我只需要改变这个豆从UserObjectifyDaoImpl类似于:

UserHibernateDaoImplUserMongoDBDaoImpl或任何实施保存到任何数据库。

而且仍然有我在UI /客户端代码完好无损,如:

WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); 

Dao dao = (Dao) ctx.getBean("userDao"); 
dao.put(something); 

一个原因,我现在需要做的这个权利,我需要使用的应用程序引擎(通过客观化)发展,但是在未来,我可能需要将某些数据访问对象更改为休眠状态,并将某些数据访问对象更改为mongodb(因此它是混合)。

我还没有测试过这个代码,这个策略会工作吗?

是的,这将起作用。事实上,这是为什么DI和接口编码被发明的主要原因之一。只要确保所有DAO实施遵循同一合同(DAO经常引入leaky abstractions)。

你也有其他几个选项来达到同样的目标:

  • 几个@Service注释类有一个标记为@Primary(如果使用的是自动装配)

  • Spring profiles和豆类的选择性激活

顺便说一句,如果你正在考虑切换到不同的DAO实现请从Spring Data查看CrudRepository。 Spring Data项目提供了几个为MongoDB,Neo4J,JPA等实现此接口的模块。

目前,好像有几个Spring Data模块不能很好地协作(见:DATAJPA-146),所以如果您选择执行CrudRepository确保此问题已修复,或者您可以解决此问题。感谢@iddqd指出。

+1

它会工作。你是righ,spring-data是好方法,但只适用于sql。spring-data-mongodb现在无法使用其他数据源https://jira.springsource.org/browse/DATAMONGO-389,https://jira.springsource.org/browse/DATAJPA-146 – iddqd 2012-02-09 12:13:42

+0

@iddqd:Nice ..但我相信OP希望完全从一个实现切换到另一个,而不是同时使用它们。 – 2012-02-09 12:15:45

+1

“我现在需要这样做的一个原因是,我需要开发使用应用程序引擎(通过objectify),但是在将来我可能需要将某些数据访问对象更改为休眠模式,以及将某些数据访问对象更改为mongodb。 “ – iddqd 2012-02-09 12:17:01

你可以改变背景config来选择DAO实现,如果你只需要一个实现应用程序,但如果你在你的应用需要一个以上的实现(混合模式),你需要设计工厂层。您尝试设计一个名为Factory的图层,并使用它的API和实现,并决定在任何时候选择Dao(Hibernate,MongoDB,JP等)。