春天通用DAO类名(Spring Generic Dao class name)

2019-07-20 07:35发布

我已经配置了一个自定义的通用服务DAO我的春/ Hibernate项目 - 的想法是,我可以从我的控制器很容易重用。

它本质上是这样的:

public class DefaultService<T> {

private Class<T> e;

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

它获取引用方式:

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

然而, String clip = e.getName()线抛出一个空指针异常。 我能得到这个工作,如果我移动到类的属性节(所以addressService.get(Address.class, 1)但我觉得这个有点凌乱,尤其是当有多个不同类别在被调用。

是否有某种方式来获得正确的类来生成一个值,而无需重复添加到我的所有功能?

提前致谢。

Answer 1:

我做了类似的事情,你需要的泛型类是构造函数的参数以及矿山使用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
    }


Answer 2:

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

  1. 手动设置类对象作为评论宁姆。
  2. 动态获取类的类型。 例如,如果你使用Spring试试这个:

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

或在这里的一些解决方法



Answer 3:

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

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

哪里

public String getClassName();

在DefaultService声明一个抽象方法,和使用(如您的方法类名())中的数据的访问的逻辑。

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



文章来源: Spring Generic Dao class name