锁定老帖子 主题:Spring的DAO设计实践
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-10-18
这里有篇如何设计DAO来良好利用Spring的Hibernate支持类的文章,我觉得挺不错,推荐一下。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-10-18
robbin 写道 http://www.gpowersoft.com/tech/Spring/39.htm
这里有篇如何设计DAO来良好利用Spring的Hibernate支持类的文章,我觉得挺不错,推荐一下。 spring提供的hibernateTemplate不是够了么,为什么要自己创建session呢? 我的hibernate基类,子类都使用template,不直接访问session public class BaseDaoHibernate extends HibernateDaoSupport implements BaseDao { protected transient final Log log = LogFactory.getLog(getClass(););; public Object getObject(Object entity); { return getObjectByLoad(entity, false);; } public Object loadObject(Object entity); { return getObjectByLoad(entity, true);; } public Object saveObject(Object entity); { return getHibernateTemplate();.saveOrUpdateCopy(entity);; } public void removeObject(Object entity); { entity = getObject(entity);; if (entity != null); { getHibernateTemplate();.delete(entity);; } } private Object getObjectByLoad(Object entity, boolean load); { Long id = null; try { Method method = entity.getClass();.getMethod("getId", new Class[0]);; id = (Long); method.invoke(entity, new Object[0]);; if (load); { return getHibernateTemplate();.load(entity.getClass();, id);; } else { return getHibernateTemplate();.get(entity.getClass();, id);; } } catch (Exception e); { throw new ObjectRetrievalFailureException(entity.getClass();, id);; } } } 另外,看了ddd的书后,更晕了,service、domain object、dao完全把我搞晕了 |
|
返回顶楼 | |
发表时间:2004-10-18
HibernateTemplate封装的并不完整,例如我要Query对象,拿不到,我要多个命名参数的iterator,没有,我要设置分页,不提供!你怎么办?都用HibernateCallBackup()?Spring的作用不是把Hibernate再封装一层,让你接触不到Hibernate的API,而是帮助你管理好Session和Transaction。hibernateTemplate只不过帮你剩几行代码而已,他没有完整的封装也无法取代Hibernate原生API。
|
|
返回顶楼 | |
发表时间:2004-10-18
这个问题我跟robbin讨论过,我是仿照Quake的做法,使用QueryManager把常用的操作进行封装,
而不直接让service extends HibernateDaoSupport来直接调用HibernateTemplate,也算是replace inheritance with delegation把。关于robbin说的 不能完全封装的问题,我的考虑是 第一,封装常用也就增删查改,分页查询,查询size,这样基本上QueryManager可以把99%的情况处理掉,剩下1%非常特殊的,完全可以再使用回调execute/executeFind来处理。 第二,Service不直接继承HibernateDaoTemplate的话,spring配置文件里头可以放心使用autowire=true,这样万一service需要相互引用,可以自动获得,不许重新配置。 第三,我可以在PersistenceManager,QueryManager的add,update,delete方法里头增加一些额外的控制, 比如add/update的时候需要建索引,delete时候需要unIndex,这都很好做到。如果纯粹用hibernate的话, 用hibernate 的interceptor倒是可以做到,但是interceptor的做法毕竟没有直接调pm,qm的api直观,也增加了学习成本 |
|
返回顶楼 | |
发表时间:2004-10-18
robbin 写道 HibernateTemplate封装的并不完整,例如我要Query对象,拿不到,我要多个命名参数的iterator,没有,我要设置分页,不提供!你怎么办?都用HibernateCallBackup()?Spring的作用不是把Hibernate再封装一层,让你接触不到Hibernate的API,而是帮助你管理好Session和Transaction。hibernateTemplate只不过帮你剩几行代码而已,他没有完整的封装也无法取代Hibernate原生API。
我现在的做法就和robbin推荐的文章一致。 HibernateTemplate封装的实在是简单,很多Hibernate的API还是需要继续在BaseDao中利用execute/excuteFind来扩展。在oracle中操作B/CLOB字段就有问题了,连flush()和refresh都没提供 |
|
返回顶楼 | |
发表时间:2004-10-18
public interface EntityDao {
public Object get(Class entityClass, Serializable id) throws DataAccessException; public Object load(Class entityClass, Serializable id) throws DataAccessException; public Serializable create(Object entity) throws DataAccessException; ...} } public interface EntityManager { public Object get(Class entityClass, Serializable id); public Object load(Class entityClass, Serializable id); public Serializable create(Object entity); ... } 这个EntityManager 似乎多余(和EntityDao方法一样只是有个好听的名字罢了,为了分层而分层,留它做甚?我喜欢简单 ),要用直接用EntityDao ,Transaction的控制直接到EntityDao 就好了 我在设计TM 1.0时采用那种结构,2.0改了,多写一堆类,麻烦 |
|
返回顶楼 | |
发表时间:2004-10-18
andy163 写道 public interface EntityDao {
public Object get(Class entityClass, Serializable id) throws DataAccessException; public Object load(Class entityClass, Serializable id) throws DataAccessException; public Serializable create(Object entity) throws DataAccessException; ...} } public interface EntityManager { public Object get(Class entityClass, Serializable id); public Object load(Class entityClass, Serializable id); public Serializable create(Object entity); ... } 这个EntityManager 似乎多余(和EntityDao方法一样只是有个好听的名字罢了,为了分层而分层,留它做甚?我喜欢简单 ),要用直接用EntityDao ,Transaction的控制直接到EntityDao 就好了 我在设计TM 1.0时采用那种结构,2.0改了,多写一堆类,麻烦 目前看来的确是多余,但在EJB 3.0(JAVA 1.5)里面就不多余了,因为可以设计成泛型的: public class<T> EntityManager { public T get(Serializable id);; public T load(Serializable id);; ... } EntityManager<User> userManager; User user = userManager.get(id);; |
|
返回顶楼 | |
发表时间:2004-10-18
dhj1 写道 正在做个程序生成器,自动跟据表名的集合,生成一个bean.xml配置.
在bean.xml配置中,每个表对应一个DAO,统一命名为DAO的名字是表名+DAO. 在DAO中有一些表的基本操作的方法,录入,删除,修改,查询.按时间段查询等! 在每个表生成一个对应的service,类名为:表名+service. 这个只有基本框架.只有表维护的SERVICE,没多少内容.有待于手工填充. 又跟据表名和表字段,生成几个JSP,录入的JSP,修改的JSP,列表的JSP. 再生成几个ACTION,处理表的录入,修改,删除! 对于一个真正的项目,程序生成后,就开始跟据项目的特点,手工增加和修改JSP, ACTION.和SERVICE! 接受了本论坛几位高人的意见,想把每个表对应一个DAO缩水为一个.SERVICE跟业务逻辑有关,要跟据业务关系来确定并人工编程,但是表维护的SERVICE则保留自动生成. 表维护的ACTION也想缩水,但还不知如何下手! --- 以上做法有什么不当之处,欢迎痛批! extends DispatchAction啊 对于简单的表我甚至做了单页面List和CRUD |
|
返回顶楼 | |
发表时间:2004-10-18
没错,程序生成器的确是不错.但是个人认为这个问题的解决不能从这种角度去解决,应该从不同的角度去考虑(更本质的),不过我也不知道是什么.
|
|
返回顶楼 | |
发表时间:2004-10-19
robbin 写道 http://www.gpowersoft.com/tech/Spring/39.htm
这里有篇如何设计DAO来良好利用Spring的Hibernate支持类的文章,我觉得挺不错,推荐一下。 那我建议看看Confluence,可借鉴的地方多了去了。 |
|
返回顶楼 | |