首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

DAO設計模式深度解析:基於Hibernate的通用分層架構實戰

     編輯:Java 綜合教學

專案結構總覽

工程目錄結構

採用經典四層架構:domain實體層 → dao接口層 → dao.impl實現層 → service/biz業務層。核心思想:面向接口編程,依賴倒置,通用基類消除樣板代碼。

領域模型設計

領域模型圖

示例實體:Book(id, name, price)、Customer(id, name)。實體類遵循JavaBean規範,提供無參構造器與Getter/Setter。

DAO接口體系:泛型抽象CRUD

// 頂層通用接口
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>統一基礎操作,子接口僅聲明特有業務方法,實現「接口分離」。

通用基類實現:反射泛型 + Hibernate模板

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

進階優化方向

  1. 事務管理上移:當前基類每方法獨立事務,實際專案應由Service層控制事務邊界(@Transactional),DAO僅執行持久化操作
  2. Session管理:引入OpenSessionInView或SpringHibernateTemplate統一生命週期
  3. 查詢構建:整合Criteria API / QueryDSL 實現類型安全動態查詢
  4. 異常轉換:捕獲Hibernate異常轉為統一DataAccessException屏蔽底層細節

總結

此DAO設計體現三大核心價值:

  • 泛型抽象:消除90%重複CRUD代碼
  • 反射泛型解析:零配置自動綁定實體類型
  • 模板方法模式:統一事務/資源管理邏輯

作為中小型項目的啟動模板極為合適;大型系統建議遷移至Spring Data JPA / MyBatis-Plus等成熟框架,專注業務創新而非基礎設施重造。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved