[英]Hibernate and Spring - Dao ,Services
我一直在閱讀一些教程,我可以看到大多數MVC實現
基於:
1)dao接口,例如“IUserDao”
2)該接口的dao impl - “mySimpleUserDaoImpl”
3)持久性的服務接口:“IUserService”
4)和一個impl - “UserServiceImpl”
這是最好的做法嗎? 我的意思是我問這個問題的原因是因為使用getXById(),deleteX(x),createX(x)方法提供30個服務看起來多余或多或少相同似乎是多余的。
請考慮到我正在使用spring 3和hibernate 4,我決定在開始用代碼猛擊我的鍵盤之前我會問這個問題
謝謝。
如果您剛剛開始開發,請查看Spring JPA 。 服務應該是一對多存儲庫(DAO)。 但是我也不會再用手創建所有的樣板代碼了。 Spring JPA消除了基本的CRUD和搜索功能以及分頁。
這是一個視頻 ,介紹了Spring,JPA,Hibernate的所有配置,並使用Spring Data JPA完成,顯示了所有已消除的樣板代碼。
要使用Spring Data JPA,您的存儲庫接口最終會:
package com.mysampleapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.wcfgroup.model.Employee;
@Repository("employeeRepository")
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
Employee findBySsn(String ssn);
}
然后使用Spring Data JPA的XML配置:
<jpa:repositories base-package="com.mysampleapp.repository"/>
現在為您處理所有樣板代碼。 您不再需要使用find方法和基本CRUD函數創建基本存儲庫類。 JpaRepository
接口提供了許多不錯的功能,您沒有為實現做任何事情。
每個模型都需要dao,daoImpl,service,serviceImpl。
您可以使用通用類EntityDaoImpl和Inteface EntityDao,如下所示:
EntityDao:
public interface EntityDao<E> {
void persist(E e) throws Exception;
void remove(Object id) throws Exception;
E findById(Object id) throws Exception;
}
EntityDaoImpl:
public class EntityDaoImpl<E> implements EntityDao<E> {
@PersistenceContext(unitName="UnitPersistenceName")
protected EntityManager entityManager;
protected E instance;
private Class<E> entityClass;
@Transactional
public void persist(E e) throws HibernateException{
getEntityManager().persist(e);
}
@Transactional
public void remove(Object id) throws Exception{
getEntityManager().remove((E)getEntityManager().find(getEntityClass(), id));
}
public E findById(Object id) throws Exception {
return (E)getEntityManager().find(getEntityClass(), id);
}
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) throws Exception{
this.entityManager = entityManager;
}
public Class<E> getEntityClass() throws Exception{
if (entityClass == null) {
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType)
{
ParameterizedType paramType = (ParameterizedType) type;
if (paramType.getActualTypeArguments().length == 2) {
if (paramType.getActualTypeArguments()[1] instanceof TypeVariable) {
throw new IllegalArgumentException(
"Can't find class using reflection");
}
else {
entityClass = (Class<E>) paramType.getActualTypeArguments()[1];
}
} else {
entityClass = (Class<E>) paramType.getActualTypeArguments()[0];
}
} else {
throw new Exception("Can't find class using reflection");
}
}
return entityClass;
}
}
你可以像這樣使用:
public interface UserDao extends EntityDao<User> {
}
和
public class UserDaoImpl extends EntityDaoImpl<User> implements UserDao{
}
不需要有30個服務層或30個dao層。您應該指定不考慮實體明智但業務功能明智的層。可以有5個或6個與某個功能相關的實體,這些實體應該在一個層中。但是如果需要,你仍然必須在那些冗余層中使用getXById(),deleteX(x),createX(x)。
為每個模型創建一個單獨的服務是一種方法,我已經看到了這樣做的真實應用程序,但我不推薦它。 這對於簡單的CRUD案例來說是過度的,對於更復雜的案例(實際上你希望事務跨越幾個DAO調用)是無益的。 它為您留下了許多代碼,但沒有做太多。 可以使用Spring Data指定DAO,服務將是樣板,每個方法都包含對DAO的調用。 Spring應該有助於減少樣板,而不是強制它。
如果你有一個完全CRUD應用程序,那么你可以合法地沒有服務,將@Transactional放在DAO上,並從Controller調用DAO。 如果服務沒有拉動它的重量擺脫它。
如果你確實在應用程序中有實際的業務邏輯,那么當用戶調用可能涉及對不同DAO的調用的東西時,這些調用通常應該在同一個事務中進行,這樣如果一件事失敗,一切都會被回滾。 (同樣創建一個事務是相對昂貴的,如果你有一個控制器為不同的實體調用不同的服務,那么這將是緩慢的。)這是服務派上用場的地方,該服務指定用戶想要的低級用例執行並允許指定事務行為。
對於CRUD案例,我更喜歡使用像Grails或Play或Rails這樣的工具或者用Spring MVC編寫Java。 例如,Grails將為您生成視圖和控制器,通過GORM提供基本數據訪問(因此沒有可寫的DAO),並且它可以讓您輕松地為您發現需要它們的情況指定服務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.