封裝JPA的數據操作公共DAO基類

jopen 12年前發布 | 55K 次閱讀 JPA 持久層框架

通過將公共通用操作寫進父類簡化代碼,提高代碼的復用。
面向接口 使用繼承  泛型  引入JPA API查詢 以及 元數據 提高代碼的安全性。

DAO接口
/**
 * 數據庫通用操作基類接口
 */
public interface IObjectDao<T> extends Serializable {

    /**
     * 不需確定新建實體是否已經存在
     */
    public T save(T t);

    /**
     * 不需確定新建實體是否已經存在
     */
    public Collection<T> save(Collection<T> ts);

    /**
     * 可確定為新建實體;返回處于托管狀態的實例
     */
    public T persist(T t);

    public boolean persist(Collection<T> ts);

    /**
     * 若數據庫中已有此記錄,置為托管狀態
     */
    public T merge(T t);

    /**
     * 若數據庫中已有此記錄,置為托管狀態
     */
    public Collection<T> merge(Collection<T> t);

    /**
     * 刪除
     */
    public void remove(T t);

    /**
     * 批量刪除 傳入集合
     */
    public void remove(Collection<T> ts);

    /**
     * 刪除指定id、指定class的實例
     */
    public void remove(Class<T> clazz, String id);

    /**
     * 刪除指定id、指定class的實例
     */
    public void remove(Class<T> clazz, Collection<String> ids);

    /**
     * 清除一級緩存
     */
    public void clear();

    /**
     * 將對象置為游離狀態
     */
    public void detach(T t);

    /**
     * 將對象置為游離狀態
     */
    public void detach(Collection<T> ts);

    /**
     * 檢查實例是否處于托管狀態
     */
    public boolean isManaged(T t);

    /**
     * 同步jpa容器和數據庫
     */
    public void flush();

接口的實現類
/**
 * 數據庫通用操作基類 包含共同方法
 */
@Component("objectDao")
public class ObjectDaoImpl<T> implements IObjectDao<T> {

    private static final long serialVersionUID = 7433224241393375192L;
    public EntityManager entityManager;

    /**
     * 不需確定新建實體是否已經存在
     */
    @Override
    public T save(T t) throws RuntimeException {
        try {
            t = entityManager.contains(t) ? t : entityManager.merge(t);
        } catch (Exception e) {
            throw new RuntimeException("保存失敗,請聯系管理員!");
        }
        return t;
    }

    /**
     * 不需確定新建實體是否已經存在 傳入對象集合
     */
    @Override
    public Collection<T> save(Collection<T> ts) {
        Collection<T> collection = new HashSet<T>();
        for (T t : ts) {
            collection.add(save(t));
        }
        return collection;
    }

    /**
     * 可確定為新建實體
     */
    @Override
    public T persist(T t) {
        try {
            entityManager.persist(t);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("錯誤:保存新建實例時,發生異常:" + e.getMessage());
        }
    }

