Spring結合JPA設計通用的BaseDao實現完全的面向介面程式設計
阿新 • • 發佈:2018-12-24
這是我們團隊小專案中設計的通用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;
//.....
}
這樣就可以完全實現面向介面程式設計。