论坛首页 Java企业应用论坛

泛型dao架构实现,封装crud等基本操作

浏览 27477 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (2) :: 隐藏帖 (5)
作者 正文
   发表时间:2008-11-10  
DAO

今天闲着没事,根据公司的框架中的程序架构进行了修改增加了泛型实现

 

其中包括4个基类 BaseDao.java, BaseDAOHibernate.java,BaseManager.java,BaseManagerImpl.java

 

1. dao接口基类

 

/**
 * BaseDAO.java
 *
 *
 */
package com.easou.ad.dao;

import java.util.HashMap;
import java.util.List;

public interface BaseDAO<E> {

    /**
     * 根据主键获得实体
     * 
     * @param id 实体主键
     * @return BaseEntity
     */
    E getEntity(Long id);

    /**
     * 获得所有实体
     * 
     * @return List
     */
    List<E> getAllEntity();

    /**
     * 保存实体
     * 
     * @param entity pojo instance
     */
    void saveEntity(E entity);

    /**
     * 根据主键删除实体
     * 
     * @param id 实体主键
     */
    void removeEntity(Long id);

    public List<E> search(HashMap con ,int page,int rowsPerPage);
	public List<E> search(HashMap con);
}

 

2. dao实现类

 

/**
 * BaseDAOHibernate.java
 *
 *Copyright 2007 easou, Inc. All Rights Reserved.
 */
package com.easou.ad.dao.hibernate;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;


import com.easou.framework.util.PageList;
import com.easou.ad.dao.BaseDAO;


