论坛首页 Java企业应用论坛

Spring的DAO设计实践

浏览 108717 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-10-18  
DAO
http://www.gpowersoft.com/tech/Spring/39.htm

这里有篇如何设计DAO来良好利用Spring的Hibernate支持类的文章,我觉得挺不错,推荐一下。
   发表时间: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完全把我搞晕了
0 请登录后投票
   发表时间:2004-10-18  
HibernateTemplate封装的并不完整,例如我要Query对象,拿不到,我要多个命名参数的iterator,没有,我要设置分页,不提供!你怎么办?都用HibernateCallBackup()?Spring的作用不是把Hibernate再封装一层,让你接触不到Hibernate的API,而是帮助你管理好Session和Transaction。hibernateTemplate只不过帮你剩几行代码而已,他没有完整的封装也无法取代Hibernate原生API。
0 请登录后投票
   发表时间: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直观,也增加了学习成本
0 请登录后投票
   发表时间: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都没提供
0 请登录后投票
   发表时间: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改了,多写一堆类,麻烦
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);;
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间:2004-10-18  
没错,程序生成器的确是不错.但是个人认为这个问题的解决不能从这种角度去解决,应该从不同的角度去考虑(更本质的),不过我也不知道是什么.
0 请登录后投票
   发表时间:2004-10-19  
robbin 写道
http://www.gpowersoft.com/tech/Spring/39.htm

这里有篇如何设计DAO来良好利用Spring的Hibernate支持类的文章,我觉得挺不错,推荐一下。


那我建议看看Confluence,可借鉴的地方多了去了。
0 请登录后投票
论坛首页 Java企业应用版

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