基于 {@link EntityManager} 的数据库操作方法集

基于 {@link EntityManager} 的数据库操作方法集。

package com.kinth.scheduler.service;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import javax.persistence.Parameter;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import org.springframework.data.jpa.repository.query.QueryUtils;
import org.springframework.transaction.annotation.Transactional;
import com.kinth.common.util.Tools;
/**
 * 基于 {@link EntityManager} 的数据库操作方法集
 */
@Named
public class EntityManagerService {

    @Inject
    private EntityManager entityManager;

    /**
     * 绑定query命名参数的值
     * @param query
     * @param paramMap
     * @return
     */
    private Query setQueryParameters(Query query, Map<String, Object> paramMap) {
        // 根据query的参数集设置各个参数值
        Set<Parameter<?>> set = query.getParameters();
        Iterator<Parameter<?>> i = set.iterator();
        while (i.hasNext()) {
            String param = i.next().getName();
            query.setParameter(param, paramMap.get(param));
        }
        return query;
    }

    /**
     * JPQL分页查询 : 加载分页数据
     * 
     * @param jpql
     * @param paramMap
     * @param page
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<Object> loadPage(String jpql, Map<String, Object> paramMap, Integer page, Integer pageSize) {
        page = (page == null || page == 0 ? 1 : page);
        pageSize = (pageSize == null || pageSize == 0 ? 10 : pageSize);
        Query query = entityManager.createQuery(jpql);
        this.setQueryParameters(query, paramMap);
        query.setFirstResult((page - 1) * pageSize);
        query.setMaxResults(pageSize);
        List<Object> list = query.getResultList();
        return list;
    }

    /**
     * JPQL分页查询 : 统计记录总数
     * 
     * @param jpql
     * @param paramMap
     * @return
     */
    public int count(String jpql, Map<String, Object> paramMap) {
        String t = QueryUtils.createCountQueryFor(jpql);
        TypedQuery<Long> query = entityManager.createQuery(t, Long.class);
        this.setQueryParameters(query, paramMap);
        Long total = query.getSingleResult();
        return total.intValue();
    }


    /**
     * SQL查询结果列表:执行原生查询SQL或存储过程
     * <br>注:sqlserver 的存储过程首行加上 SET NOCOUNT ON
     * @param sql
     * @param paramMap
     * @param page
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<Object> executeNativeQuery(String sql, Map<String, Object> paramMap) {
        Query query = entityManager.createNativeQuery(sql);
        this.setQueryParameters(query, paramMap);
        List<Object> list = query.getResultList();
        return list;
    }

    /**
     * SQL查询结果列表:执行原生查询SQL或存储过程
     * <br>注:sqlserver 的存储过程首行加上 SET NOCOUNT ON
     * @param sql
     * @param paramMap
     * @param clazz
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> executeNativeQuery(String sql, Map<String, Object> paramMap, Class<T> clazz) {
        Query query = entityManager.createNativeQuery(sql);
        this.setQueryParameters(query, paramMap);
        List<T> list = query.getResultList();
        return list;
    }

    /**
     * SQL查询单个结果:执行原生查询SQL或存储过程
     * @param sql
     * @param paramMap
     * @param page
     * @return
     */
    public Object getSingleResultByNativeQuery(String sql, Map<String, Object> paramMap) {
        Query query = entityManager.createNativeQuery(sql);
        this.setQueryParameters(query, paramMap);
        Object result = query.getSingleResult();
        return result;
    }

    /**
     * SQL更新或删除:执行原生查询SQL
     * @param sql
     * @param paramMap
     * @param page
     * @return
     */
    @Transactional
    public int updateByNativeQuery(String sql, Map<String, Object> paramMap) {
        Query query = entityManager.createNativeQuery(sql);
        this.setQueryParameters(query, paramMap);
        int count = query.executeUpdate();
        return count;
    }

    /**
     * 通过NamedQeury查询一条记录
     * @param queryName
     * @param params
     * @param clazz
     * @return
     */
    public Object findOneEntity(String queryName, String params) {
        if (Tools.emptyRequestParameter(params)) {
            return null;
        }

        Query query = entityManager.createNamedQuery(queryName);

        String[] paramArr = params.split(",");
        for (int i=0 ; i<paramArr.length ; i++) {
            query.setParameter(i+1, paramArr[i]);
        }

        List<?> resultList = query.getResultList();
        if (resultList == null || resultList.size() == 0) {
            return null;
        }

        return resultList.get(0);
    }

