數據訪問層常用操作的JPA實現

轉自:http://www.haogongju.net/art/1604040


針對數據的增刪改查,使用JPA做一些常用的封裝。

  一個基礎DAO接口和一個DAO接口的實現類。

  1、基礎DAO接口BaseDao

package cn.luxh.app.dao.common;
import java.util.List;
import cn.luxh.app.util.Pagination;
import cn.luxh.app.util.QueryCondition;
/**
* interface <code>BaseDao</code> DAO接口,封裝常用的數據庫操作
*
* @author Luxh
*/
public interface BaseDao {
/**
* 新增實體
* @param entity  要新增的實體
*/
public void save(Object entity);
/**
* 更新實體
* @param entity  要更新的實體
*/
public void update(Object entity);
/**
* 根據主鍵刪除實體
* @param <T>
* @param clazz   實體類的Class
* @param id      主鍵
*/
public <T> void delete(Class<T> clazz,Object id);
/**
* 根據主鍵批量刪除實體
* @param <T>
* @param clazz   實體類的Class
* @param id      主鍵數組
*/
public <T> void delete(Class<T> clazz,Object[] ids);
/**
* 根據主鍵查詢
* @param <T>
* @param clazz  實體類的Class
* @param id     主鍵
* @return
*/
public <T> T getById(Class<T> clazz,Object id);
/**
* 查詢所有記錄
* @param <T>
* @param clazz 實體類的Class
* @return
*/
public <T> List<T> getAll(Class<T> clazz);
/**
* 根據條件集合查詢記錄
* @param <T>
* @param clazz
* @param queryConditions 查詢條件集合
* @param orderBy         排序,如 order by id desc
* @param currentPage     當前頁
* @param pageSize        每頁顯示記錄數
* @return
*/
public <T> List<T> get(Class<T> clazz,List<QueryCondition> queryConditions,String orderBy,int currentPage,int pageSize);
/**
* 根據條件集合查詢記錄
* @param <T>
* @param clazz
* @param queryConditions  查詢條件集合
* @return
*/
public <T> List<T> get(Class<T> clazz,List<QueryCondition> queryConditions);
/**
* 根據條件集合查詢記錄
* @param <T>
* @param clazz
* @param queryConditions  查詢條件集合
* @param orderBy          排序,如 order by id desc
* @return
*/
public <T> List<T> get(Class<T> clazz,List<QueryCondition> queryConditions,String orderBy);
/**
* 根據條件集合查詢單條記錄
* @param clazz
* @param queryConditions  查詢條件集合
* @return
*/
@SuppressWarnings("rawtypes")
public  Object getSingleResult(Class clazz,List<QueryCondition> queryConditions);
/**
* 根據條件查詢記錄數量
* @param clazz
* @param queryConditions  查詢條件集合
* @return
*/
@SuppressWarnings("rawtypes")
public long getRecordCount(Class clazz,List<QueryCondition> queryConditions);
/**
* 根據jpql查詢
* @param <T>
* @param jpql
* @param objects
* @return
*/
public <T> List<T> getByJpql(String jpql,Object...objects);
/**
* 執行jpql語句
* @param jpql
* @param objects
* @return
*/
public int executeJpql(String jpql,Object...objects);
/**
* 分頁查詢
* @param <T>
* @param clazz
* @param queryConditions   查詢條件集合
* @param orderBy           排序字段 如:order by id desc
* @param currentPage       當前頁
* @param pageSize          每頁顯示記錄數
* @return
*/
public <T> Pagination<T> getPagination(Class<T> clazz,List<QueryCondition> queryConditions,String orderBy,int currentPage,int pageSize);
/**
* 查找唯一結果
* @param jpql
* @param objects
* @return
*/
public Object getUniqueResultByJpql(String jpql,Object...objects);
}

  


  2、DAO接口的實現類BaseDaoImpl

