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


3. 基礎功能

3.1. 設計BaseDao接口與BaseDaoImpl類

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

 

實體Dao接口實現類

========================================================

User--> UserDao--> UserDaoImpl

Role--> RoleDao--> RoleDaoImpl

Department--> DepartmentDao--> DepartmentDaoImpl

Article--> ArticleDao--> ArticleDaoImpl

...

 

設計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即可

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM