ItcastOA_設計BaseDao_設計DAO接口和實現類_寫DAO實現類中的方法內容

3. 基礎功能

3.1. 設計BaseDao接口與BaseDaoImpl類

每一個實體都應有一個對應的Dao,他封裝了對這個實體的數據庫操做。java

 

實體Dao接口實現類spring

========================================================數據庫

User--> UserDao--> UserDaoImplsession

Role--> RoleDao--> RoleDaoImpl框架

Department--> DepartmentDao--> DepartmentDaoImplide

Article--> ArticleDao--> ArticleDaoImplthis

...spa

 

設計Dao接口(抽取接口的公共方法)

BaseDao.java----把每一個dao都須要的方法放到這裏,好讓他們繼承設計

public interface BaseDao<T> {
    void save(T entity);
    /**
     * 保存實體
     * @param id
     */
    void delete (Long id);
    /**
     * 刪除實體
     * @param entity
     */
    void update(T entity);
    /**
     * 更新實體
     * @param id
     * @return
     */
    T getById(Long id);
    /**
     * 按id查詢
     * @return
     */
    List<T> getByIds(Long[] id);
    /**
     * 按id查詢
     * @return
     */
    List<T> findAll();
    /**
     * 查詢全部
     */
}

 

UserDao.java----一些公用的方法繼承BaseDao便可code

public interface UserDao extends BaseDao<User>{
    //本身有的特殊方法寫在本身這裏面
}

 

RoleDao.java

public interface RoleDao extends BaseDao<Role>{

}

 

增刪改查等共有方法都有了

 

設計Dao實現類(抽取實現類的公共方法)

 

//實現RoleDao,實現全部未實現的方法
public class RoleDaoImpl implements RoleDao{

    public void save(Role entity) {        
    }

    public void delete(Long id) {        
    }

    public void update(Role entity) {        
    }

    public Role getById(Long id) {
        return null;
    }

    public List<Role> getByIds(Long[] id) {
        return null;
    }

    public List<Role> findAll() {
        return null;
    }
}

 

public class UserDaoImpl implements RoleDao{

    public void save(Role entity) {        
    }

    public void delete(Long id) {        
    }

    public void update(Role entity) {        
    }

    public Role getById(Long id) {
        return null;
    }

    public List<Role> getByIds(Long[] id) {
        return null;
    }

    public List<Role> findAll() {
        return null;
    }
}

 

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

    public void save(T entity) {
    }

    public void delete(Long id) {
    }

    public void update(T entity) {
    }

    public T getById(Long id) {
        return null;
    }

    public List<T> getByIds(Long[] id) {
        return null;
    }

    public List<T> findAll() {
        return null;
    }
}

 

public class RoleDaoImpl extends BaseDaoImpl<Role> implements RoleDao{
}

 

public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{

}

 

能夠看出這兩個實現類的不少方法都重複了,咱們把它抽取出來,咱們寫一個類它事先實現了裏面的公共方法,讓這兩個實現類繼承便可。

 

BaseDaoImpl裏方法是有了,但裏面尚未內容,接下來寫該實現類裏面的方法內容

 

@SuppressWarnings("unchecked")
public abstract class BaseDaoImpl<T> implements BaseDao<T> {

    @Resource
    private SessionFactory sessionFactory;// 經過注入獲得SessionFactory,要把它放到容器裏才能注入,在具體的實現類上聲明@Repository

    private Class<T> clazz;
    
    public BaseDaoImpl() {
        //使用反射技術獲得T的真實類型
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();//獲取當前new類型的泛型的父類類型
        this.clazz = (Class<T>) pt.getActualTypeArguments()[0];//獲取第一個類型參數的真實類型,只有一個泛型參數,因此寫0
        System.out.println("clazz--->" + clazz);
    }

    /**
     * 獲取當前可用的session對象,用protected修飾方便子類獲得session
     */
    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    public void save(T entity) {
        // 不須要本身關事務了,spring框架已經幫咱們作了,咱們用它的事務管理
        getSession().save(entity);
    }

    public void update(T entity) {
        getSession().update(entity);
    }

    public void delete(Long id) {
        Object obj = getById(id);
        if (obj != null) {
            getSession().delete(obj);
        }
    }

    public T getById(Long id) {
        return (T) getSession().get(clazz, id);
    }

    public List<T> getByIds(Long[] ids) {
        return getSession().createQuery(//
                "FROM User WHERE id=IN(:ids)")//
                .setParameter("", ids)
                .list();
    }
    
    public List<T> findAll() {
        return getSession().createQuery(//
                "FROM " + clazz.getSimpleName())//
                .list();
    }
}

 

 

 

說明:

4, 實體的Dao接口要繼承BaseDao接口。

5, Dao的實現類要繼承DaoImplBase類。

6, 也能夠不繼承指定的接口或類,這樣就要本身寫相應的方法。

7, T getById(Long id)與List<T> getByIdList(Long[] idList)不要合併爲List getById(Long... ids),由於獲取一個對象時也是返回List,不方便。

 

 

獲取 BaseDao的類型參數T的Class

 

問題:

1, 有了DaoBase與DaoImplBase,還要用UserDao、RoleDao嗎

答:要用由於UserDao或RoleDao中的方法能夠分爲有公有的方法與特有的方法兩部分。公有的方法是經過繼承BaseDao獲得的,特有的方法要寫在本身裏面(BaseDao中是沒有的)。

2, UserDaoImpl已經繼承了BaseDaoImpl,就不實現UserDao能夠嗎?

答:不能夠不然UserDao userDao = new UserDaoImpl(); 就不成立。

 

使用反射獲取類型參數的真實類型的代碼以下:

public DaoBaseImpl () {

  Type type = this.getClass().getGenericSuperclass();

  ParameterizedType pt = (ParameterizedType) type;

  this.clazz = (Class<T>) pt.getActualTypeArguments()[0];

}

 

 

說明:

1, 使用Session時,不要本身建立,也不要管理事務,直接調用getSession()便可。

2, 暫時不實現getSession()方法,在後面的事務管理中實現
protected Session getSession(){
    throw new UnsupportedOperationException();
}

相關文章
相關標籤/搜索