    /**
     * 可確定為新建實體 成功返回true 失敗返回false
     */
    @Override
    public boolean persist(Collection<T> ts) {

        try {
            for (T t : ts) {
                entityManager.persist(t);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 若數據庫中已有此記錄,置為托管狀態并刷新實體信息
     */
    @Override
    public T merge(T t) throws RuntimeException {
        try {
            t = entityManager.contains(t) ? t : entityManager.merge(t);
        } catch (Exception e) {
            throw new RuntimeException("更新失敗,請聯系管理員!");
        }
        return t;
    }

    /**
     * 若數據庫中已有此記錄,置為托管狀態
     */
    @Override
    public Collection<T> merge(Collection<T> ts) {
        Collection<T> collection = new HashSet<T>();
        for (T t : ts) {
            collection.add(merge(t));
        }
        return collection;
    }

    /**
     * 刪除
     */
    @Override
    public void remove(T t) throws RuntimeException {
        if (null == t) {
            throw new RuntimeException("請求刪除的對象為空!");
        }
        try {
            if (entityManager.contains(t)) {
                entityManager.remove(t);
            } else {
                Object id = entityManager.getEntityManagerFactory()
                        .getPersistenceUnitUtil().getIdentifier(t);
                entityManager.remove(entityManager.find(t.getClass(), id));
            }
        } catch (Exception e) {
            throw new RuntimeException("刪除對象時出錯,請聯系管理員!");
        }
    }

    /**
     * 批量刪除 傳入集合
     */
    @Override
    public void remove(Collection<T> ts) {
        for (T t : ts) {
            remove(t);
        }
    }

    /**
     * 刪除
     */
    @Override
    public void remove(Class<T> clazz, String id) throws RuntimeException {
        if (isEmpty(id)) {
            throw new RuntimeException("請求刪除的對象為空!");
        }
        try {
            entityManager.remove(entityManager.find(clazz, id));
        } catch (Exception e) {
        }
    }

    /**
     * 刪除
     */
    @Override
    public void remove(Class<T> clazz, Collection<String> ids) {
        for (String id : ids) {
            remove(clazz, id);
        }
    }

    /**
     * 若數據庫中存在,返回最新狀態;否則,返回空
     * 
     * @param clazz
     * @param t
     * @param id
     * @return
     */
    protected T refresh(Class<T> clazz, T t) throws RuntimeException {
        String id = (String) entityManager.getEntityManagerFactory()
                .getPersistenceUnitUtil().getIdentifier(t);
        if (null == t) {
            throw new RuntimeException("請求刷新的實體為空!");
        }
        if (StringUtil.isEmpty(id)) {
            return null;
        }
        if (entityManager.contains(t)) {
            entityManager.refresh(t);
            return t;
        } else {
            return entityManager.find(clazz, id);
        }
    }

    /**
     * 清除一級緩存
     */
    @Override
    public void clear() {
        entityManager.clear();
    }

    /**
     * 將對象置為游離狀態
     */
    @Override
    public void detach(T t) {
        entityManager.detach(t);
    }

    /**
     * 將對象置為游離狀態
     */
    @Override
    public void detach(Collection<T> ts) {
        for (T t : ts) {
            detach(t);
        }
    }

    /**
     * 判斷實體是否處于托管狀態
     */
    @Override
    public boolean isManaged(T t) {
        return entityManager.contains(t);
    }

    /**
     * 同步jpa容器和數據庫
     */
    @Override
    public void flush() {
        entityManager.flush();
    }

    // --------------------- DataBaseTool -------------------

    public EntityManager getEntityManager() {
        return entityManager;
    }

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    /**
     * 判斷一個字符串是否為空
     */
    protected boolean isEmpty(String string) {
        return null == string || string.trim().equals("") ? true : false;
    }

    /**
     * 日期轉換 :將java.util.Date類型轉換為java.sql.Date
     */
    protected java.sql.Date getSqlDate(java.util.Date date) {
        Long times = date.getTime();
        java.sql.Date date1 = new java.sql.Date(times);
        return date1;
    }

    /**
     * 數據查詢
     * 
     * @param start
     *            數據起始游標值
     * @param pageSize
     *            分頁大小
     * @param pageResult
     *            結果集封裝對象
     * @param cq
     *            數據查詢
     * @param cqCount
     *            符合條件的總條數
     * @return
     */
    protected PageResult<T> getResult(CriteriaQuery<T> cq,
            List<Predicate> predicates, CriteriaQuery<Long> cqCount,
            List<Predicate> predicatesCount, int start, int pageSize) {

        PageResult<T> pageResult = new PageResult<T>();
        // 設置查詢條件
        cq.where(predicates.toArray(new Predicate[0]));
        cqCount.where(predicatesCount.toArray(new Predicate[0]));
        try {
            // 查詢符合條件的數據總數
            long total = getEntityManager().createQuery(cqCount)
                    .getSingleResult();
            // 如果結果總數超過了Integer的最大值 則Integer的返回最大值
            pageResult.setTotalCount(total <= Integer.MAX_VALUE ? (int) total
                    : Integer.MAX_VALUE);
        } catch (Exception e) {
            // e.printStackTrace();
            pageResult.setTotalCount(0);
        }
        // 判斷分頁
        if (start > pageResult.getTotalCount() && pageSize > 0) {
            int newIndex = pageResult.getTotalCount() % pageSize == 0 ? pageResult
                    .getTotalCount() / pageSize
                    : pageResult.getTotalCount() / pageSize + 1;
            start = (newIndex - 1) * pageSize;
            pageResult.setChangeIndex(newIndex);
            pageResult.setFirst(start);
            pageResult.setPageSize(pageSize);
        }
        // 分頁查詢
        TypedQuery<T> tq = entityManager.createQuery(cq);
        if (start >= 0 && pageSize > 0) {
            tq.setFirstResult(start).setMaxResults(pageSize);
        }
        pageResult.setPageResultList(tq.getResultList());
        return pageResult;
    }

    /**
     * 返回指定類的靜態元模型名稱
     * 
     * @param clazz
     * @return
     */
    protected String getStaticMetamodelName(Class<T> clazz) {
        return clazz.getName() + "_";
    }

    /**
     * 根據company Id查找單個對象
     * 
     * @param company
     *            company不能為空,若為空以異常處理
     * @param clazz
     *            查詢數據類型
     * @param id
     * @return
     * @throws RuntimeException
     */
    @SuppressWarnings("unchecked")
    protected T findById(Company company, Class<?> clazz, String id)
            throws RuntimeException {
        if (null == company || isEmpty(company.getId())) {
            throw new RuntimeException("company 不能為空!");
        }
        if (isEmpty(id)) {
            return null;
        }
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<T> cq = (CriteriaQuery<T>) cb.createQuery(clazz);
        Root<T> root = (Root<T>) cq.from(clazz);
        cq.select(root).where(
                cb.and(cb.equal(root.get("id"), id),
                        cb.equal(root.get("company"), company)));
        try {
            return entityManager.createQuery(cq).getSingleResult();
        } catch (Exception e) {
            return null;
        }
    }

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!