2013-02-21 121 views
2

我为我的spring/hibernate项目配置了一个自定义通用服务DAO - 这个想法是我可以从我的控制器轻松地重用它。Spring Generic Dao类名

它在本质上是这样的:

​​

它得到的引用:

@Autowired 
public DefaultService<Address> addressService; 
addressService.get(1); 

然而String clip = e.getName()行抛出一个空指针异常。如果我将该类移动到属性部分中,我可以得到这个工作(所以addressService.get(Address.class, 1),但我觉得这有点不整洁,特别是当有多个不同的类被调用时。

是否有某种方法可以让类生成正确的值,而不必重复添加到我的所有功能?

在此先感谢。

回答

5

我没有类似的东西,你需要的泛型类是构造函数的参数以及矿山使用Hibernate的实体,但你可以传入表名字符串

public class DomainRepository<T> { 

    @Resource(name = "sessionFactory") 
    protected SessionFactory sessionFactory; 

public DomainRepository(Class genericType) { 
     this.genericType = genericType; 
    } 

@Transactional(readOnly = true) 
    public T get(final long id) { 
     return (T) sessionFactory.getCurrentSession().get(genericType, id); 
    } 

然后,您可以子类(如果需要)来定制或者干脆建立你的bean在Spring配置如下图所示T:

<bean id="tagRepository" class="com.yourcompnay.data.DomainRepository"> 
     <constructor-arg value="com.yourcompnay.domain.Tag"/> 
</bean> 

因此,在你的代码,你可以再参考tagRepository像这样(没有需要有比上面贴出来,和低于其他鳕鱼EIS):

@Resource(name = "tagRepository") 
private DomainRepository<Tag> tagRepository; 

另外,我把它叫做一个仓库不是一个服务,与不同类型和它们之间的相互作用(而不仅仅是一个)的业务交易。而对于具体的例子使用SQL字符串:

public final String tableName; 
public DomainRepository(String tableName) { 
     this.tableName = tableName; 
} 
public List<T> getAll(Integer status) { 
    Session session = sessionFactory.getCurrentSession(); 
    Query query = session.createQuery("FROM " + tableName + " WHERE status = " + status); 
    return query.list(); 
} 

,让你的豆类定义,像这样

<bean id="addressRepository" class="com.yourcompnay.data.DomainRepository"> 
    <constructor-arg value="address"/> 
</bean> 

然后你就可以alsow创建子类youself在必要时:

public class PersonRepository extends DomainRepository<Person> { 
    public PersonRepository(){ 
     super("person"); //assumes table name is person 
    } 
+0

我满级的第一行是@Repository,所以我就开始打电话从现在起:)因为它是我想要的类的名称,所以我可以创建自定义的数据库查找,并查看您的代码,这是我需要在理论上添加的所有'public void e(Class genericType){this.e = genericType; }'? – Toby 2013-02-21 13:41:48

+0

请参阅更新,如果子文件为空,则不必在必要时子类... onyl子类。在我的应用程序中,我有许多存储库,这些存储库只是通用存储库的实例,然后是一个或两个已被分类的转售(它们有更复杂的需求)。我提供的解决方案允许您继承子类...我会告诉你,aswel – NimChimpsky 2013-02-21 13:49:07

+0

好的,所以我已经对我的应用程序进行了改造,以遵循此步骤(勉强地为每个模型创建所有这些额外的存储库)。最后一个问题 - 这个bean做什么?它似乎工作得很好,没有它,但我确实需要删除'tableName'的'最终'修饰符并添加一个'Public DomainRepository(){}'方法... – Toby 2013-02-27 13:17:02

0

正如我明白你有NPE,因为你没有为这个领域设置任何价值。 所以你可以通过2种方法解决这个问题:

  1. 设置手动的类对象,如注释NimChimpsky。
  2. 动态获取类的类型。 E.克,如果你使用Spring试试这个:

protected Class getEntityClass() { return GenericTypeResolver.resolveTypeArguments(getClass(), DefaultService.class)[0]; }

some workaround here

+0

这应该与我目前的代码?我对发生的事情有一个很好的基本理解,但我不太明白这条线如何适应? – Toby 2013-02-21 13:33:05

+0

是的,这种方法应该对你有帮助。此行显示如何获取具体泛型类型的Class类型。你可以使用这个类对象:获取名称和其他东西。 – 2013-02-21 15:07:51

0

这是更好地定义一个特定的类地址服务

public class AddressService extends DefaultService<Address>{ 
    public String getClassName(){ 
    return "Address"; 
    } 
} 

其中

public String getClassName(); 

是在DefaultService中声明的一种抽象方法,并且在您的数据访问逻辑中使用(如您的方法className())。

使用这种方法,你就可以添加特定的数据访问逻辑(例如,getUsersByAddress)