文档章节

数据持久层(DAO)通用API的实现

FansUnion
 FansUnion
发布于 2015/05/03 01:31
字数 1165
阅读 171
收藏 0

在Web开发中,一般都分3层。
Controller/Action 控制层,
Service/Business 服务层/业务逻辑层,
Dao 数据访问层/数据持久层。

在学习和工作的实践过程中,我发现很多功能是比较通用的,我们可以把他们抽象成API接口。

下文通过一段较长的代码,Hibernate实现,来展示如何设计一些通用的API。

说明:代码只是起到一个示范(Demo)的作用,实际上完全可以做得更强大。
我最近已经在现在的基础上大大改进了,现在把比较基础的实现分享给大家。

package cn.fansunion.demo.db.dao; 

import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; 

import javax.annotation.Resource; 

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory; 

import cn.fansunion.common.util.EmptyUtils; 

/**
* Dao的父类。采用泛型,实现了 一些通用的功能,大大减少了子类代码的重复。 

* 目前只能适用于1个表或实体。
*
* @author leiwen@fansunion.cn
*/
public abstract class BaseDao<T> { 

    private Class<T> modelClazz; 

    @Resource
    private SessionFactory sessionFactory; 

    // ////////////////////////////////////////////////////////////// 

    public BaseDao() {
        this.modelClazz = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    } 

    // //////////////////////////////////////////////////////
    // //////////////////////泛型方法-CRUD/////////////////////////
    // ///////////////////////////////////////////////////// 

    /**
     * 根据主键查询
     *
     * @param id
     *            主键
     * @return 实体对象
     */
    public T get(Integer id) {
        T entity = (T) getCurrentSession().get(modelClazz, id);
        return entity;
    } 

    /**
     * 增加
     *
     * @param entity
     *            实体对象
     */
    public void add(T entity) {
        getCurrentSession().save(entity); 

    } 

    /**
     * 物理删除
     *
     * @param entity
     *            实体对象
     */
    public void delete(T entity) {
        getCurrentSession().delete(entity);
    } 

    /**
     * 更新
     *
     * @param entity
     *            持久态的实体对象
     */
    public void update(T entity) {
        getCurrentSession().update(entity);
    } 

    /**
     * 逻辑删除
     *
     * @param id
     *            主键
     */
    public void remove(Integer id) { 

        Session session = getCurrentSession();
        String sql = "update " + modelClazz
                + " set isDeleted = 1 where id = :id";
        Query query = session.createQuery(sql);
        query.setParameter("id", id);
        query.executeUpdate(); 

    } 

    // ///////////////////////////////////////////////
    // ////////////获取记录总数/////////////////////////
    // ///////////////////////////////////////////////
    /**
     * 获得1个整数
     *
     * @param hql
     *            hql语句
     * @return 1个整数
     */
    protected Integer getCount(String hql) {
        Integer count = 0;
        Query query = createQuery(hql);
        count = getCount(query);
        return count;
    } 

    protected Integer getCount(String hql, String key, Object value) {
        Integer count = 0;
        Query query = createQuery(hql, key, value);
        count = getCount(query);
        return count;
    } 

    // 带参数的hql语句
    protected Integer getCount(String hql, Map<String, Object> params) {
        Integer count = 0;
        Query query = createQuery(hql, params);
        count = getCount(query);
        return count;
    } 

    private Integer getCount(Query query) {
        Integer count = 0;
        Object uniqueResult = query.uniqueResult();
        if (uniqueResult != null) {
            count = Integer.parseInt(uniqueResult.toString());
        }
        return count;
    } 

    // ///////////////////////////////////////////////
    // ////////////获取一个对象/////////////////////////
    // ///////////////////////////////////////////////
    protected List findByProperty(String name, Object value) {
        String hql = "from " + modelClazz.getSimpleName() + " where " + name
                + "=" + ":" + name;
        return executeQueryList(hql, name, value);
    } 

    protected T executeQueryUnique(String hql) {
        T result = null;
        List<T> list = executeQueryList(hql);
        if (list != null && list.size() >= 1) {
            result = list.get(0);
        }
        return result;
    } 

