hibernate的DAO层封装-基础功能

2019-04-08  本文已影响0人  东本三月

1.需求/目的

2.使用环境

            <!-- hibernate核心包 -->
            <dependency>
              <groupId>org.hibernate</groupId>
              <artifactId>hibernate-core</artifactId>
            </dependency>

            <!-- hibernate 提供用于连接和操作数据库的entitymanager对象 -->
            <dependency>
              <groupId>org.hibernate</groupId>
              <artifactId>hibernate-entitymanager</artifactId>
            </dependency>

            <!-- 提供数据库连接池 -->
            <dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>druid</artifactId>
              <version>1.1.10</version>
            </dependency>

            <!-- 用于将对象的属性封装到对象 -->
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
                <version>1.9.3</version>
            </dependency>

3.基础方法

   //通过注入的EntityManager来获取数据库操作对象session
   @PersistenceContext
   private EntityManager entityManager;
   //日志对象
   protected Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 获取数据库操作对象,,通过session,this.entityManager.unwrap(Session.class);
    * @return org.hibernate.Session对象
    * @time 2018年9月17日09:11:26
    * @author authstr
    */
   @Override
   public Session getSession() {
           return (Session)this.entityManager.unwrap(Session.class);
     }

   /**
    *  刷新Session对象,在进行多个实体的操作时,需要调用该方法
    *  @time 2018年9月17日09:12:21
    *  @author authstr
    */
   @Override
   public  void flushSession() {
       this.getSession().flush();
       this.getSession().clear();
   }

4.提供简单增删改操作

 /**
      * 添加/保存一个entity
     * @param entity
     * @return 主键值
     */
    @Override
    public Serializable save(Object entity) {
           //这里可以根据一些model的设置进行特定的验证或者处理
           //比如对象是否符合model接口,设置创建时间之类的
            return this.getSession().save(entity);
       }
     
    /**
     * 添加/保存多个entity
     * @param entityList
     * @return 主键id的list
     */
    @Override
    public List<Serializable> saveList(List entityList){
        List<Serializable> res=new ArrayList<Serializable>();
        for(int i=0;i<entityList.size();i++){
            res.add(this.save(entityList.get(i)));
            //每20次刷新一下session
            if(i%20==0){
                this.flushSession();
            }
        } 
        return res;
    }
    /**
      * 更新/修改一个entity
     * @param entity
     * @time 2018年9月25日16:15:25
     * @author authstr
     */
    @Override
    public void update(Object entity) {
          this.getSession().update(entity);
       }

    /** 
     * 更新/修改多个entity
     * @param entityList
     * @return 修改的数量
     * @time 2018年9月25日16:16:01
     * @author authstr
     */
    @Override
    public int updateList(List entityList) {
        for(int i=0;i<entityList.size();i++){
            update(entityList.get(i));
            //每20次刷新一下session
            if(i%20==0){
                this.flushSession();
            }
        }
        return entityList.size();
    }

-删除

    /**
     * 删除一个entity对象
     * @param entity
     * @time 2018年11月13日 上午11:24:35
     * @author authstr
     */
    @Override
    public void remove(Object entity) {
        this.getSession().remove(entity);
    }

5.Query对象的创建

    /**
     * 创建Query对象
     * @param sql sql语句
     * @param firstRows 起始数据行
     * @param maxRows 获取数据条数
     * @param returnType 结果集封装
     * @return Query对象
     * @time 2019年4月8日14:57:28
     * @author authstr
     */
    public Query createQuery(String sql,Integer firstRows,Integer maxRows,Class returnType){
        Assert.isTrue(StringUtils.hasText(sql),"sql语句必须存在",true);
        Assert.isTrue(returnType!=null,"返回值不能为空",true);
        NativeQuery query= this.getSession().createNativeQuery(sql);
        //设置返回值类型
        if(SqlResult.class.equals(returnType)){
            //原封不动的封装数据
            query.setResultTransformer(SqlResultTransformer.SQL_INSTANCE);
        }else{
            //将数据封装为HashMap
            query.setResultTransformer(MapResultTransformer.MAP_INSTANCE);
        }
        query.setResultTransformer(new MapResultTransformer());
        //设置开始行
        if(firstRows!=null){
            query.setFirstResult(firstRows);
        }
        //设置数据条数
        if(maxRows!=null){
            query.setMaxResults(maxRows);
        }
        return query;
    }
/**
 * 实体类,用于储存sql语句的结果集
 * 2019年4月8日14:19:23
 * authstr
 */
public class SqlResult  {
    private String[] aliases;
    private Object[] tuple;

    public String[] getAliases() {
        return aliases;
    }

    public void setAliases(String[] aliases) {
        this.aliases = aliases;
    }

    public Object[] getTuple() {
        return tuple;
    }

