Spring Generic Dao类名

我已经为我的spring / hibernate项目配置了一个自定义通用服务DAO – 这个想法是我可以从我的控制器中轻松地重用它。

它基本上是这样的:

public class DefaultService { private Class e; public String className(Class e) { String clip = e.getName(); clip = clip.substring(clip.lastIndexOf('.') + 1, clip.length()); return clip; } public List getAll(Integer status) { Session session = sessionFactory.getCurrentSession(); Query query = session.createQuery("FROM " + className(e) + " WHERE status = " + status); return query.list(); } ... 

哪个被引用:

 @Autowired public DefaultService
addressService; addressService.get(1);

但是, String clip = e.getName()行会抛出Null指针exception。 如果我将类移动到属性部分(因此addressService.get(Address.class, 1) ,我可以addressService.get(Address.class, 1)但我发现这有点不整洁,特别是当有多个不同的类被调用时。

有没有办法让类正确生成一个值而不必重复添加到我的所有函数中?

提前致谢。

我做了类似的事情,你需要generics类作为构造函数参数,我使用hibernate实体,但你可以传入表名字符串。

 public class DomainRepository { @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); } 

然后你可以子类化(如果你需要)自定义或简单地在spring配置中设置bean,如下所示:

    

因此,在您的代码中,您可以像这样引用tagRepository(不需要其他代码,而不是上面和下面发布的代码):

 @Resource(name = "tagRepository") private DomainRepository tagRepository; 

此外,我将其称为存储库而非服务,服务处理不同类型及其交互(不仅仅是一个)。 特别是使用SQL字符串的示例:

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

并让你的bean定义如此

    

然后你也可以在必要时自己创建子类:

 public class PersonRepository extends DomainRepository { public PersonRepository(){ super("person"); //assumes table name is person } 

据我所知你有NPE,因为你没有为这个字段设置任何值。 所以你可以通过两种方式解决这个问题:

  1. 手动设置类对象,如注释NimChimpsky。
  2. 动态获取类类型。 例如,如果您使用Spring,请尝试以下方法:

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

或者在这里解决一些问题

最好为Address服务定义一个特定的类

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

哪里

 public String getClassName(); 

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

使用此方法,您将能够添加特定的数据访问逻辑(例如,getUsersByAddress)