public abstract class BaseDAOHibernate<E> extends HibernateDaoSupport implements
        BaseDAO<E> {
    protected final Log log = LogFactory.getLog(this.getClass().getName());
    protected Class<E> clazz;
 
    public BaseDAOHibernate() {
     
        this.clazz =(Class<E>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];     
    }
    /**
     * 根据主键获得实体
     * 
     * @param id 实体主键
     * @return 实体对象
     */
    @SuppressWarnings("unchecked")
	public final E getEntity(final Long id) {
        return (E)getHibernateTemplate().get(clazz, id);
    }

    /**
     * 获得所有实体
     * 
     * @return List
     */
    @SuppressWarnings("unchecked")
    public final List<E> getAllEntity() {
        PageList result = new PageList();
        List l = getHibernateTemplate().loadAll(clazz);
        result.addAll(l);
        result.setCurrentPage(1);
        result.setPageCount(1);
        result.setTotalRowCount(l.size());
        return result;
    }

    /**
     * 保存实体
     * 
     * @param entity 实体对象
     */
    public final void saveEntity(final E entity) { 
            getHibernateTemplate().saveOrUpdate(entity);
    }

    /**
     * 根据主键删除实体
     * 
     * @param id 实体主键
     */
    public final void removeEntity(final Long id) {
        Object o = getEntity(id);
        if (null != o) {
            getHibernateTemplate().delete(o);
        }
    }

    /**
     * 执行批量更新和删除操作的HQL
     * 
     * @param sql hql语句
     * @return PageList
     */
    @SuppressWarnings("unchecked")
	protected final List<E> executeHQL(final String sql) {
        Session session = null;
        List<E> ret = null;
        try {
        	log.info(sql);
            session = this.getSession();
            if (sql.toUpperCase().startsWith("DELETE")
                    || sql.toUpperCase().startsWith("UPDATE")) {
                session.createQuery(sql).executeUpdate();
            } else {
                ret = session.createQuery(sql).list();
            }
        } catch (HibernateException e) {
            log.error("executeHQL() error:" + sql, e);
            throw convertHibernateAccessException(e);
        } finally {
            this.releaseSession(session);
        }
        return ret;
    }

    /**
     * 执行分页查询
     * 
     * @param selectField HQL语句中,SELECT 的内容(如果设置了此参数值,则sql参数中不可带SELCT语句部分)
     * @param countField HQL语句中,count 的内容
     * @param sql HQL语句
     * @param page 第几页
     * @param rowsPerPage 每页记录数
     * @return PageList
     */
    @SuppressWarnings("unchecked")
	protected final List<E> pageListQuery(final String selectField,
            String countField, String sql, int page, int rowsPerPage) {
        PageList result = new PageList();
        Session session = null;
        try {
            session = this.getSession();
            // 预留count的sql语句
            String countSql = sql.substring(sql.toUpperCase().indexOf("FROM"));
            // 设置返回的列,进行查询
            if (null != selectField) {
                sql = "SELECT " + selectField + sql;
            }
            if (page <= 0) {
                page = 1; // page最小为1
            }
            log.debug("query sql:" + sql);
            Query q = session.createQuery(sql);
            if (rowsPerPage > 0) { // rowsPerPage的值是0或-1时,都返回全部结果集
                q.setFirstResult(rowsPerPage * (page - 1));
                q.setMaxResults(rowsPerPage);
            }

            result.addAll(q.list());

            // 设置分页查询的列
            if (null == countField) {
                countField = "*";
            }

            int rowsCount = result.size();
            if (rowsPerPage > 1 && rowsCount > 0) {
                // 每页记录数大于1且结果集大于0才计算分页信息,否则当前页记录数就作为总的记录数
                // TODO 解决page值过大,可能导致rowsCount为0的问题
                countSql = "select count(" + countField + ") " + countSql;
                // 计算总记录数时,消除 Order by语句,提高性能
                int oPos = countSql.toUpperCase().indexOf("ORDER BY");
                if (oPos > 0) {
                    countSql = countSql.substring(0, oPos);
                }
                rowsCount = ((Integer) session.createQuery(countSql).iterate().next()).intValue();
            }

            if (0 == rowsCount) {
                page = 0;
            }
            if (rowsPerPage < 0) {
                page = 1;
                rowsPerPage = rowsCount;
            }

            result.setCurrentPage(page);
            result.setTotalRowCount(rowsCount);
            result.calcPageCount(rowsPerPage);

        } catch (HibernateException e) {
            log.error("pageListQuery() error:" + sql, e);
            throw convertHibernateAccessException(e);
        } finally {
            this.releaseSession(session);
        }
        return result;
    }

    /**
     * 执行分页查询
     * 
     * @param selectField HQL语句中,SELECT 的内容(如果设置了此参数值,则sql参数中不可带SELCT语句部分)
     * @param sql HQL语句
     * @param page 第几页
     * @param rowsPerPage 每页记录数
     * @param totalRowCount HQL语句获得的总记录数
     * @return PageList
     */
    @SuppressWarnings("unchecked")
    protected final PageList pageListQuery(final String selectField,
            String sql, int page, int rowsPerPage, final int totalRowCount) {
        PageList result = new PageList();
        Session session = null;
        try {
            session = this.getSession();
            // 设置返回的列,进行查询
            if (null != selectField) {
                sql = "SELECT " + selectField + sql;
            }
            if (page <= 0) {
                page = 1; // page最小为1
            }

            Query q = session.createQuery(sql);
            if (rowsPerPage > 0) { // rowsPerPage的值是0或-1时,都返回全部结果集
                q.setFirstResult(rowsPerPage * (page - 1));
                q.setMaxResults(rowsPerPage);
            }

            result.addAll(q.list());

            if (0 == totalRowCount) {
                page = 0;
            }
            if (rowsPerPage < 0) {
                page = 1;
                rowsPerPage = totalRowCount;
            }

            result.setCurrentPage(page);
            result.setTotalRowCount(totalRowCount);
            result.calcPageCount(rowsPerPage);

        } catch (HibernateException e) {
            log.error("pageListQuery() error:" + sql, e);
            throw convertHibernateAccessException(e);
        } finally {
            this.releaseSession(session);
        }
        return result;
    }

    /**
     * 执行分页查询
     * 
     * @param sql HQL语句
     * @param page 第几页
     * @param rowsPerPage 每页记录数
     * @param totalRowCount HQL语句获得的总记录数
     * @return PageList
     */
    protected final PageList pageListQuery(final String sql, final int page,
            final int rowsPerPage, final int totalRowCount) {
        return pageListQuery(null, sql, page, rowsPerPage, totalRowCount);
    }

    /**
     * 执行分页查询
     * 
     * @param sql HQL语句
     * @param rowsPerPage 每页记录数
     * @param page 第几页
     * @return PageList
     * @throws HibernateException hibernate 异常
     */
    protected List<E> pageListQuery(final String sql, final int page,
            final int rowsPerPage) throws HibernateException {
        return pageListQuery(null, null, sql, page, rowsPerPage);
    }

    /**
     * 执行分页查询
     * 
     * @param countField HQL语句中,count 的内容
     * @param sql HQL语句
     * @param rowsPerPage 每页记录数
     * @param page 第几页
     * @return PageList
     * @throws HibernateException hibernate 异常
     */
    protected List pageListQuery(final String countField, final String sql,
            final int page, final int rowsPerPage) throws HibernateException {
        return pageListQuery(null, countField, sql, page, rowsPerPage);
    }

    /**
     * 计算HQL查询的返回记录数
     * 
     * @param sql 查询语句
     * @param countField count语句操作的字段
     * @return 记录数
     */
    protected int countHQL(String sql, String countField) {

        int rowsCount = 0;
        Session session = null;
        try {
            session = this.getSession();
            if (null == countField) {
                countField = "*";
            }
            sql = "select count(" + countField + ") " + sql;
            rowsCount = ((Integer) session.createQuery(sql).iterate().next())
                    .intValue();
        } catch (HibernateException e) {
            log.error("countHQL() error:" + sql, e);
            throw convertHibernateAccessException(e);
        } finally {
            this.releaseSession(session);
        }
        return rowsCount;
    }

    /**
     * 计算HQL查询的返回记录数
     * 
     * @param sql 查询语句
     * @return 记录数
     */
    protected int countHQL(String sql) {
        return countHQL(sql, null);
    }
}

 