    public void setTuple(Object[] tuple) {
        this.tuple = tuple;
    }
}
/**
 * hibernate的转换类,将数据库的返回值封装成SqlResult对象
 * @time 2019年4月8日15:21:27
 * @author authstr
 *
 */
public class SqlResultTransformer extends AliasedTupleSubsetResultTransformer {

    public static final SqlResultTransformer SQL_INSTANCE = new SqlResultTransformer();

    private Object readResolve() {
        return SQL_INSTANCE;
    }

    public Object transformTuple(Object[] tuple, String[] aliases) {
        SqlResult res=new SqlResult();
        res.setAliases(aliases);
        res.setTuple(tuple);
        return res;
    }

    public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) {
        return false;
    }
}
/**
 * hibernate的转换类,将数据库的返回值封装成map
 * @author authstr
 *
 */
public class MapResultTransformer extends AliasedTupleSubsetResultTransformer {
    public static final MapResultTransformer MAP_INSTANCE = new MapResultTransformer();

    private Object readResolve() {
        return MAP_INSTANCE;
    }

    public Object transformTuple(Object[] tuple, String[] aliases) {
        HashMap<String, Object> result = new HashMap<String, Object>(tuple.length);
        for(int i=0;i<aliases.length;i++){
            String alias = aliases[i];
            if (alias != null) {
                result.put(alias, tuple[i]);
            }
        }
        return result;
    }
    public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) {
        return false;
    }
}

6.Query对象的参数设置

 /**
      * 通过数组设置查询参数,适用于用”?”来定义参数位置
     * @param query 要操作的query对象
     * @param values 数组,要替换成的值
     * @time 2018年9月25日11:27:58
     * @author authstr
     */
    public Query setQueryParameters(Query query, Object[] values) {
        //数组为空.直接返回
        if (!ObjectUtils.isExist(values)) return query;
        for(int i=0;i<values.length;i++){
            query.setParameter(i + 1, values[i]);
        }
        return query;
    }

这种方式比较方便快捷,缺点是参数较多时,sql语句参数的阅读与修改比较麻烦

/**
     * 设置query对象的一个参数
     * @param query 要操作的query对象
     * @param paramName 要替换的sql语句中的占位字符名称,如 :temp
     * @param value 要替换成的值
     * @return 被操作的query对象
     * @time 2018年9月17日09:44:24
     * @author authstr
     */
    private Query setKeyValue(Query query, String paramName, Object value) {
        //如果值是集合类型的对象,如,map,set,list,向下转型并设置
        //setParameterList方法无法使用Object作为参数,必须转成正确的类型
        if (value instanceof Collection) {
            query.setParameterList(paramName, (Collection)value);
        } else if (value instanceof Object[]) {
            //如果是数组,也向下转型
            query.setParameterList(paramName, (Object[])value);
        } else {
            query.setParameter(paramName, value);
        }
        return query;
    }
    /**
     * 通过两个数组设置query对象的参数,适用于用”:”+参数名称来定义参数位置
     * @param query 要操作的query对象
     * @param paramNames 数组,要替换的sql语句中的占位字符名称,如 :temp
     * @param values 数组,要替换成的值
     * @return 被操作的query对象
     * @time 2018年9月17日10:37:32
     * @author authstr
     */
    public Query setQueryParameters(Query query,String[] paramNames,Object[] values){
        //字段名称为空,视为使用”?”来定义参数位置
        if(!ObjectUtils.isArrayExist(paramNames)){
            return setQueryParameters(query,values);
        }
        //参数长度验证
        Assert.isTrue(paramNames.length==values.length, 
                "参数长度不一致,parm["+paramNames.length+"],value["+values.length+"]",true);
        for(int i=0;i<paramNames.length;i++){
            setKeyValue(query, paramNames[i], values[i]);
        }
        return query;
    }
    /**
     * 通过Map设置query对象的参数
     * @param query query 要操作的query对象
     * @param kv key表示要替换的sql语句中的占位字符名称,如 :temp,value表示要替换成的值
     * @return 被操作的query对象
     * @time 2018年9月17日11:12:24
     * @author authstr
     */
    public Query setQueryParameters(Query query,Map<String, Object> kv ){
        //判断map是否存在
        if(!CollectionUtils.isMapExist(kv)){
            return  query;
        }
        for (Map.Entry<String, Object> m : kv.entrySet()) {//遍历map
             this.setKeyValue(query, m.getKey(), m.getValue());
         }
        return query;
    };

