论坛首页 Java企业应用论坛

我的通用DAO理解,请大家指正

浏览 33999 次
精华帖 (2) :: 良好帖 (1) :: 新手帖 (2) :: 隐藏帖 (1)
作者 正文
   发表时间:2008-11-22   最后修改:2008-11-22
amonlei 写道
通用dao??先明确通用的范围,是基于sql的通用呢?还是基于所有orm技术的通用呢?



这个通用的角度找得好啊.
我看J2EE without EJB中 Rod 对DAO的设计的问题,就应该是基于sql关系手动处理对象关系映射,还是基于orm自动对象关系映射,就算都是orm,但JDO,TopLink,Hibernate之间的行为也不同(详细的就看without EJB吧).因为一不小心就会写出不可移植得DAO,也就无所谓通用了.不过Rod也说了就算写出这样的通用DAO,意义也并不大,持久策略(sql或orm只是实现之一)一般在设计前期都定好了,这个应该和实现可移植性的问题差不多吧,只是这种通用DAO本身是设计策略并不是实现策略,问题有点儿不明显吧.

当然LZ写得通用角度也很好,利用范形定义出所有DAO的最基本操作(CURD),还是可以少写些代码的.

异常应该有自己的业务层异常体系,在Service捕获感兴趣的DAO层的UnChecked异常并转译成自定义的业务异常.
0 请登录后投票
   发表时间:2008-11-22  
前面的朋友提到异常UI的交互,
下面我又接着写了action异常处理,大家看看是否合理
请先看配置:
1.struts-config.xml配置
<global-exceptions>
   <exception key="error" type="com.kkk.exceptions.ChipInException" path="/commons/messages.jsp"/>
</global-exceptions>
2.action中的代码
public ActionForward saveChip(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {

if(ename==null||ename.equals("")){
messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("ename.null"));
saveMessages(request, messages);
    throw new ChipInException("名字为空");
}
try{
  xxxServiceImpl.insert(product);
}catch(Exception e ){
  e.printStackTrace();
  throw new ChipInException("保存失败");
}

}
3.资源文件中的配置
error=some errors here
ename.null=please select one name first!!!  
4.显示异常页面
<%-- Error Messages --%>
<logic:messagesPresent>
<div class="error">
<html:messages id="error">
${error}<br/>
</html:messages>
</div>
</logic:messagesPresent>

<%-- Success Messages --%>
<logic:messagesPresent message="true">
<div class="message" id="message">
<html:messages id="message" message="true">
${message}<br/>
</html:messages>
</div>

<script type="text/javascript">

new Effect.Highlight('message');
window.setTimeout("Effect.DropOut('message')", 1000);

</script>
</logic:messagesPresent>


我的问题是

我这里的异常处理及转向合理吗?配置文件的配置有没错?
key="error"是不是说明会读取资源文件中的error的值到messages.jsp页面显示?
还是说显示我action中的messages存的ename.null的资源文件值信息?
其实具体应该如何来进行这个异常处理在这几个文件中的配置?这里的异常显示页面message.jsp会不会和<global forwards>的有重合?
我要让"名字为空"这几个字在message.jsp页面中显示有办法吗?

Effect未定义是不是少了包支持?
0 请登录后投票
   发表时间:2008-11-22  
期待回复中......
0 请登录后投票
   发表时间:2008-11-22  
这样的结构看见过。和前面的看法一样,不在DAO中处理异常,而是在service中抛出自定义的异常。
0 请登录后投票
   发表时间:2008-11-22  
package net.vschool.util.dao;

/**
 *  该类为hibernaeDao的基础类,所以其它模块的类的dao都集成该接口
 *  @author cheafen
 *  @version 1.0 05/30/2007
 *  @since 1.0
 */
import java.io.Serializable;
import java.util.Collection;

public interface GenericDao<T,ID extends Serializable> {
	/**
	 * 根据对象id获得一个对象
	 * @param id 对象主键id
	 * @return 返回一个对象类型
	 */
	T loadObjectById(ID id);	
	
	/**
	 * 保存一条新的记录或者跟新一条新的记录
	 * @param entity 一个对象实体
	 * @return 返回保存的对象实体
	 */
	T saveOrUpdate(T entity);
	
	/**
	 * 删除一个对象实体
	 * @param entity 对象实体
	 */
	void delete(T entity);
	
	/**
	 * 查询出所有的对象集合
	 * @return 返回一个对象实体的集合
	 */
	Collection<T> findAll();
	
	/**
	 * 根据条件列出对象实体集合
	 * @param cmd HQL语句的查询相关关键字
	 * @param params 参数数组
	 * @param page 显示的第几个页面
	 * @param count 一共返回的条数
	 * @return 返回集合为count+1条记录的集合
	 */
	Collection findCmd(String cmd,Object[] params,int page,int count);
	
	/**
	 * 根据动态queryHql来列出对象实体集合
	 * @param querySql 查询语句
	 * @param page 显示的第几页面
	 * @param count 集合的条数
	 * @return 返回集合为count+1条记录的集合
	 */
	Collection<Object>findCmdByDyn(String querySql,int page,int count);
	
	/**
	 * 根据cmd对应语句查询可以执行如下操作:count、max、min、sum、avg
	 * count: select count(*) from net.vschool.user.User as user 
	 * max: select max(user.id) from net.vschool.user.User as user
	 * min: select min(user.id) from net.vschool.user.User as user
	 * sum: select sum(user.id) from net.vschool.user.User as user
	 * avg: select avg(user.id) from net.vschool.user.User as user
	 * @param cmd HQL语句的查询相关关键字
	 * @return 对应字段最大值
	 */
	Object queryByCmd(String cmd,Object[] params);
}


实现:

/**
 * 
 */
package net.vschool.util.dao.hibernate;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;

import net.vschool.util.dao.GenericDao;
import net.vschool.util.dao.ObjectParser;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;


/**
 * @author lovejj
 * 
 */
public class HibernateBaseDaoImpl<T,ID extends Serializable> extends HibernateDaoSupport implements GenericDao<T,ID> {
	private Class<T> persistentClass=null;
	/*
	 * Cmd parameter is the named query's name. Please refer to Hibernate Named Query.
	 * 
	 * @see com.zybedu.dao.FindCmdDao#findCmd(java.lang.String,
	 *      java.lang.Object[], int, int)
	 */
	@SuppressWarnings("unchecked")
	public Collection findCmd(final String cmd, final Object[] params,
			final int page, final int count) {
		List result = null;
		Object o = this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException {
				Query query = session.getNamedQuery(cmd);
				if (params != null) {
					int len = params.length;
					for (int i = 0; i < len; i++) {
						query.setParameter(i, params[i]);
					}
				}
				if (page > 0) {
					int maxResult = count;
					if (count < 1)
						maxResult = 1;
					int first = (page - 1) * maxResult;
					query.setFirstResult(first);
					query.setMaxResults(maxResult + 1);
				} else {

				}
				List list = query.list();
				org.hibernate.Hibernate.initialize(list);
				return list;
			}
		});
		if (o != null)
			result = (List) o;
		return result;
	}

	public void delete(T entity) {
		this.getHibernateTemplate().delete(entity);
		this.getSession().flush();
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		List list= this.getHibernateTemplate().loadAll(this.getPersistentClass());
		org.hibernate.Hibernate.initialize(list);
		return list;
	}


	@SuppressWarnings("unchecked")
	public T loadObjectById(ID id) {
		return (T)this.getHibernateTemplate().get(this.getPersistentClass(), id);
	}

	public T saveOrUpdate(T entity) {
		this.getHibernateTemplate().saveOrUpdate(entity);
		return entity;
	}

	protected Class<T> getPersistentClass(){
		if(this.persistentClass==null){
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
		}
		return this.persistentClass;
	}

	public Collection<Object> findCmdByDyn(String querySql, final int page, final int count) {
		List result=null;
		final String fullHql=querySql;
		//LazyParser parser=parsers.get(cmd);
		if(fullHql!=null)
		{
			Object o=this.getHibernateTemplate().execute
			(
					new HibernateCallback() 
					{
						public Object doInHibernate(Session session) throws HibernateException 
						{

							Query query=session.createQuery(fullHql);
							
							if(page>0){
								int maxResult =count;
								if(count<1) maxResult=1;
								int first=(page-1)*maxResult;
								query.setFirstResult(first);
								query.setMaxResults(maxResult+1);
							}
							
							List list=query.list();												
							return list;
						}
					});
			if(o!=null) result=(List)o;
		}
		return result;
	}

	public Object queryByCmd(final String cmd,final Object[] params) {
		// 
		Object avg = null;
		Object avgTemp = this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException {
				Query query =  session.getNamedQuery(cmd);
				
				if (params != null) {
					int len = params.length;
					for (int i = 0; i < len; i++) {
						query.setParameter(i, params[i]);
					}
				}
				return query.uniqueResult();
			}
		});
		if (avgTemp != null)
			avg =  avgTemp;
		return avg;
	}


}
0 请登录后投票
   发表时间:2008-11-22  
SQL异常等无法处理直接抛出由struts的异常处理架构处理,service层最好不抛出异常,而是返回一些有意义的标识。实在无法返回采用异常。异常很耗资源,尽量少抛出自定义异常。
0 请登录后投票
   发表时间:2008-11-22   最后修改:2008-11-22
showtime520 写道
SQL异常等无法处理直接抛出由struts的异常处理架构处理,service层最好不抛出异常,而是返回一些有意义的标识。实在无法返回采用异常。异常很耗资源,尽量少抛出自定义异常。


是利用异常还是返回标识,这个存在一个折中.
不过很少情况下因为异常成为程序的性能瓶颈原因,异常是语言级别的错误处理机制,返回值的方式是语言之外的.
C没有异常处理,返回值当然是解决办法,Java并不和C一样,有更好的错误处理方式.
如果异常真得成为程序的性能瓶颈原因,那就用返回值吧,不过一定要做好文档说明.这也是返回值不太好的地方,异常一般都是自描述.
能够升级一下硬件的话可能更有效吧.
0 请登录后投票
   发表时间:2008-11-22  
尽量不要用泛型,现在生产环境大多都是jdk412的版本哦。
0 请登录后投票
   发表时间:2008-11-22  
actionMessages的使用呢?
0 请登录后投票
   发表时间:2008-11-23  
kaki 写道
尽量不要用泛型,现在生产环境大多都是jdk412的版本哦。


Java范型相比C++范型没那么强大,但如果能带来好处仍然要使用的,至少相比数组,数组已越来越没优势.
企业应用也终会过度到1.5,1.6,1.X,...;
讨论贴嘛,总会比实际应用左一些.
0 请登录后投票
论坛首页 Java企业应用版

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