在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

[置顶] 数据持久层(DAO)常用功能–通用API的实现的更多相关文章

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

    在Web开发中,一般都分3层.Controller/Action 控制层,Service/Business 服务层/业务逻辑层,Dao 数据访问层/数据持久层. 在学习和工作的实践过程中,我发现很多功 ...

  2. Java数据持久层

    一.前言 1.持久层 Java数据持久层,其本身是为了实现与数据源进行数据交互的存在,其目的是通过分层架构风格,进行应用&数据的解耦. 我从整体角度,依次阐述JDBC.Mybatis.Myba ...

  3. Restful.Data v1.0 - 轻量级数据持久层组件, 正式开源发布了

    经过几个星期的优化调整,今天 Restful.Data 正式开源发布. 源码地址:https://github.com/linli8/Restful 今天不写那么多废话了,还是重新介绍一下 Restf ...

  4. c++ 数据持久层研究(一)

    C++ORM框架自动生成代码数据库  用过Java的都知道SSH框架,特别对于数据库开发,Java领域有无数的ORM框架,供数据持久层调用,如Hibernate,iBatis(现在改名叫MyBatis ...

  5. 数据持久层框架iBatis, Hibernate 与 JPA 比较

    在本文中我们介绍并比较两种最流行的开源持久框架:iBATIS和Hibernate,我们还会讨论到Java Persistence API(JPA).我们介绍每种解决方案并讨论其所规定的品质,以及在广泛 ...

  6. Java数据持久层框架 MyBatis之背景知识一

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  7. 为什么三层架构中业务层(service)、持久层(dao)需要使用一个接口?

    为什么三层架构中业务层(service).持久层(dao)需要使用一个接口? 如果没有接口那么我们在控制层使用业务层或业务层使用持久层时,必须要学习每个方法,若哪一天后者的方法名改变了则直接影响到前面 ...

  8. UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?

    选择SQLite的理由 在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的: 1,微软做的UWP应用大部分也是用Sqlite.或者说是微软 ...

  9. .NET平台下,关于数据持久层框架

    在.NET平台下,关于数据持久层框架非常多,本文主要对如下几种做简要的介绍并推荐一些学习的资源: 1.NHibernate 2.NBear 3.Castle ActiveRecord 4.iBATIS ...

随机推荐

  1. SGU 165.Basketball

    题意       输入n个在[1.95,2.05]范围内的数.       保证他们的平均数为2.00.       现在要求把这些数调整出一个顺序,       使得任意长度为K的子段和与2.00* ...

  2. 《service》-“linux命令五分钟系列”之二

    本原创文章属于<Linux大棚>博客. 博客地址为http://roclinux.cn. 文章作者为roc 希望您能通过捐款的方式支持Linux大棚博客的运行和发展.请见“关于捐款” == ...

  3. html中的空格可以用什么代替

    半角空格用 代替,全角的空格可以直接在网页里生效. 打全角空格的两种方法:1.智能ABC按v1,选择第一个2.按shift+空格切换输入法的“半.全角”状态为全角再按空格

  4. php如何计算两个时间戳之间相差的日时分秒

    /功能:计算两个时间戳之间相差的日时分秒//$begin_time 开始时间戳//$end_time 结束时间戳function timediff($begin_time,$end_time){ if ...

  5. Zookeeper的设计模式之观察者模式(十)

    Watcher是Zookeeper用来实现distribute lock, distribute configure, distribute queue等应用的主要手段.要监控data_tree上的任 ...

  6. api1

    http://www.android-doc.com/reference/android/app/Fragment.html

  7. JS获取select选中的值

    var oSel=oFl.getElementsByTagName('select')[0]; oSel.onchange=function(){ var indexselect=oSel.selec ...

  8. 一定要记住这20种PS技术!!!会让你的照片美的不行!!!

    一种简单的数码照片后期润饰 1 打开图片,执行色像/饱和度(-40)降低饱和度. 2 新建一图层,将图层模式改为柔光,用画笔工具将需要润饰的部分画几下,这里可以利用色板方便的提取颜色 3 图片色彩过渡 ...

  9. How to solve "The specified service has been marked for deletion" error

    There may be several causes which lead to the service being stuck in “marked for deletion”. Microsof ...

  10. SharePoint REST api

    http://msdn.microsoft.com/en-us/magazine/dn198245.aspx Understanding and Using the SharePoint 2013 R ...