3. 业务逻辑基类接口

 

/**
 * BaseManager.java
 *
 * Copyright 2007 easou, Inc. All Rights Reserved.
 */
package com.easou.ad.bl;

import java.util.HashMap;
import java.util.List;

/**
 * TODO 业务逻辑基类接口
 * 
 * Revision History
 * 
 * 
 */
public interface BaseManager<E> {
    /**
     * 根据主键获得实体
     * 
     * @param id 主键id
     * @return BaseEntity
     */
    E get(Long id);

    /**
     * 获得所有实体
     * 
     * @return List
     */
    List<E> getAll();

    /**
     * 保存实体
     * 
     * @param entity pojo instance
     */
    void save(E entity);

    /**
     * 根据主键删除实体
     * 
     * @param id 实体主键
     */
    void remove(Long id);

    /**
     * 分页搜索
     * @param con
     * @param page
     * @param rowsPerPage
     * @return
     */
    public List<E> search(HashMap con ,int page,int rowsPerPage);
    /**
     * 搜索
     * @param con
     * @return
     */
	public List<E> search(HashMap con);
}

 4.业务逻辑实现基类

 

/**
 * BaseManagerImpl.java
 *
 * Copyright 2007 easou, Inc. All Rights Reserved.
 */
package com.easou.ad.bl.impl;

import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.easou.ad.bl.BaseManager;
import com.easou.ad.dao.BaseDAO;

/**
 * 业务逻辑基类
 * 
 * Revision History
 * 
 * 
 */
public class BaseManagerImpl<E,D extends BaseDAO<E>> implements BaseManager <E> {
    protected final Log log = LogFactory.getLog(getClass().getName());

    /**
     * 数据访问接口
     */
    protected D dao;

    /**
     * @return List 所有实体
     */
    public final List<E> getAll() {
        return dao.getAllEntity();
    }

    /**
     * @param id 实体主键
     * @return 实体
     */
    public final E get(final Long id) {
    
        return dao.getEntity(id);
    }

    /**
     * @param id 实体主键
     */
    public final void remove(final Long id) {
        dao.removeEntity(id);
    }
    
    public List<E> search(HashMap con, int page, int rowsPerPage) {
		return ((D)dao).search(con, page, rowsPerPage);
	}

	public List<E> search(HashMap con) {
		return ((D)dao).search(con);
	}
    /**
     * @param entity 实体
     */
    public final void save(final E entity) {
        dao.saveEntity(entity);
    }

    /**
     * 
     * @return 获取泛形
     */
    public final D getDao() {
        return dao;
    }

    /**
     * 
     * @param dao 泛形
     */
    public final void setDao(final D dao) {
        this.dao = dao;
    }
	

}

 

 

  接下来只需要实现基类,就包含了基本crud操作

   发表时间:2008-11-15  
你的代码好像有点问题啊?太复杂了。
还有一个问题就是为什么你们总喜欢用HIBERNATE呢?莫非你是做外包的/
我个人比较喜欢用Spring做底层,抑或是直接JDBC连接。
这样好控制。
0 请登录后投票
   发表时间:2008-11-18  
逆风的香1314 写道
你的代码好像有点问题啊?太复杂了。
还有一个问题就是为什么你们总喜欢用HIBERNATE呢?莫非你是做外包的/
我个人比较喜欢用Spring做底层,抑或是直接JDBC连接。
这样好控制。


所以你这辈子都不会明白ORM。
1 请登录后投票
   发表时间:2008-11-18  
楼主的abstractDao封装的方法过于少了。
其实可以整合criteria,另外一般情况下用hibernate写sql的时候比较少。

建议参照SpringSide的泛型DAO。很漂亮。
0 请登录后投票
   发表时间:2008-11-18  
EXvision 写道
楼主的abstractDao封装的方法过于少了。
其实可以整合criteria,另外一般情况下用hibernate写sql的时候比较少。

建议参照SpringSide的泛型DAO。很漂亮。

说的对,如果一个范型dao就封装这几个方法,那确实是没有必要了。
关键是整合其它一些方法,这样才能真正的减少dao数量。
0 请登录后投票
   发表时间:2008-11-27  
有这些就足够了,弄的太过于复杂反而不好用,让别人用的也不顺心,实在需要的地方,自己再定义接口另外实现
0 请登录后投票
   发表时间:2008-11-27  
这是项目中使用的很久的代码,没有问题
0 请登录后投票
   发表时间:2008-12-02  
楼主这个万一主键是字符串类型怎么办呢?
0 请登录后投票
   发表时间:2008-12-04  
我认为这样就很不错,因为楼主说了吗只是关乎CRUD的BaseDAO
0 请登录后投票
   发表时间:2008-12-04  
呵呵,上面的兄弟说的很对 ,万一是字符窜就麻烦了, 可以改进下把主键类型也范型就可以了
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics