论坛首页 Java企业应用论坛

关于 DAO 接口设计的思考

浏览 23939 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-04-23  
BirdGu 写道
public interface BaseDao<T> {
    public void create (T t);
    public void delete (T t);
    public void update (T t);
}

public interface WindDao extends BaseDao<Wind> {
    public void other (Wind wind);
}


不明白为什么说用范型好,假设可以用范型。
请原谅我的无知。
0 请登录后投票
   发表时间:2007-04-23  
fsinbad 写道
BirdGu 写道
public interface BaseDao<T> {
    public void create (T t);
    public void delete (T t);
    public void update (T t);
}

public interface WindDao extends BaseDao<Wind> {
    public void other (Wind wind);
}


不明白为什么说用范型好,假设可以用范型。
请原谅我的无知。

    是不是因为:   简化开发,代码量减少,同时后面的类型检查也可以防止出错。。。
有个疑问,应用泛型后会不会对性能造成影响?
想起一个笑话:java的某种技术使开发量降低20%,整个社区无不欢欣鼓舞,虽然运行时性能降低了10%
            c++的某种技术使运行时性能降低0.1%,被骂的无处藏身。。。。
0 请登录后投票
   发表时间:2007-08-01  
hanny0918 写道
我们公司就是用反射,觉得还可以啦!

能详细说说怎么实现的吗?
0 请登录后投票
   发表时间:2007-08-01  
去年年底开始用泛型写基础DAO了,效果很好
/*
 * Created on 2006-07-xx
 *
 */
package net.yigoware.common.dao.impl.hibernate;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import net.yigoware.common.dao._BaseDAO;
import net.yigoware.common.exception.ObjectNotFoundException;
import net.yigoware.common.util.MyBeanUtils;
import net.yigoware.common.util.PageInfo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

// 这个不能算是渗透哦,没办法,common beanutils没法解决
// import com.opensymphony.util.BeanUtils;

/**
 * 
 * @author Yigo
 * @createdate 2006-07-xx
 * @param <T>
 * @param <ID>
 */
abstract public class _BaseDAOImplHibernate<T, ID extends Serializable> extends
		HibernateDaoSupport implements _BaseDAO<T, ID> {
	@SuppressWarnings("unused")
	private static final Log log = LogFactory
			.getLog(_BaseDAOImplHibernate.class);

	private Class<T> objectClass;

	private _BaseDAOImplHibernate() {

	}

	// protected abstract String getUniqueKeyName();

	/**
	 * @param objectClass
	 */
	public _BaseDAOImplHibernate(Class<T> objectClass) {
		this.objectClass = objectClass;
	}

	public T findById(ID id) throws ObjectNotFoundException {
		// log.debug("getting instance with id: " + id);
		try {
			T instance = (T) getHibernateTemplate().get(objectClass, id);
			if (null == instance) {
				throw new ObjectNotFoundException(objectClass, id);
			}
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	public T findDetailsById(ID id) throws ObjectNotFoundException {
		T instance = findById(id);
		getHibernateTemplate().initialize(instance);
		return instance;
	}

	public T findByUniqueKey(String keyName, Serializable key)
			throws ObjectNotFoundException {
		log.debug("read instance by uniquekey - " + keyName + ": " + key);
		try {
			DetachedCriteria detachedCriteria = DetachedCriteria
					.forClass(this.objectClass);
			// log.debug("this.objectClass:" + this.objectClass);
			detachedCriteria = detachedCriteria
					.add(Expression.eq(keyName, key));
			List<T> list = this.getHibernateTemplate().findByCriteria(
					detachedCriteria);

			// log.debug("list:" + list);
			if (list.size() == 0) {
				log.error("not found!");
				throw new ObjectNotFoundException(this.objectClass, key);
			} else if (list.size() > 1) {
				// throw new NotUniqueKeyException();
				// return null;
				throw new RuntimeException("RuntimeException:NotUniqueKey");
			} else {
				return list.get(0);
			}
		} catch (RuntimeException e) {
			log.error("readByUniqueKey failed", e);
			throw e;
		}
	}

	public List<T> findAll() {
		// log.debug("findAll");
		try {
			return this.getHibernateTemplate().loadAll(this.objectClass);
		} catch (RuntimeException e) {
			log.error("findAll failed", e);
			throw e;
		}
	}

	/**
	 * 
	 */
	public List<T> findByExample(Map<String, Object> values) {
		// log.debug("finding instance by example");
		try {
			// List results =
			// this.getHibernateTemplate().findByExample(instance);
			// TODO 3.2 不需要不必要的初始化
			Class<T> c = null;
			T object = null;
			try {
				object = c.newInstance();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for (String key : values.keySet()) {
				MyBeanUtils.setValue(object, key, values.get(key));
			}
			// List<T> results = getSession().createCriteria(
			// this.objectClass.getName()).add(Example.create(instance))
			// .list();
			List<T> results = getSession().createCriteria(
					this.objectClass.getName()).add(Example.create(object))
					.list();
			// log.debug("find by example successful, result size: "
			// + results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	/**
	 * 根据查询条件查询的方法
	 */
	public List<T> findByCriteria(DetachedCriteria criteria) {
		try {
			List<T> results = getHibernateTemplate().findByCriteria(criteria);
			// log.debug(results);
			return results;
		} catch (RuntimeException re) {
			log.error("find by Criteria failed", re);
			throw re;
		}
	}

	/**
	 * 支持分页的查询,测试中
	 */

	// public List<T> findByCriteria(final DetachedCriteria detachedCriteria,
	// final int pageSize, final int startIndex) {
	// try {
	// List<T> results = getHibernateTemplate().findByCriteria(
	// detachedCriteria, pageSize, startIndex);
	// return results;
	// } catch (RuntimeException re) {
	// log.error("find by Criteria failed", re);
	// throw re;
	// }
	// }
	// public List<T> findByCriteria(DetachedCriteria criteria, int firstResult,
	// int maxResults);
	public List<T> findByCriteria(final DetachedCriteria criteria,
			final int pageSize, final int startIndex) {
		try {
			List<T> results = getHibernateTemplate().findByCriteria(criteria,
					startIndex, pageSize);
			// log.debug(results);
			return results;
		} catch (RuntimeException re) {
			log.error("find by Criteria failed", re);
			throw re;
		}
	}

	@SuppressWarnings("unchecked")
	public PageInfo<T> findPageByCriteria(
			final DetachedCriteria detachedCriteria, final int pageSize,
			final int startIndex) {

		// int totalCount = getHibernateTemplate()
		// .findByCriteria(detachedCriteria).size();
		// List<T> list =
		// getHibernateTemplate().findByCriteria(detachedCriteria,
		// startIndex, pageSize);
		// return new PageInfo<T>(list, totalCount, pageSize, startIndex);

		return (PageInfo<T>) getHibernateTemplate().execute(
				new HibernateCallback() {
					@SuppressWarnings("unchecked")
					public PageInfo<T> doInHibernate(Session session)
							throws HibernateException {
						Criteria criteria = detachedCriteria
								.getExecutableCriteria(session);

						if (startIndex >= 0) {
							criteria.setFirstResult(startIndex);
						}
						if (pageSize > 0) {
							criteria.setMaxResults(pageSize);
						}
						List<T> list = criteria.list();

						criteria.setFirstResult(0);
						criteria.setMaxResults(999);

						// criteria.setFirstResult(0).setMaxResults(maxResults);
						int totalCount = ((Integer) criteria.setProjection(
								Projections.rowCount()).uniqueResult())
								.intValue();
						// criteria.setProjection(null);
						// log.debug(totalCount);
						// log.debug(pageSize);
						// log.debug(startIndex);
						PageInfo<T> ps = new PageInfo<T>(list, totalCount,
								pageSize, startIndex);
						return ps;
					}
				}, true);
	}

	public void create(T transientInstance) {
		log.debug("create... transientInstance" + transientInstance);
		try {
			getHibernateTemplate().save(transientInstance);
			// log.debug("create successful");
		} catch (RuntimeException re) {
			log.error("create failed", re);
			throw re;
		}
	}

	public void update(ID id, Map<String, Object> values)
			throws ObjectNotFoundException {
		// log.debug("update transientInstance");
		try {
			T cacheObject = this.findById(id);
			for (String key : values.keySet()) {
				MyBeanUtils.setValue(cacheObject, key, values.get(key));
			}
			// Map<String, Object> map = MyBeanUtils.getValues(object,
			// MyBeanUtils
			// .getPropertyNames(object));
			// for (String key : map.keySet()) {
			// Object value = map.get(key);
			// log.debug("key:::::::::::::::" + key);
			// log.debug("value:::::::::::::::" + value);
			// if (null != value) {
			// MyBeanUtils.setValue(cacheObject, key, value);
			// }
			// }
			this.getHibernateTemplate().update(cacheObject);
		} catch (RuntimeException re) {
			log.error("update failed", re);
			throw re;
		}

		// 错了!原先的代码错了,DAO层不应该有隐含逻辑:只更新非空属性。
		// 应该只是update。至于原来的webwork框架会从页面上读取的VO,只有部分属性的问题:
		// 可以先根据load对象,再在web层把非空属性写入。
		// 最后传到dao一起update。

		// 再者!原先的ID和ObjectNotFoundException也不需要了,因为在业务层要把vo的值复制过去,就要根据id
		// load一次了。
		// 如果这里在load一次,为的是抛出ObjectNotFoundException的话,就load了两次。
		// 只有对象的id在,就传给hibernate去处理吧。

		// 以上好像又全错了,“更新”的概念可以这样理解:
		// 给定一个主键ID的对象,更新属性为传来vo的非空。
		// 而不是直接传一个什么都写好了的PO

		// 他妈的全都错了,最后改成用map类型的values来记录哪些要改的属性,甚至包括设置成null。
		// 至于这些属性的生产,在web层做,交给webwork,不行!(想了一下,因为没有FormBean)

		// log.debug("update transientInstance");
		// try {
		// getHibernateTemplate().save(object);
		// log.debug("save successful");
		// } catch (RuntimeException re) {
		// log.error("save failed", re);
		// throw re;
		// }
	}

	public void delete(ID id) throws ObjectNotFoundException {
		// log.debug("deleting instance");
		try {
			getHibernateTemplate().delete(this.findById(id));
			// log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}
}


贴一次code看看效果。:P
0 请登录后投票
   发表时间:2007-08-08  
zjut2006 写道
那个BaseDao<T> 中的T是不是可以是其他的字母啊 对范性不了解啊


试试不就知道了,哈哈
0 请登录后投票
   发表时间:2007-08-08  
反射的一个最大的烦恼就是应用反射以后得到的基本上都是Object类型的对象,这种对象要使用,需要我们进行强制类型转化。而泛型的功能之一就是消除我们使用强制类型转化。所以反射与泛型可结合使用
0 请登录后投票
   发表时间:2007-08-09  
用泛型不错...
0 请登录后投票
   发表时间:2007-08-09  
public interface BaseDao<T> {
public void create (T t);
public void delete (T t);
public void update (T t);
}

public interface WindDao extends BaseDao<Wind> {
public void other (Wind wind);
}
这种设计比较合理
0 请登录后投票
   发表时间:2007-08-13  
泛型是一个不错的解决方案,但时常开发还是受限于JDK的版本
如果大量使用泛型作为DAO的实现方式,那么在低版本的JDK上问题就出来了.

其实反射也不失为一种兼容性较好的实现方式,Hibernate正是基于反射机制来实现的.

一般情况下,系统大部分的时间消耗在查询上.增删改相对少一些.但要视系统规模而定.

to zhao
对象是不能强制类型转换的, 只能称为造型.造型的确会带来性能的损失:)
0 请登录后投票
论坛首页 Java企业应用版

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