当前位置: 首页 > 知识库问答 >
问题:

JavaEE 6/7中的持久层设计

阎星华
2023-03-14

上次用JBoss 7.1 (Java EE6标准)开发app,用DAOs写了持久层。

首先,我有一个“抽象”的道,它是所有具体道的父亲:

public abstract class AbstractDao<T> {

    private Class<T> entityClass;

    private String defaultSortColumn;

    public AbstractDao(Class<T> entityClass) {
        this.entityClass = entityClass;
        this.defaultSortColumn = "";
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    @SuppressWarnings("rawtypes")
    public List<T> find() {
        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
    CriteriaQuery cq = cb.createQuery();
        Root from = cq.from(entityClass);
        cq.select(from);
        return getEntityManager().createQuery(cq).getResultList();
    }

    @SuppressWarnings("rawtypes")
    public int count() {
        //...
    }

}

然后,我的域中的每个DB实体都有一个dao实现。

它们都非常相似,它们只是为比通常的“crud”操作更复杂的查询添加方法。

下面是一个示例:

@Stateless
public class ShopDao extends AbstractDao<Shop> {

    @Inject
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public ShopDao() {
        super(Shop.class);
    }
}

如您所见,我的Dao是无状态EJB。

这种方式使我的应用程序工作,但...当我必须创建一个新的实体时,我必须创建实体本身和DAO。有点多余是不是?但是,我想不出更好的方法,因为我经常需要对特定的实体进行复杂的查询。

问题是:

> < li>

这是最佳做法吗?我还能如何设计我的持久层?

对于一个道琼斯来说,成为一个EJB有好处吗?

我在客户端(JSF 控制器)中进行了验证。它应该在持久层吗?如何?

在服务层类中使用原始EntityManager是否更好,避免DAO?

编辑

有没有办法避免每个表都有一个dao?

共有3个答案

任小云
2023-03-14

部分答案:

我认为这是一个很好的做法,但就我而言,我也会有一个包含部分逻辑的实体服务层。通常我使用隐藏道的EntityService,它负责逻辑/验证/…

但是如果你使用Spring,你可以(应该?)使用Spring数据JPA,它有一个非常好的数据层。

不要在持久性层中嵌入验证。仅保留此图层以供数据库访问。例如,应在服务图层中(或根据您的项目在视图图层中)中完成验证。并将实体管理器保留在持久性层中,因为它们粘在一起。

陶高扬
2023-03-14

我建议完全放弃DAO。你必须问自己,你需要它们做什么?

1)抽象DAO类实际上什么也不做,然后将调用委托给实体管理器,因此您自己创建了一个<code>edit</code>方法来替换<code>merge</code>方法,这不仅是不必要的,而且还使代码更难阅读,因为必须有人检查<code>edit</code>方法的功能。

第二)您没有显示具体DAO类的功能,但很可能这可以在实体本身(因为实体是一个业务对象,而不仅仅是一个哑数据容器)或控制器(因为它们控制实体之间的交互,例如无状态EJB)中完成。

在你的应用程序中总是从简单开始,不要从设计一个层开始,你可能需要一些时间,但这会使一切变得更复杂。

季博
2023-03-14

“这是最佳实践吗?我还能怎么设计我的持久层?”

你的方法看起来不错。有些人喜欢让DAO层完全独立于其他层。这种方法的优点是,您可以在其他地方重用DAO层,而且在应用服务器之外测试DAO也更容易。我不太支持这种方法,因为它经常是一种矫枉过正的做法——EJB方法只是DAO层的一层薄薄的包装。EJB也很容易在应用服务器之外测试(Spring提供了所有需要的测试工具)。所以,只要你不打算在你的EJB实现更复杂的商业逻辑,我会赞同你的方法。

请继续阅读以了解更多详细信息…

“DAO做EJB好吗?”

更准确地说,在您的方法中,EJB不是Dao,因为它们也管理事务,可以负责业务逻辑的其他非数据库元素。EJB还为您的应用程序提供外部接口。从技术上讲,EntityManager是您的DAO,EJB使用它来实现所有需要的业务逻辑。

“我在客户端(JSF控制器)进行了验证。它应该在持久层吗?怎么做?”

在 Java EE 6 中,您可以利用 Bean 验证技术 - 在模型级别定义验证规则(作为实体字段上的注释),这些规则由持久性层和 JSF Web 层强制执行。

"将原始的EntityManager放在服务层类中,避免使用Dao,会不会更好?"

据我所知,你想摆脱EJB?您可以这样做,但是您需要自己管理事务(在简单的情况下,这不是什么大事)。无状态本地接口或无接口EJB现在相当轻量级,所以没有很好的理由去避免它们。作为替代,你可以使用Spring框架支持JPA。

 类似资料:
  • 名称 方法 实现 Hibernate 优势 劣势 Mybaties Jpa get 1. Hibernate 1.1 单独使用 1.1.1 For Idea 新建项目:【File】——>【New】——>【Project】——>【Java】——>【Hibernate、JavaEE Persistence】 添加数据连接驱动 配置数据源 根据数据库表生成实体类:【Persistence】——>【名称】

  • 我是微服务架构的初学者,我在很多博客中读到过,在微服务架构中,每个微服务都必须有自己的数据库。在我的情况下,它可能花费非常昂贵。 我的问题是,有没有可能使持久层本身成为微服务?这将具有允许其他微服务对数据库具有读/写访问权限的功能。谢谢

  • 本文向大家介绍请问持久层设计要考虑的问题有哪些?请谈一下你用过的持久层框架都有哪些?相关面试题,主要包含被问及请问持久层设计要考虑的问题有哪些?请谈一下你用过的持久层框架都有哪些?时的应答技巧和注意事项,需要的朋友参考一下 考察点:框架 参考回答: 所谓"持久"就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中

  • 问题内容: 我正在尝试编写一个Java程序,该程序将自动下载并命名一些我最喜欢的网络漫画。由于我将请求来自同一域的多个对象,因此我希望有一个持久的http连接,在下载所有漫画之前,我可以一直保持打开状态。以下是我正在进行的工作。如何在不打开新的http连接的情况下从相同域但路径不同发出另一个请求? 问题答案: 根据此处的文档,HTTP持久性在Java中是透明处理的,尽管它提供了一些选项,也可以通过

  • Serenity 2.1.5 引入保存如下信息的网格列表设置: 可见列和显示顺序 列宽 排序的列 高级过滤器(由右下角的编辑过滤器链接创建) 快速过滤器(撰写本文档时,尚未提供该功能) 包含已删除的状态切换 默认情况下,网格列表不会自动持久化任何东西。 因此,如果你隐藏某些列并离开订单页面,当你再次返回该页面时,你就会看到那些隐藏的列再次成为可见列。 你需要开启所有网格列表的持久化设置,或设置单独

  • Akka持久化使有状态的actor能留存其内部状态,以便在因JVM崩溃、监管者引起,或在集群中迁移导致的actor启动、重启时恢复它。Akka持久化背后的关键概念是持久化的只是一个actor的内部状态的的变化,而不是直接持久化其当前状态 (除了可选的快照)。这些更改永远只能被附加到存储,没什么是可变的,这使得高事务处理率和高效复制成为可能。有状态actor通过重放保存的变化来恢复,从而使它们可以重