【发布时间】:2012-04-17 19:50:02
【问题描述】:
任何人都可以建议一个 Web 应用程序的 DAO 实现吗?
如果我为基本操作(例如findByID()、findALL()、createObject()、deleteObject() 等)创建事务会出现什么问题?
请推荐一个支持惰性操作的 DAO 实现。
【问题讨论】:
任何人都可以建议一个 Web 应用程序的 DAO 实现吗?
如果我为基本操作(例如findByID()、findALL()、createObject()、deleteObject() 等)创建事务会出现什么问题?
请推荐一个支持惰性操作的 DAO 实现。
【问题讨论】:
如果您使用Hibernate Tools 生成代码,则会自动为您生成基本的 DAO。您可以在它们的基础上进行构建。
无论如何,我用一些代码sn-p进行交易:
public void executeTransaction(Object[] parameters, Transact transact) throws ApplicationException
{
Transaction tx = null;
try
{
tx = HibernateSessionFactory.getSession().beginTransaction();
transact.execute(parameters, tx);
tx.commit();
LOG.trace("executeTransaction() success");
}
catch (Exception e)
{
rollback(tx);
throw new ApplicationException(e);
}
}
private void rollback(Transaction tx) throws ApplicationException
{
LOG.warn("rollback()");
if (tx != null)
{
try
{
tx.rollback();
}
catch (Exception ex)
{
LOG.error("rollback() failure",ex);
}
}
}
public interface Transact
{
public void execute(Object[] parameters, Transaction tx) throws Exception;
}
void updateDistrictImpl(final Distretto district) throws ApplicationException, ApplicationValidationException
{
try
{
LOG.trace("updateDistrict[" + distrettoToString(district) + "]");
executeTransaction(new Transact() {
public void execute(Object[] parameters, Transaction tx) throws ApplicationException
{
DistrettoHome DistrettoDAO = new DistrettoHome();
DistrettoDAO.attachDirty(district);
}
});
LOG.info("updateDistrict[" + distrettoToString(district) + "] success!");
}
catch (ApplicationException e)
{
LOG.error("updateDistrict() exception: " + e.getLocalizedMessage(), e);
throw e;
}
}
【讨论】:
有 3 个主要选项:
1) 在您的映射和查询中正确配置延迟加载:这并不总是最简单的方法,因为您在开发 DAO 时并不总是知道您的对象将如何在表示层中使用。
2) 使用 OpenSessionInView 模式:这样,您将能够在表示层中延迟加载相关对象。这可能是最简单的方法,因为它只需要一点配置。但是要小心,因为延迟加载可能会非常昂贵,如果您在表示层中做了一些可疑的事情,您可能会遇到性能问题。您还可以从演示文稿中修改您的对象,这意味着更容易出现预编程错误。
3) 添加一个服务层,将您的 Hibernate 对象转换为值对象:这是最细粒度的选项,因为您还可以限制 wchi 属性暴露给表示。您在服务调用周围保持事务边界,因此您可以确保在服务之外不会修改任何内容。
在所有情况下,您至少应该尝试正确配置延迟加载。否则你可能会遇到性能问题!
【讨论】: