簡體   English   中英

春季通用道類名稱

[英]Spring Generic Dao class name

我已經為我的spring / hibernate項目配置了一個自定義的通用服務DAO-這個想法是我可以從控制器中輕松地重用它。

基本上看起來像這樣:

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()行會引發Null指針異常。 如果將類移到屬性部分(所以addressService.get(Address.class, 1) ,我可以使它addressService.get(Address.class, 1)但是我發現這有點不整潔,尤其是在調用多個不同的類時。

有什么方法可以讓類正確地生成一個值,而無需將其重復添加到我的所有函數中?

提前致謝。

我做了類似的事情,您也需​​要將通用類也用作構造函數參數,我的也使用休眠實體,但是您可以傳入表名的字符串。

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);
    }

然后,您可以子類化(如果需要)以自定義或簡單地在spring配置中設置bean,如t所示:

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

因此,在您的代碼中,您可以像這樣引用tagRepository(除了上面和下面發布的代碼之外,不需要其他編碼):

@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>

然后,您還可以根據需要自己創建子類:

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

據我了解,您之所以獲得NPE,是因為您沒有為此字段設置任何值。 因此,您可以通過兩種方法解決此問題:

  1. 如注釋NimChimpsky中所述手動設置類對象。
  2. 動態獲取類類型。 例如,如果您使用Spring,請嘗試以下一種方法:

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

這里的一些解決方法

最好為地址服務定義一個特定的類

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

哪里

public String getClassName();

是在DefaultService中聲明的抽象方法,並在數據訪問邏輯中使用(類似於方法className())。

使用這種方法,您將能夠添加特定的數據訪問邏輯(例如,getUsersByAddress)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM