1. 程式人生 > >Spring結合JPA設計通用的BaseDao實現完全的面向介面程式設計

Spring結合JPA設計通用的BaseDao實現完全的面向介面程式設計

 這是我們團隊小專案中設計的通用BaseDao:


public interface BaseDao<T> {
    /**
     * 新增實體類
     * @param t
     * @return
     */
    public T add(T t);

    /**
     * 更新實體類
     * @param t
     * @return
     */
    public T update(T t);

    /**
     * 根據主鍵ID刪除實體類
     * @param id
     */
    public void delete(Serializable id);

    /**
     * 根據JPQL語句更新或刪除操作
     * @param jpql
     * @param obj
     */
    public int executeUpdate(String jpql,Object... obj);

    /**
     * 根據主鍵ID查詢單個實體類
     * @param id
     * @return
     */
    public T load(Serializable id);

    /**
     * 根據JPQL語句查詢單個實體類
     * @param jpql
     * @param obj(引數可有可無)
     * @return
     */
    public T load(String jpql,Object... obj);

    /**
     * 查詢所有的實體類
     * @return
     */
    public List<T> findAll();

    /**
     * 根據JPQL語句查詢集合實體類
     * @param jpql
     * @param obj(引數可有可無)
     * @return
     */
    public List<T> find(String jpql,Object... obj);

    /**
     * 聚合查詢
     * @param jpql
     * @param obj
     * @return
     */
    public Object findByAggregate(String jpql,Object... obj);

    /**
     * 查詢總記錄數
     * @return
     */
    public int count();

    /**
     * 根據JPQL語句查詢記錄數
     * @param jpql
     * @param obj
     * @return
     */
    public int count(String jpql,Object... obj);

    /**
     * 分頁查詢集合實體類
     * @param firstIndex
     * @param maxResults
     * @return
     */
    public List<T> findPage(Integer firstIndex, Integer maxResults);

    /**
     * 根據JPQL語句查詢集合實體類
     * @param firstIndex
     * @param maxResults
     * @param jpql
     * @param obj
     * @return
     */
    public List<T> findPage(Integer firstIndex, Integer maxResults,String jpql,Object... obj);


    public Page findPage(Page page,String jpql,Object... obj);

}

BaseDao的基礎實現類AbstractBaseDao:


public abstract class AbstractBaseDao<T> implements BaseDao<T> {

    @PersistenceContext
    private EntityManager em;

    private Class<T> clazz = null;

    public AbstractBaseDao(){
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
    }


    @Override
    public T add(T t) {
        em.persist(t);
        return t;
    }

    @Override
    public T update(T t) {
        return em.merge(t);
    }


    @Override
    public void delete(Serializable id) {
        T t = em.getReference(clazz, id);
        em.remove(t);
    }

    @Override
    public int executeUpdate(String jpql, Object... obj) {
        Query query = em.createQuery(jpql);
        if(obj.length > 0){
            for (int i = 0; i < obj.length; i++) {
                query.setParameter((i+1),obj[i]);
            }
        }
        return query.executeUpdate();
    }

    @Override
    public T load(Serializable id) {
        return em.find(clazz, id);
    }

    @Override
    public T load(String jpql, Object... obj) {
        try{
            Query query = em.createQuery(jpql);
            if(obj.length > 0){
                for (int i = 0; i < obj.length; i++) {
                    query.setParameter((i+1),obj[i]);
                }
            }
            return (T) query.getSingleResult();
        }catch (Exception e){
          return null;
        }
    }

    @Override
    public List<T> findAll() {
        return em.createQuery("from "+clazz.getSimpleName()).getResultList();
    }

    @Override
    public List<T> find(String jpql, Object... obj) {
        try{
            Query query = em.createQuery(jpql);
            if(obj.length > 0){
                for (int i = 0; i < obj.length; i++) {
                    query.setParameter((i+1),obj[i]);
                }
            }
           return query.getResultList();
        }catch (Exception e){
            return null;
        }
    }

    @Override
    public Object findByAggregate(String jpql, Object... obj) {
        Query query = em.createQuery(jpql);
        if(obj.length > 0){
            for (int i = 0; i < obj.length; i++) {
                query.setParameter((i+1),obj[i]);
            }
        }
        Object result = query.getSingleResult();
        return result;
    }

    @Override
    public int count() {
        Long num = (Long) em.createQuery("select count(*) from "+clazz.getSimpleName()).getSingleResult();
        return num.intValue();
    }

    @Override
    public int count(String jpql,Object... obj) {
        try{
            Query query = em.createQuery(jpql);
            if(obj.length > 0){
                for (int i = 0; i < obj.length; i++) {
                    query.setParameter((i+1),obj[i]);
                }
            }
            Long num = (Long)query.getSingleResult();
            return num.intValue();
        }catch (Exception e){
            return 0;
        }
    }

    @Override
    public List<T> findPage(Integer firstIndex, Integer maxResults) {
        return em.createQuery("from "+clazz.getSimpleName()).setFirstResult(firstIndex).setMaxResults(maxResults).getResultList();
    }

    @Override
    public List<T> findPage(Integer firstIndex, Integer maxResults,String jpql,Object... obj) {
        try{
            Query query = em.createQuery(jpql);
            if(obj.length > 0){
                for (int i = 0; i < obj.length; i++) {
                    query.setParameter((i+1),obj[i]);
                }
            }
            query.setFirstResult(firstIndex).setMaxResults(maxResults);
            return query.getResultList();
        }catch (Exception e){
            return null;
        }

    }

    @Override
    public Page<T> findPage(Page page, String jpql, Object... obj) {
        Query query = em.createQuery(jpql);
        if(obj.length > 0){
            for (int i = 0; i < obj.length; i++) {
                query.setParameter((i+1),obj[i]);
            }
        }
        int total = ((Long)query.getSingleResult()).intValue();
        page.setItemTotal(total);
        query.setFirstResult(page.getFirstIndex()).setMaxResults(page.getPageCount());
        List<T> list = query.getResultList();
        page.setItems(list);
        return page;
    }

}

這裡我們AbstractBaseDao設計為abstract ,因為我們不想讓他被例項化。IOC作為Spring中的核心技術之一使用它可以實現完全的面向介面程式設計,所以我們需要設計介面。這樣我們就可以在service層中使用介面注入。

現在我們來設計介面,如果我現在想要做一個訂單的持久層OrderDao要怎麼做。

public interface OrderDao extends BaseDao<Order> {

    List<Order> findOrderByStoreId(String storeId);

    List<Order> findOrderByStatus(String storeId,Integer status);

    int getActiveOrderCount(String storeId);

    int getNewOrderCount(String storeId);

    int getOrderCount(String storeId);

    List<Order> findOrderByStoreId(String storeId,Integer page, Integer pageSize);

    List<Order> findOrderByStatus(String storeId, Integer status, Integer page, Integer pageSize);

    int getOrderByStatusCount(String storeId, Integer status);
}

然後寫一個實現OrderDao的OrderDaoImpl:


@Repository
public class OrderDaoImpl extends AbstractBaseDao<Order> implements OrderDao {

    public List<Order> findOrderByStoreId(String storeId){
        List<Order> orders = this.find("SELECT o FROM Order o WHERE o.storeId = ? order by o.createTime desc", storeId);
        return orders;
    }

    @Override
    public List<Order> findOrderByStatus(String storeId,Integer status) {
        List<Order> orders = this.find("SELECT o FROM Order o WHERE o.storeId = ? and o.status = ? order by o.createTime desc", storeId, status);
        return orders;
    }

    @Override
    public int getActiveOrderCount(String storeId) {
        return this.count("SELECT count(o) FROM Order o WHERE o.storeId = ? and o.status in (1,2)", storeId);
    }

    @Override
    public int getNewOrderCount(String storeId) {
        return this.count("SELECT count(o) FROM Order o WHERE o.storeId = ? and o.status = 0", storeId);
    }

    @Override
    public int getOrderCount(String storeId) {
        return this.count("SELECT count(o) FROM Order o WHERE o.storeId = ?", storeId);
    }

    @Override
    public List<Order> findOrderByStoreId(String storeId, Integer page, Integer pageSize) {
        return this.findPage((page -1) * pageSize, pageSize, "SELECT o FROM Order o WHERE o.storeId = ? order by o.createTime desc, o.id", storeId);
    }

    @Override
    public List<Order> findOrderByStatus(String storeId, Integer status, Integer page, Integer pageSize) {
        return this.findPage((page -1) * pageSize, pageSize, "SELECT o FROM Order o WHERE o.storeId = ? and o.status = ? order by o.createTime desc, o.id", storeId, status);
    }

    @Override
    public int getOrderByStatusCount(String storeId, Integer status) {
        return this.count("SELECT count(o) FROM Order o WHERE o.storeId = ? and o.status = ?", storeId, status);
    }
}

然後我們在service層中就可以直接注入。

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;
  
    //.....

}

這樣就可以完全實現面向介面程式設計。