[英]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,是因為您沒有為此字段設置任何值。 因此,您可以通過兩種方法解決此問題:
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.