    protected T executeQueryUnique(String hql, String key, Object value) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(key, value);
        return executeQueryUnique(hql, params);
    } 

    // 根据属性获得对象
    protected T executeQueryUnique(String hql, String key1, Object value1,
            String key2, Object value2) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(key1, value1);
        params.put(key2, value2);
        return executeQueryUnique(hql, params);
    } 

    protected T executeQueryUnique(String hql, Map<String, Object> params) {
        T result = null;
        List<T> list = executeQueryList(hql, params);
        if (EmptyUtils.isNotEmpty(list)) {
            result = list.get(0);
        }
        return result;
    } 

    // ///////////////////////////////////////////////
    // //////////////获取一个列表(不使用泛型 List<T>)/////////////////
    // ///////////////////////////////////////////////
    // 执行不带参数的hql查询,返回一个结果集List
    protected List executeQueryList(String hql) {
        return executeQueryList(hql, null);
    } 

    protected List executeQueryList(String hql, String key, Object value) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(key, value);
        return executeQueryList(hql, params);
    } 

    protected List executeQueryList(String hql, String key1, Object value1,
            String key2, Object value2) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(key1, value1);
        params.put(key2, value2);
        return executeQueryList(hql, params);
    } 

    protected List executeQueryList(String hql, Map<String, Object> params) {
        return executeQueryList(hql, params, -1, -1);
    } 

    protected List executeQueryList(String hql, Integer firstResult,
            Integer maxResults) {
        return executeQueryList(hql, null, firstResult, maxResults);
    } 

    protected List executeQueryList(String hql, String key, Object value,
            Integer firstResult, Integer maxResults) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(key, value);
        return executeQueryList(hql, params, firstResult, maxResults);
    } 

    // 执行带参数并且含有分页的hql查询
    protected List executeQueryList(String hql, Map<String, Object> params,
            Integer firstResult, Integer maxResults) {
        Query query = createQuery(hql, params);
        if (firstResult > 0) {
            query.setFirstResult(firstResult);
        } 

        if (maxResults > 0) {
            query.setMaxResults(maxResults);
        } 

        return query.list();
    } 

    // ///////////////////////////////////////////////
    // ////////////更新操作/////////////////////////
    // /////////////////////////////////////////////// 

    protected int executeUpdate(String hql) {
        return executeUpdate(hql, null);
    } 

    protected int executeUpdate(String hql, String key, Object value) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(key, value);
        return executeUpdate(hql, params);
    } 

    protected int executeUpdate(String hql, String key1, Object value1,
            String key2, Object value2) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(key1, value1);
        params.put(key2, value2);
        return executeUpdate(hql, params);
    } 

    // 执行带参数的hql更新语句
    protected int executeUpdate(String hql, Map<String, Object> params) {
        Query query = createQuery(hql, params);
        return query.executeUpdate();
    } 

    // ///////////////////////////////////////////////
    // ////////////创建Query对象/////////////////////////
    // ///////////////////////////////////////////////
    private Query createQuery(String hql, Map<String, Object> params) {
        Query query = getCurrentSession().createQuery(hql);
        if (params != null) {
            Set<Entry<String, Object>> entrySet = params.entrySet();
            for (Map.Entry<String, Object> entry : entrySet) {
                Object value = entry.getValue();
                String key = entry.getKey();
                if (value instanceof Collection) {
                    query.setParameterList(key, (Collection) value);
                } else if (value instanceof Object[]) {
                    query.setParameterList(key, (Object[]) value);
                } else {
                    query.setParameter(key, value);
                }
            }
        }
        return query;
    } 

    private Query createQuery(String hql, String key, Object value) {
        Query query = getCurrentSession().createQuery(hql);
        if (key != null) {
            query.setParameter(key, value);
        }
        return query;
    } 

    private Query createQuery(String hql) {
        return getCurrentSession().createQuery(hql);
    } 

    /**
     * 获取主数源
     */
    protected Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    } 

}


在工作和学习的实践中,我发现Web开发有很大程度上的通用性。

我希望,也在努力地总结这些规律,争取早点弄出一套可以大大提高生产力的方法和代码框架。

技术不能改变程序员的命运,而生产力可以。

提高生产力,是我目前迫切的追求。

过去,现在和未来,我都将为之而努力。

我的博客网站:http://FansUnion.cn

原文参见:http://fansunion.cn/articles/2264

© 著作权归作者所有

FansUnion
粉丝 60
博文 858
码字总数 825464
作品 0
丰台
高级程序员
私信 提问
DAO层,Service层,Controller层、View层详解

本文转载自http://www.jianshu.com/p/403acf6df656 1、Dao层 Dao层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,Dao层的设计首先是设计Dao的接口,然后在Spring的配...

武小猪
2018/06/26
0
0
说说 Spring DAO 的设计思想

DAO (Data Access Object )是访问数据的对象,它不但屏蔽了不同的数据存储介质(数据库、文件或 LDAP 等),也屏蔽了具体的实现技术 。 我们只要为数据访问定义好 DAO 接口,然后使用具体技...

deniro
2018/09/23
0
0
SpringBoot+Dubbo+Mybatis 项目升级版本(Gradle)

按最近公司的架构,自己搭建这样个样例。主要是将服务API层进行了区分,解耦接口与模型层. 其中pojo层与vo层都是用来传递参数用法,API-facade层与service是两个概念。API-facade层有统一的规...

唐代de豆腐
2016/05/18
1K
0
由Spring应用的瑕疵谈谈DDD的概念与应用(二)

在上一篇文章中,通过Spring Web应用的瑕疵引出改善的措施,我们讲解了领域驱动开发的相关概念和设计策略。本文主要讲解领域模型的几种类型和DDD的简单实践案例。 架构风格 在《实现领域驱动...

aoho
04/15
0
0
图解JavaWeb开发模式及MVC

疑问区? 1.在JavaWeb开发中将MVC与业务层、持久层、表现层相结合的运用有何好处? 用三层架构可以降低层与层之间的耦合度。 2.Servlet是如何是如何调用业务层的呢?(说明过程) 通过接口一...

鲁雯雪
2013/11/08
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

以太坊中文文档翻译-区块

本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读。 区块(Blocks) 区块相关的 API,接口的参数说明请参考Etherscan API 约定, 文档中不单独...

Tiny熊
34分钟前
1
0
Linux 内核的一个问题

是virtio 驱动,但是没有启动 virtio-mmio virtio-mmio.0: Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.....[ 1.047924] md: ... autorun......

MtrS
57分钟前
2
0
MySQL主从配置

17.1 MySQL主从介绍 17.2 准备工作 17.3 配置主 17.4 配置从 17.5 测试主从同步 一、 MySQL主从介绍

tobej
今天
2
0
读书replay《博弈与社会》.1.20190526

前情 《美丽心灵》,一部讲数学家约翰·福布斯·纳什的电影,我第一次听到博弈理论就是在这部电影里。看过电影之后就一直想知道,博弈论究竟讲了什么。很久之后,20190417这天,我刷JD的购物...

wanxiangming
今天
2
0
iOS TableView层级结构剖析

首先上图 下面来分析一下tableView的层级结构 tableView的组成: 1.整个tableView有且仅有一个头部和尾部就是tableViewHeadView和tableViewFooterView2.tableView 可以有多个section,一个s...

HOrange
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部