採用經典四層架構:domain實體層 → dao接口層 → dao.impl實現層 → service/biz業務層。核心思想:面向接口編程,依賴倒置,通用基類消除樣板代碼。
示例實體:Book(id, name, price)、Customer(id, name)。實體類遵循JavaBean規範,提供無參構造器與Getter/Setter。
// 頂層通用接口
public interface Dao<T> {
void add(T t);
void update(T t);
void delete(Serializable id);
T findOne(Serializable id);
}
// 業務擴展接口
public interface BookDao extends Dao<Book> { }
public interface CustomerDao extends Dao<Customer> {
List<Customer> findCustomers(int startIndex, int offset); // 分頁查詢
}
設計亮點:泛型<T>統一基礎操作,子接口僅聲明特有業務方法,實現「接口分離」。
public abstract class BaseDao<T> implements Dao<T> {
private Class<T> clazz;
public BaseDao() {
// 關鍵:通過反射獲取子類泛型實際類型
Type type = getClass().getGenericSuperclass(); // BaseDao<Book>
ParameterizedType pType = (ParameterizedType) type;
clazz = (Class<T>) pType.getActualTypeArguments()[0];
}
protected Session getSession() {
return HibernateUtil.getSession(); // 單例SessionFactory獲取Session
}
@Override public void add(T t) { execute(session -> session.save(t)); }
@Override public void update(T t) { execute(session -> session.update(t)); }
@Override public void delete(Serializable id) {
execute(session -> session.delete(findOne(id)));
}
@Override public T findOne(Serializable id) {
return getSession().get(clazz, id);
}
// 模板方法封裝事務
private void execute(Consumer<Session> action) {
Session session = getSession();
Transaction tx = session.beginTransaction();
try {
action.accept(session);
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}
}
核心技巧:構造器中通過getGenericSuperclass()解析實際泛型類型(如Book),賦值給clazz供session.get(clazz, id)使用,實現「寫一次基類,處處復用」。
public class BookDaoImpl extends BaseDao<Book> implements BookDao { }
public class CustomerDaoImpl extends BaseDao<Customer> implements CustomerDao {
@Override
public List<Customer> findCustomers(int startIndex, int offset) {
// HQL分頁查詢實現
return getSession()
.createQuery("from Customer")
.setFirstResult(startIndex)
.setMaxResults(offset)
.list();
}
}
OpenSessionInView或SpringHibernateTemplate統一生命週期DataAccessException屏蔽底層細節此DAO設計體現三大核心價值:
作為中小型項目的啟動模板極為合適;大型系統建議遷移至Spring Data JPA / MyBatis-Plus等成熟框架,專注業務創新而非基礎設施重造。