1. 程式人生 > >JPA通用dao包設計

JPA通用dao包設計

JPA通用dao包,封裝常用功能,具體程式碼如下

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.util.Assert;

/**
 * 
 * JPA通用dao包實現
 * @author 丶曉權
 *
 */
@SuppressWarnings("unchecked")
public class BaseDaoImpl{
	
	@PersistenceContext
	protected EntityManager enmanager;
	
	/**
	 * 根據ID查詢實體物件
	 * 呼叫例如:getEntity(UserEntity.class,1)
	 * @param cls 需要查詢實體的class 
	 * @param id 實體物件的ID
	 * @return 查詢到的結果
	 */
	public<T,ID extends Serializable> T getEntity(Class<T> cls,ID id) {
		return this.enmanager.find(cls, id);
	}

	/**
	 * 查詢全部資料
	 * 呼叫例如:findAll(UserEntity.class)
	 * @param cls 需要查詢實體的class
	 * @return 查詢到的結果集
	 */
	public <T> List<T> findAll(Class<T> cls) {
		CriteriaBuilder builder = enmanager.getCriteriaBuilder();
		CriteriaQuery<T> query = builder.createQuery(cls);
		return enmanager.createQuery(query.select(query.from(cls))).getResultList();
	}

	/**
	 * 新增
	 * @param t 實體物件
	 */
	public <T> void save(T t) {
		Assert.notNull(t);
		this.enmanager.persist(t);
	}

	/**
	 * 修改
	 * @param t 實體物件
	 * @return
	 */
	public <T> T update(T t) {
		Assert.notNull(t);
		return this.enmanager.merge(t);
	}

	/**
	 * 刪除
	 * @param t
	 */
	public <T> void delete(T t) {
		enmanager.remove(t);
	}

	/**
	 * 
	 * 根據實體中不為空欄位查詢資料庫中的數量
	 * 例如:UserEntity中userName='admin',password=null
	 * SELECT COUNT(a.id) FROM user AS a WHERE userName='admin'
	 * @param t 查詢條件
	 * @return 資料庫數量
	 */
	public <T> Integer queryCount(T t) {
		try {
			//建立查詢器
			CriteriaBuilder builder = enmanager.getCriteriaBuilder();
			CriteriaQuery<Long> query = builder.createQuery(Long.class);
			Root<T> root = query.from((Class<T>)t.getClass());
			
			//建立查詢條件集合
			List<Predicate> paramList =new  ArrayList<Predicate>();
			
			//反向對映
			Field[] fields = t.getClass().getDeclaredFields();
			for (Field field:fields) {
				if(java.lang.reflect.Modifier.isFinal(field.getModifiers())){
					continue;
				}
				Field.setAccessible(fields, true);
				Object object = field.get(t);
				if(object!=null){
					//新增查詢條件
					paramList.add(builder.equal(root.get(field.getName()).as(field.getType()), object));
				}
			}
			query.where(paramList.toArray(new Predicate[paramList.size()]));
			
			//返回查詢到的結果
			return enmanager.createQuery(query.select(builder.count(root))).getSingleResult().intValue();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	
	/**
	 * 
	 * 根據實體中不為空欄位分頁查詢得到List集合
	 * 例如:UserEntity中userName='admin',password=null
	 * SELECT a.* FROM user AS a WHERE userName='admin' LIMIT #{startRow},#{pageSize}
	 * @param t 查詢條件
	 * @param startRow 分頁開始位置
	 * @param pageSize 分頁結束位置
	 * @return
	 */
	public <T> List<T> queryList(T t, Integer startRow, Integer pageSize) {
		try {
			//建立查詢器
			CriteriaBuilder builder = enmanager.getCriteriaBuilder();
			CriteriaQuery<T> query = builder.createQuery((Class<T>)t.getClass());
			Root<T> root = query.from((Class<T>)t.getClass());
			
			//建立查詢條件集合
			List<Predicate> paramList =new  ArrayList<Predicate>();
			
			//反向對映
			Field[] fields = t.getClass().getDeclaredFields();
			for (Field field:fields) {
				if(java.lang.reflect.Modifier.isFinal(field.getModifiers())){
					continue;
				}
				Field.setAccessible(fields, true);
				Object object = field.get(t);
				if(object!=null){
					//新增查詢條件
					paramList.add(builder.equal(root.get(field.getName()).as(field.getType()), object));
				}
			}
			query.where(paramList.toArray(new Predicate[paramList.size()]));
			
			//返回查詢到的結果集
			return enmanager.createQuery(query.select(root)).setFirstResult(startRow).setMaxResults(pageSize).getResultList();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 根據hql查詢資料庫
	 * @param hql hql
	 * @param cls 需要查詢的entity
	 * @param args 查詢引數
	 * @return 查詢的結果集
	 */
	public<T> List<T> createHqlQuery(String hql,Class<T> cls,Object ...args) {
		TypedQuery<T> createQuery = enmanager.createQuery(hql,cls);
		for (int i = 0;args!=null&&i < args.length; i++) {
			createQuery.setParameter((i+1), args[i]);
		}
		return createQuery.getResultList();
	}

	/**
	 * 根據sql查詢資料庫的內容
	 * @param sql 原生態sql
	 * @param args 查詢引數
	 * @return 查詢的結果集
	 */
	public List<Map<String, ? extends Object>> createSqlMapQuery(String sql, Object... args) {
		Query createNamedQuery = enmanager.createNativeQuery(sql);
		for (int i = 0;args!=null&&i < args.length; i++) {
			createNamedQuery.setParameter((i+1), args[i]);
		}
		createNamedQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return createNamedQuery.getResultList();
	}
}