BaseDao --- dao層的抽取

通常來說一個項目中,我們會使用到多個Dao,例如一個學生管理系統,可能就包含AdminDao,StudentDao,CourseDao等模塊,每個Dao都有相同的增刪改查代碼,每個Dao去寫也是可以的,不過代碼量就會偏多。實際上可以通過泛型,來抽取出一個BaseDao,這個BaseDao包含了各個Dao常用的增刪改查代碼,創建新的Dao時,繼承BaseDao,就可以少寫很多重複代碼。
下面我們先寫一個普通的Dao,然後抽取出BaseDao,看Dao前後代碼變化。

1、抽取前dao接口代碼

package cn.tax.nsfw.user.dao;
import java.io.Serializable;
import java.util.List;
import cn.tax.nsfw.user.entity.User;

public interface UserDao {

    public void save(User user);// 保存

    public void delete(User user);// 刪除用戶

    public void update(User user);// 更新用戶

    public User findById(Serializable id);// 根據主鍵查找用戶

    public List<User> getAll();// 查看所有

}

2、抽取前dao實現類

package cn.tax.nsfw.user.dao.impl;
import java.io.Serializable;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import cn.tax.nsfw.user.dao.UserDao;
import cn.tax.nsfw.user.entity.User;

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

    public void save(User user) {
        getSession().save(user);
    }
    public void delete(User user) {
        getSession().delete(user);
    }
    public void update(User user) {
        getSession().update(user);
    }
    public User findById(Serializable id) {
        return (User) getSession().get(User.class, id);
    }
    public List<User> getAll() {
        return getSession().createQuery("FROM User").list();
    }

}

3、創建BaseDao接口

這個接口不需要改動太多,只需要把基本的增刪改查代碼改成泛型(把dao接口的複製過來,把User 改成 T ,)T是可以任意一個字母,只是習慣都用T (泛型知識)。

package cn.tax.nsfw.core.dao;
import java.io.Serializable;
import java.util.List;

public interface BaseDao<T> {

    public void save(T entity);// 保存

    public void delete(T entity);// 刪除用戶

    public void update(T entity);// 更新用戶

    public T findById(Serializable id);// 根據主鍵查找用戶

    public List<T> getAll();// 查看所有

}

4、創建BaseDao實現

實現了BaseDao接口後,最主要的做的事情是要獲取到T的類型。
因爲在查詢數據庫的時候Hibernate需要用到這個字段去拼接查詢語句
其實在service層調用的時候,就已經知道T的傳入類型,問題就在於怎麼在BaseDao實現類中獲取到這個傳入類型,看下面這行代碼,這行代碼返回的是包含泛型的父類:
a、ParameterizedType pt =
(ParameterizedType)this.getClass().getGenericSuperclass();
具體打印出來是:cn.tax.nsfw.core.dao.impl.BaseDaoImpl< cn.tax.nsfw.user.entity.User >
b、clazz = (Class< T >)pt.getActualTypeArguments()[0]
這行代碼返回的是此類型實際類型參數的Type對象的數組,數組裏放的都是對應類型的Class
具體打印出來的是:cn.tax.nsfw.user.entity.User
c、到這裏就已經拿到了在service層傳進來的實體類類型。
最後用的時候再通過clazz.getSimpleName()就可以拿到“User”字段去拼接查詢語句了

BaseDao實現類代碼:

package cn.tax.nsfw.core.dao.impl;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import cn.tax.nsfw.core.dao.BaseDao;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {

    Class<T> clazz;
    ParameterizedType pt;
    public BaseDaoImpl() {
        pt = (ParameterizedType)this.getClass().getGenericSuperclass();     //cn.tax.nsfw.core.dao.impl.BaseDaoImpl<cn.tax.nsfw.user.entity.User>
        clazz = (Class<T>)pt.getActualTypeArguments()[0];  //cn.tax.nsfw.user.entity.User
    }
    public void save(T entity) {
        getSession().save(entity);
    }
    public void delete(T entity) {
        getSession().delete(entity);
    }
    public void update(T entity) {
        getSession().update(entity);
    }
    public T findById(Serializable id) {
        return (T) getSession().get(clazz, id);
    }
    public List<T> getAll() {
        return getSession().createQuery("FROM " + clazz.getSimpleName()).list();
    }

}

5、修改抽取前的Dao接口

 A、繼承BaseDao< User > 
 B、把BaseDao< User >中有的方法都可以註釋掉(刪掉),
 C、以後有新增的業務,只需要加新增的業務代碼。整個dao就沒有多少代碼了。
package cn.tax.nsfw.user.dao;
import cn.tax.nsfw.core.dao.BaseDao;
import cn.tax.nsfw.user.entity.User;

public interface UserDao extends BaseDao<User> {

    //public void save(User user);// 保存

    //public void delete(User user);// 刪除用戶

    //public void update(User user);// 更新用戶

    //public User findById(Serializable id);// 根據主鍵查找用戶

    //public List<User> getAll();// 查看所有

}

6、修改抽取前的dao實現類

 A、繼承BaseDaoImpl< Use r> ,因爲BaseDaoImpl< User >繼承了hibernateDaoSupport,所以UserDaoImpl 也是可以用hibernateDaoSupport的方法的
 B、同樣是把BaseDaoImpl< User >中已有的方法註釋掉(刪掉),只需添加新的業務代碼。
package cn.tax.nsfw.user.dao.impl;
import cn.tax.nsfw.core.dao.impl.BaseDaoImpl;
import cn.tax.nsfw.user.dao.UserDao;
import cn.tax.nsfw.user.entity.User;

public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {
    //如果沒有新的業務,dao層代碼基本是空的,所有基本的增刪改查都交給baseDao來處理,
    //這裏只需要實現一些新增業務代碼就可以了
    /*public void save(User user) {
        getSession().save(user);
    }
    public void delete(User user) {
        getSession().delete(user);
    }
    public void update(User user) {
        getSession().update(user);
    }
    public User findById(Serializable id) {
        return (User) getSession().get(User.class, id);
    }
    public List<User> getAll() {
        return getSession().createQuery("FROM User").list();
    }*/

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章