    /**
     * 通过属性值查询实体
     * @param entity
     * @param properties
     * @return
     */
    public Object findOneEntityByProperty(Object entity, String properties) {
        if (Tools.emptyRequestParameter(properties)) {
            return null;
        }

        String canonicalName = entity.getClass().getCanonicalName();
        String[] canonicalNameSplit = canonicalName.split("\\.");
        String entityName = canonicalNameSplit[canonicalNameSplit.length - 1];

        String[] propertyArr = properties.split(",");
        String jpql = "select entity"
                + " from " + entityName + " entity"
                + " where ";
        int i;
        for (i=0 ; i<propertyArr.length ; i++) {
            jpql += "entity."+propertyArr[i]+" = ?"+ (i+1) +" and ";
        }
        jpql = jpql.substring(0, jpql.length() - " and ".length());

        Query query = entityManager.createQuery(jpql);
        for (i=0 ; i<propertyArr.length ; i++) {
            query.setParameter(i+1, getEntityProperty(entity, propertyArr[i]));
        }

        List<?> resultList = query.getResultList();
        if (resultList == null || resultList.size() == 0) {
            return null;
        }

        return resultList.get(0);
    }

    /**
     * 通过jpql查询实体
     * @param jpql
     * @param params
     * @return
     */
    public Object findOneEntityByJpql(String jpql, String params) {
        Query query = entityManager.createQuery(jpql);
        if (!Tools.emptyRequestParameter(params)) {
            String[] paramArr = params.split(",");
            for (int i = 0 ; i < paramArr.length ; i++) {
                query.setParameter(i+1, paramArr[i]);
            }
        }

        List<?> resultList = query.getResultList();
        if (resultList == null || resultList.size() == 0) {
            return null;
        }

        return resultList.get(0);
    }