package cn.luxh.app.dao.common;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import cn.luxh.app.util.Pagination;
import cn.luxh.app.util.QueryCondition;
/**
* Class <code>BaseDaoImpl</code> DAO接口實現類,實現常用的操作
*
* @author Luxh
*/
@Repository(value="baseDao")
public class BaseDaoImpl implements BaseDao {
@PersistenceContext
protected EntityManager em;
public <T> void delete(Class<T> clazz, Object id) {
T entity = em.find(clazz, id);
em.remove(entity);
}
public <T> void delete(Class<T> clazz, Object[] ids) {
T entity = null;
for(Object id : ids) {
entity = em.find(clazz, id);
em.remove(entity);
}
}
@SuppressWarnings("unchecked")
public <T> List<T> getAll(Class<T> clazz) {
String className = clazz.getSimpleName();
StringBuffer jpql = new StringBuffer("select o from ");
jpql.append(className).append(" o ");
return em.createQuery(jpql.toString()).getResultList();
}
public <T> T getById(Class<T> clazz, Object id) {
return em.find(clazz, id);
}
public void save(Object entity) {
em.persist(entity);
}
public void update(Object entity) {
em.merge(entity);
}
@SuppressWarnings("unchecked")
public <T> List<T> get(Class<T> clazz, List<QueryCondition> queryConditions,String orderBy,int currentPage,int pageSize) {
Query query = getQuery(clazz, queryConditions, orderBy, false);
if(currentPage == 0 && pageSize == 0) {
return query.getResultList();
}else {
return query.setFirstResult((currentPage-1)*pageSize).setMaxResults(pageSize).getResultList();
}
}
/**
* 根據查詢條件獲取Query
* @param clazz
* @param queryConditions
* @param orderBy
* @param isQueryTotal  是否查詢記錄總數, true 則查詢記錄總數
* @return
*/
@SuppressWarnings("rawtypes")
private  Query getQuery(Class clazz, List<QueryCondition> queryConditions,String orderBy,boolean isQueryTotal) {
String className = clazz.getSimpleName();
String preJPQL = isQueryTotal?"select count(*) from ":"select o from ";
StringBuffer jpql = new StringBuffer(preJPQL);
jpql.append(className).append(" o where 1=1 ");
Query query = null;
if(queryConditions != null && queryConditions.size() > 0) {
//構造jpql語句
Iterator<QueryCondition> iterator = queryConditions.iterator();
while(iterator.hasNext()) {
QueryCondition queryCondition = iterator.next();
if(queryCondition!=null) {
if(queryCondition.getOperator().equals(QueryCondition.CUSTOM)) {
jpql.append(" and (").append(queryCondition.getCustomJPQL()).append(")");
}
if(queryCondition.getValue() != null && !"".equals(queryCondition.getValue())) {
//如果佔位符名稱是*.*格式,則換成*_*格式。且:和名稱之間不能有空格
String placeholder = queryCondition.getField().indexOf(".")!=-1 ? queryCondition.getField().replace(".", "_"):queryCondition.getField();
jpql.append(" and o.").append(queryCondition.getField().trim())
.append(" ").append(queryCondition.getOperator()).append(":").append(placeholder.trim());
}
}
}
}
if(orderBy != null && !"".equals(orderBy)) {
jpql.append(" ").append(orderBy);
}
query = em.createQuery(jpql.toString());
if(queryConditions != null && queryConditions.size() > 0) {
//爲參數賦值
Iterator<QueryCondition> iterator2 = queryConditions.iterator();
while(iterator2.hasNext()) {
QueryCondition queryCondition = iterator2.next();
if(queryCondition!=null) {
if(queryCondition.getValue() != null && !"".equals(queryCondition.getValue())) {
//將佔位符中的.替換成_
queryCondition.setField(queryCondition.getField().indexOf(".") != -1 ? queryCondition.getField().replace(".", "_"):queryCondition.getField());
if(queryCondition.getOperator().equals(QueryCondition.LK)) {
query.setParameter(queryCondition.getField(), "%"+queryCondition.getValue()+"%");
}else {
query.setParameter(queryCondition.getField(), queryCondition.getValue());
}
}
}
}
}
return query;
}
public <T> List<T> get(Class<T> clazz, List<QueryCondition> queryConditions) {
return get(clazz, queryConditions, null, 0, 0);
}
public <T> List<T> get(Class<T> clazz, List<QueryCondition> queryConditions, String orderBy) {
return get(clazz, queryConditions, orderBy, 0, 0);
}
@SuppressWarnings("rawtypes")
public Object getSingleResult(Class clazz, List<QueryCondition> queryConditions) {
Query query = getQuery(clazz, queryConditions, null, false);
return query.getSingleResult();
}
@SuppressWarnings("rawtypes")
public long getRecordCount(Class clazz, List<QueryCondition> queryConditions) {
Query query = getQuery(clazz, queryConditions, null, true);
Object result = query.getSingleResult();
long recordCount = 0L;
if(result != null) {
recordCount = ((Long)result).longValue();
}
return recordCount;
}
@SuppressWarnings("unchecked")
public <T> List<T> getByJpql(String jpql, Object... objects) {
Query query = em.createQuery(jpql);
if(objects != null) {
if (objects != null) {
for(int i = 0 ; i < objects.length ; i ++){
query.setParameter(i, objects[i]);
}
}
}
return query.getResultList();
}
public int executeJpql(String jpql,Object...objects) {
Query query = em.createQuery(jpql);
if (objects != null) {
for(int i = 0 ; i < objects.length ; i ++){
query.setParameter(i, objects[i]);
}
}
return query.executeUpdate();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> Pagination<T> getPagination(Class<T> clazz,List<QueryCondition> queryConditions,String orderBy,int currentPage,int pageSize) {
List<T> recordList = get(clazz, queryConditions, orderBy, currentPage, pageSize);
long recordCount = getRecordCount(clazz, queryConditions);
return new Pagination(currentPage, pageSize, recordCount, recordList);
}
@Override
public Object getUniqueResultByJpql(String jpql, Object... objects) {
Query query = em.createQuery(jpql);
if (objects != null) {
for(int i = 0 ; i < objects.length ; i ++){
query.setParameter(i, objects[i]);
}
}
return query.getSingleResult();
}
}


 

