现在的位置: 首页 > 综合 > 正文

数据访问层常用操作的JPA实现

2012年08月12日 ⁄ 综合 ⁄ 共 9287字 ⁄ 字号 评论关闭

  针对数据的增删改查,使用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

 

抱歉!评论已关闭.