BaseDao這個強大父類出現的價值分析

在原先的數據層在處理業務數據時,需要對不同的處理對象具備不同的方法來處理,比如客戶Customer對象的增刪改查基本操作需要一套save(Customer c)、delete(Long cust_id)、update(Customer c)、get(Long cust_id)這些方法,同樣,在聯繫人LinkMan對象的增刪改查有需要這麼一套類似的方法,區別只是操作的對象不一樣。我們苦苦追求如何不去寫重複的代碼!在jdk1.5版本出現之後,我們開發人員接觸到新的概念,叫作泛型。有泛型的出現,纔會有BaseDao的設計,我們的追求終究看到了答案。(在這其中也利用了反射技術)
BaseDao其實就是一個帶有泛型的接口,接口中寫出了一些數據庫操作的基本方法的,代碼如下:

package com.itcast.dao;

import java.io.Serializable;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;

public interface BaseDao<T> {
    //增
    void saveOrUpdate(T t);
    //刪
    void delete(Serializable id);
    //改
    void update(T t);
    //根據id查
    T findById(Serializable id);
    //查詢總記錄數
    Integer getTotalCount(DetachedCriteria dc);
    //查詢所有條目
    List getPageList(DetachedCriteria dc, Integer start, Integer pageSize);
}

爲了基於接口編程,我們需要寫它的實現類,對方法進行實現,這個實現代碼基於泛型編寫的可能容易理解,理解不了的可以多看幾遍註釋回味回味其中的意思。

package cn.itcast.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.HibernateTemplate;
import cn.itcast.dao.BaseDao;

public class BaseDaoImpl<T> implements BaseDao<T> {
    //持有操作數據庫的HibernateTemplate對象
    private HibernateTemplate ht;
    //持有Class對象,用來接收子類傳入的泛型的class對象
    private Class clazz;

    //構造函數,用來在通過反射創建該類對象時,經過空參構造代碼塊將
    public BaseDaoImpl() {
        //java中的反射API
        //獲得可獲得泛型類型的父類(就是實際泛型)
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        //獲得泛型類型
        clazz = (Class) pt.getActualTypeArguments()[0];
    }
    //保存對象
    @Override
    public void save(T t) {
        ht.saveOrUpdate(t);
    }
    //根據id刪除對象
    @Override
    public void delete(Serializable id) {
        T t = this.getById(id);
        ht.delete(t);
    }
    //更新對象
    @Override
    public void update(T t) {
        ht.update(t);
    }
    //根據id查詢對象
    @Override
    public T getById(Serializable id) {//id的數據類型Serializable是所有類型的基本數據類型及包裝
                                        //類型的父接口,可以接受上面的所有類型數據
        return (T) ht.load(clazz, id); //load加載對象需要傳入對象的字節碼及對象id
    }
    //根據離線查詢對象得到總記錄數
    @Override
    public Integer getTotalCount(DetachedCriteria dc) {
        //設置查詢總記錄數(count)
        dc.setProjection(Projections.rowCount());//select count(*)
        List<Long> list = (List<Long>) ht.findByCriteria(dc);
        //清空總記錄數條件
        dc.setProjection(null);
        return list.get(0).intValue();
    }
    //根據離線查詢對象,初始索引和頁大小,分頁查詢記錄,以list返回
    @Override
    public List getPageList(DetachedCriteria dc, Integer start, Integer pageSize) {
        return ht.findByCriteria(dc, start, pageSize);
    }
    //注入HibernateTemplate對象
    public void setHt(HibernateTemplate ht) {
        this.ht = ht;
    }

    public HibernateTemplate getHt() {
        return ht;
    }

}

有了BaseDao的實現類BaseDaoImpl,我們就可以在處理不同對象時只需要調用這裏面的方法,傳入實際類型替代泛型,即可進行數據操作,大大減少我們的代碼量。到這裏基本上介紹的差不多了,但是爲了達到完美,我們在處理不同模塊的業務是都定義了數據操作接口,例如:CustomerDao、LinkManDao、UserDao分別管理不同類型的業務,對應這些接口,也具備了各自的實現類,在這裏,與BaseDao關聯就可以毫無顧忌的使用它內部的方法了
,關聯其實很簡單,用各個模塊的接口去繼承BaseDao接口,這樣基本的數據操作需要的方法聲明直接從父類拿來用,各個模塊的實現類一方面實現模塊接口,同時還要繼承BaseDaoImpl,這樣實現類的方法從父類直接拿來去實現接口中的方法,下面我貼出部分模塊的實現類和接口.
1. CustomerDaoImpl

package cn.itcast.dao.impl;

import cn.itcast.dao.CustomerDao;
import cn.itcast.domain.Customer;

public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao {}
基本數據操作的方法從BaseDaoImpl直接拿來用(此時已經將BaseDao中的泛型T置爲Customer)。

2. LinkManDaoImpl

package cn.itcast.dao.impl;

import cn.itcast.dao.LinkManDao;
import cn.itcast.domain.LinkMan;

public class LinkManDaoImpl extends BaseDaoImpl<LinkMan> implements LinkManDao {}

今天介紹BaseDao我所在的環境是Hibernate-struts2-Spring3,dao層用到的操作數據路的技術是HibernateTemplete模板技術,spring爲每個模塊的數據操作類注入了HibernateTemplete,配置代碼段在Application.xml文件中如下:

<!-- 配置Dao -->
    <bean name="userDao" class="cn.itcast.dao.impl.UserDaoImpl" >
        <property name="ht" ref="hibernateTemplate" ></property>
    </bean>
    <bean name="customerDao" class="cn.itcast.dao.impl.CustomerDaoImpl" >
        <property name="ht" ref="hibernateTemplate" ></property>
    </bean>
    <bean name="linkManDao" class="cn.itcast.dao.impl.LinkManDaoImpl" >
        <property name="ht" ref="hibernateTemplate" ></property>
    </bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章