数据访问层常用操作的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);


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