7.执行sql进行查询数据

    /**
     * 执行查询语句,获取返回值(执行方法)
     * @param sql 查询sql语句
     * @param fields sql参数 属性项数组
     * @param values sql参数 属性值数组
     * @param firstRows 查询起始行数
     * @param maxRows 查询数据条数
     * @param returnType 结果集封装的类型
     * @param <T> 结果集类型
     * @return 查询结果
     * @time 2019年4月5日11:23:53
     * @author authstr
     */
    public  <T> List<T> getBySQL(String sql,String[] fields,Object[] values,Integer firstRows,Integer maxRows,Class<T> returnType){
        //获取query对象
        Query query=createQuery(sql,firstRows,maxRows,returnType);
        //设置参数
        setQueryParameters(query,fields,values);
        List li=query.list();
        List res = converListToModel(returnType, li);
        return res;
    }
    /**
     * 将map的集合,转换为指定对象的集合
     * @param clazz 要转换为的对象类型
     * @param list 原数据
     * @return 转换后的数据
     * @time 2018年10月15日 上午11:35:53
     * @author authstr
     */
    public <T> List converListToModel(Class<T> clazz, List<Map> list){
        Assert.isTrue(clazz!=null,"返回类型不能为空",true);
        //如果返回值是SqlResult或是Map,不进行处理
        if(SqlResult.class.equals(clazz)||HashMap.class.equals(clazz) || Map.class.equals(clazz)){
            return list;
        }
        List<T> res=new ArrayList(list.size());
        //检查集合
        if(!ObjectUtils.isExist(list)){
            return res;
        }
        //遍历转换
        for(Map map:list){
            try {
                T bean = clazz.newInstance();
                BeanUtils.populate(bean, map);
                res.add(bean);
            } catch (Exception e) {
                log.error("无法正确的将sql结果集的某条数据转换为["+clazz.getName()+"]类型的数据;位置:AbstractDao-converListToModel;异常原因:"+e.getMessage());
            }
        }
    
    /**
     * 使用 属性+值 的参数方式,执行查询语句,获取返回值(参数跳转)
     * @param sql 查询sql语句
     * @param kv sql参数,键为属性项数组,值为 属性值数组
     * @param firstRows 查询起始行数
     * @param maxRows 查询数据条数
     * @param returnType 结果集封装的类型
     * @param <T> 结果集类型
     * @return 查询结果
     * @time 2019年4月5日11:27:12
     * @author authstr
     */
    public  <T> List<T> getByMapSQL(String sql,Map<String,Object> kv,Integer firstRows,Integer maxRows,Class<T> returnType){
        String[] fields=new String[kv.size()];
        Object[] values=new Object[kv.size()];
        int i=0;
        //遍历Map
        for (Entry<String, Object> entry : kv.entrySet()) {
            fields[i]= entry.getKey();
            values[i]= entry.getValue();
            i++;
        }
        return getBySQL(sql,fields,values,firstRows,maxRows,returnType);
    }
/**
     * 使用 参数值 的参数方式,执行查询语句,获取返回值(参数跳转)
     * @param sql 查询sql语句
     * @param values
     * @param firstRows 查询起始行数
     * @param maxRows 查询数据条数
     * @param returnType 结果集封装的类型
     * @param <T> 结果集类型
     * @return 查询结果
     * @return
     * @time 2019年4月5日16:53:36
     * @author authstr
     */
    public  <T> List<T> getByValuesSql(String sql,Object[] values,Integer firstRows,Integer maxRows,Class<T> returnType){
        return getBySQL(sql,null,values,firstRows,maxRows,returnType);
    }
    /**
     * 执行查询语句,获取返回值(参数跳转)
     * @param sql 查询sql语句
     * @param fields sql参数 属性项数组
     * @param values sql参数 属性值数组
     * @param returnType 结果集封装的类型
     * @param <T> 结果集类型
     * @return 查询结果
     * @time 2019年4月5日17:18:59
     * @author authstr
     */
    public  <T> List<T> getBySQL(String sql,String[] fields,Object[] values,Class<T> returnType){
        return getBySQL(sql,fields,values,null,null,returnType);
    }

8.执行sql进行修改数据

    /**
     * 执行sql语句,对数据库进行操作(map参数)
     * @param sql sql语句
     * @param kv sql参数
     * @return 影响行数
     * @time 2018年11月13日 上午11:37:44
     * @author authstr
     */
    public int executeSQl(String sql,Map<String,Object> kv){
        NativeQuery query=getSession().createNativeQuery(sql);
        setQueryParameters(query, kv);
        return query.executeUpdate();
    }

    /**
     * 执行sql语句,对数据库进行操作(value参数)
     * @param sql sql语句
     * @param value sql参数
     * @return 影响行数
     * @time 2018年11月13日 上午11:39:14
     * @author authstr
     */
    public int executeSQl(String sql,Object[] value){
        NativeQuery query=getSession().createNativeQuery(sql);
        setQueryParameters(query, value);
        return query.executeUpdate();
    }
上一篇 下一篇

猜你喜欢

热点阅读