  3、查詢條件工具類QueryCondition

package cn.luxh.app.util;
/**
* Class <code>QueryCondition</code> 查詢條件
* @author Luxh
*/
public class QueryCondition {
/**等於*/
public static final String EQ = "=";
/**小於*/
public static final String LT = "<";
/**大於*/
public static final String GT = ">";
/**小於等於*/
public static final String LE = "<=";
/**大於等於*/
public static final String GE = ">=";
/**相似*/
public static final String LK = "like";
//可以再擴展
//......
/**自定義jpql語句*/
public static final String CUSTOM = "custom";
/**屬性名*/
private String field;
/**操作符*/
private String operator;
/**值*/
private Object value;
/**自定義jpql語句*/
private String customJPQL;
/**
* 傳入自定義語句
* @param customJPQL
*/
public QueryCondition(String customJPQL) {
this.customJPQL = customJPQL;
this.operator = CUSTOM;
}
/**
*
* @param field        屬性名
* @param operator    操作符
* @param value     值        如果屬性是日期類型,需將字符串格式爲日期 如new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-03-23 10:22:22")
*/
public QueryCondition(String field, String operator, Object value) {
this.field = field;
this.operator = operator;
this.value = value;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public String getCustomJPQL() {
return customJPQL;
}
public void setCustomJPQL(String customJPQL) {
this.customJPQL = customJPQL;
}
}


  

  4、查詢條件QueryCondition的使用

List<QueryCondition> queryConditions = new ArrayList<QueryCondition>();
//根據姓名和年齡的範圍查找用戶
//對應的SQL: name = '楚留香'
queryConditions.add(new QueryCondition("name",QueryCondition.EQ,"楚留香"));
//對應的SQL: age = 10 or age =20
queryConditions.add(new QueryCondition("age = 10 or age =20"));
List<User> users = baseDao.get(User.class, queryConditions);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章