在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. java的动态绑定与双分派(规避instanceof)

    1. 动态绑定的概念 指程执行期间(而不是在编译期间)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法 . 例如: package org.demo.clone.demo; public c ...

  2. jQuery慢慢啃筛选(四)

    1.eq(index|-index) 获取第N个元素 其中负数:一个整数,指示元素的位置,从集合中的最后一个元素开始倒数.(1算起) $("p").eq(1)//获取匹配的第二个元 ...

  3. java中的异常结构

    1.基类为Throwable. 2.Error和Exception分别继承Throwable. 3.Error类异常描述了Java运行系统中的内部错误以及资源耗尽的情形.应用程序不应该抛出这种类型的对 ...

  4. js 强制转换

    强制转换为布尔类型: <script> var text =Boolean(0) //=>以下转换的类型都为false text = Boolean(0.0) text = Bool ...

  5. phpexcel 一些基本的设置 (表格的基本属性)

    网址是:http://www.thinkphp.cn/code/1893.html

  6. 每个Linux新手都应该记住的10个基本Linux命令

    Linux对我们的生活有着很大的影响.至少,你的安卓手机上面就有Linux内核.然而,头一次入手Linux只会让你觉得不适.因为在Linux上,你通常应该使用终端命令,而不是只要点击启动器图像(就像你 ...

  7. 矩形嵌套问题-ACM集训

    参考 http://blog.csdn.net/xujinsmile/article/details/7861412 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形 ...

  8. QTP插入Output Value和插入CheckPoint,注意点

    1. 必须打开程序才能进行Output value和CheckPoint的插入. 2. 也有可能是对象获取不到,从新加载对象库. 提示如下图:

  9. CSS Hack技术详解,支持IE 6-11、Chrome、FireFox、Safari、Opera 6-11、Chrome、FireFox、Safari、Opera6-11、Chrome、FireFox、Safari、Opera6-11、Chrome、FireFox、Safari、Opera

    转自: http://www.365mini.com/page/css-hack-ie-chrome-firefox-safari-opera.htm 当前网络时代,各种各样的网页向我们展示着丰富多彩 ...

  10. orcad中的PSpice仿真加入厂商模型

      <1>首先要知道原理图的符号是没有模型的,不是你肆意妄为就可以拉来仿真的. <2>其次要知道很多器件软件中是没有模型的. <3>有很多获取模型的方法:<使 ...