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


  針對數據的增刪改查,使用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);

 

   5、分頁工具類Paginationhttp://www.cnblogs.com/luxh/archive/2012/08/11/2633844.html

 


免責聲明!

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



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