    /**
     * 设置对象的id
     * @param id
     * @param entity
     */
    public void setEntityId(Object id, Object entity) {
        Method idGetter = null;
        Method[] methods = entity.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(Id.class)) {
                idGetter = method;
                break;
            }
        }

        if (idGetter == null) {
            return;
        }

        Class<?> clazz = entity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), clazz);
                Method getMethod = propertyDescriptor.getReadMethod();
                if (getMethod.equals(idGetter)) {
                    Method setMethod = propertyDescriptor.getWriteMethod();
                    setMethod.invoke(entity, id);
                    return;
                }
            } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                // do nothing
            }

        }
    }

    /**
     * 获取对象的id
     * @param entity
     * @return
     */
    public Object getEntityId(Object entity) {
        Method[] methods = entity.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(Id.class)) {
                try {
                    Object id = method.invoke(entity);
                    return id;
                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    break;
                }
            }
        }

        return null;
    }

    /**
     * 获取实体的属性值
     * @param entity
     * @param property
     * @return
     */
    public Object getEntityProperty(Object entity, String property) {
        Class<?> clazz = entity.getClass();
        try {
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(property, clazz);
            Method getMethod = propertyDescriptor.getReadMethod();
            Object id = getMethod.invoke(entity);
            return id;
        } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 合并两个实体
     * @param originEntiy
     * @param newEntity
     */
    public void mergeEntity(Object originEntiy, Object newEntity) {
        Class<?> clazz = newEntity.getClass();

        Field[] fields = newEntity.getClass().getDeclaredFields();
        for (Field field : fields) {
            try {
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), clazz);
                Method getter = propertyDescriptor.getReadMethod();
                Object fieldValue = getter.invoke(newEntity);
                if (fieldValue != null) {
                    Method setter = propertyDescriptor.getWriteMethod();
                    setter.invoke(originEntiy, fieldValue);
                }
            } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                // do nothing
            }
        }
    }

    /**
     * 持久化实体,首先通过属性(多个属性用,分隔)查找实体是否存在,如果存在则更新实体,否则insert
     * @param entity
     * @param queryProperty
     * @throws ClassNotFoundException
     */
    @Transactional
    public void persistSingleEntity(Object entity,String queryProperty) throws ClassNotFoundException {
        Object dbEntity = this.findOneEntityByProperty(entity, queryProperty);
        if (dbEntity != null) {
            Object id = this.getEntityId(dbEntity);
            this.setEntityId(id, entity);
            entityManager.merge(entity);
        } else {
            entityManager.persist(entity);
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一次写博客,那是因为我想与大家分享.Net世界.我原来是ASP程序员,与.Net结缘那是在两年多前.第一次接触它,就喜欢上了.哈哈 接着我给大家分享一下我在项目中用到的数据访问层,这个是我用微软网站上得到的DBHepler数据库访问层的一次改编,让它支持实体类和用表达 式的方式生成SQL,而且更关键的是,他是采用参数的方式传值的,这样就避免了SQL的注入啦.. 以下是这个项目的结构 [SuperDAL] ---DbHelper.cs(来自MSDN的数据访问层) ---EntityManager.cs(实体类管理) ---Expressions.cs(实体类表达式查询) ---Expression.cs(实体类表达式) ---OrderByExpressions.cs(排序表达式查询) ---OrderByExpression.cs(排序表达式) ---ObjectValues -------OrderBy.cs(排序枚举类) ---DBManager.cs(数据访问类管理) ---DbParams.cs(数据库访问类参数) ---DataTableExtensions.cs(这个就是顾名思义啦,DataTable传实体类) 在这里最主要介绍的就是EntityManager这个啦,使用方法如下: 有数据库DB的一张表Customs CREATE TABLE [Customs] ( [Name] [varchar] (20) , [Password] [varchar] (20) , [Email] [varchar] (50) , [Phone] [varchar] (11) NULL , [Old] [int] , [Birthday] [DateTime] ) 有个实体类Customs.cs,结构如下: public class Customs { public string Name {get;set;} public string Password {get;set;} public string Email {get;set;} public string Phone {get;set;} public int Old{get;set} public DateTime Brithday {get;set;} } 数据库表与实体Customs结构是一一对应的.有了实体类CUstoms,下面就可以操作实体类跟操作数据库一样的啦,我们新建一个实体类管理类 CustomsManager.cs public class CustomsManager:EntityManager { public Customs GetByName(string name) { //创建表达式Expressions Expressions exps=new Expressions(); //向表达式添加条件 exps.Eq("name",name); //根据条件查询返回实体类 return EM_GetUnique(exps); } public List SearchByName(string name) { //同样像上面一样建立表达式类 Expressions exps=new Expressions(); exps.Like("name",name);//当然,有年朋友会说如果我要姓为"陈"的,那有些人的名字带陈的怎么办,没关系,可以改为 exps.LeftLike ("name",name); //根据条件查询返回实体类 return EM_GetEntity(exps); } /// /// 登录 /// /// 用户名 /// 密码 public List Login(string name,string password) { Expressions exps=new Expressions(); exps.Eq("name",name); exps.Eq("password",password); return EM_GetEntity(exps); } /// /// 选择年龄大于指定岁数的,并按年龄从小到大排序 /// /// 年龄 public List SelectOlder(int old) { Expressions exps=new Expressions(); exps.Gt("old",old); exp.OrderBys.Add("old", OrderBy.Asc); return EM_GetEntity(exps); } /// /// 选择年龄大于小于指定岁数段的,并按年龄从小到大,姓名从字母升序排序 /// /// 年龄 public List SelectByOld(int oldStart,int oldend) { Expressions exps=new Expressions(); exps.Between("old",oldStart,oldEnd); exp.OrderBys.Add("old", OrderBy.Asc); exp.OrderBys.Add("name",OrderBy.Asc); return EM_GetEntity(exps); } #region 增删改 操作 /// /// 更新操作 /// /// 实体类 public int Update(Customs customs) { return EM_Save(customs);//返回更新的记录数,当然,一般成功执行就会返回1;也可以改上面为public void Update(Customs customs) } /// /// 删除操作 /// /// public int DeleteByName(string name) { Expressions exps=new Expressions(); exps.Eq("name",name); return EM_Delete(exps); } /// /// 删除操作 /// /// 实体类 public int Save(Customs custom) { return EM_Save(custom); } #endregion } 当然还有更多的也就不一一贴出来了 Expressions支持的表达式有 1. Eq (等于)[name=value] 2. NotEq (不等于)[not name = value] 3. Ge (大于等于)[name >=value] 4. Gt (大于)[name>value] 5. Le (小于等于)[name<=value] 6. Lt (小于)[name<value] 7. In (包括)[name in (value)] 8. NotIn (不包括)[not name in (value) 9. IsNotNull (不为NULL)[not name is null] 10. IsNull (等于NULL)[name is null] 11. Between (之间)[name between valueStart and valueEnd] 12. Like (模糊) [name like ‘%value%’ ] 13. LeftLike (左模糊) [name like ‘%value’] 14. RightLike (右模糊) [name like ‘value%’] 其它功能待与Net爱好者探讨啦,希望你有更好的思路
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值