【问题标题】:JavaEE app structureJavaEE 应用程序结构
【发布时间】:2016-10-27 14:18:49
【问题描述】:

我正在使用 JEE7 创建一个 Web 应用程序。我的问题是关于我的应用程序的架构。基本上,我有几个实体类(业务类)代表将存储在我的数据库中的内容。例如,我有一个实体类 Book 和一个实体类 Comic。
要访问数据库,我想创建一个 EJB(有点像 DAO 设计模式)。这是我的问题,我在网上找不到准确的答案。

我是否应该为 Book 类和漫画类创建一个 @remote 接口和一个 @stateless 类以及添加/删除/获取/更新的所有方法?

或者我应该创建 2 个@remote 接口和 2 个@stateless 类(2 个 EJB),每个实体类一个?

因为让我们想象一下我创建了一个更大的网络应用程序。如果我有 100 个实体类,使用第一种方法我将拥有一个巨大的 EJB,但使用第二种方法我将拥有 100 个 EJB 及其接口。我认为第二个更好,但我不确定。你怎么看?

【问题讨论】:

标签: jpa jakarta-ee dao java-ee-7


【解决方案1】:

为什么不只使用一个无状态bean和一个远程接口?

远程 bean 的一个非常好的特性是,它们可以是通用的,所以基本上你只需要一个接口和一个远程 bean(参见 SimpleEntity 及其远程 bean)。

我混合使用了一个非常通用的远程 bean DAO 来读取简单的实体和一些特定的 bean,用于需要更多 CUD 操作逻辑的实体。接下来我只是提取了最小接口来重现它。

如果我创建一个新表和实体,它可以立即在远程客户端上使用。

实体

/* 
 * Complex entity with enhanced CRUD logic
 */
public class Foo implements Entity { }

/*
 * Simple entity without complex CRUD logic
 */
public class Bar implements SimpleEntity { }

界面

public interface Entity { }
public interface SimpleEntity extends Entity { }

/*
 * Generic entity DAO interface, for remote beans and other datasources
 */
public interface IEntityDAO<T extends Entity>
{ 
    public T get(Class<T> type, long id);
    public T update(T t);
}

/*
 * Generic remote bean interface for a JNDI service locator lookup
 */
public interface EntityDAOBeanRemote<T extends Entity> extends IEntityDAO<T> { }

无状态远程 Bean

/*
 * 'abstract' base class for stateless DAO beans
 */
public class AEntityDAOBean<T extends Entity> implements EntityDAOBeanRemote<T>
{
    public T get(Class<T> type, long id)
    {
        Session session = // obtain current hibernate session
        return id == (T) session.createCriteria(type).add(Restrictions.idEq(id)).uniqueResult();
    }

    public T update(T t, long id)
    {
        Session session = // obtain current hibernate session
        session.update(t);
        return t; // return updated instance
    }
}

/*
 * Generic stateless remote DAO bean implementation
 */
@Stateless(mappedName = "SimpleEntityDAOBean")
@Remote(EntityDAOBeanRemote.class)
public class SimpleEntityDAOBean extends AEntityDAOBean<SimpleEntity> implements EntityDAOBeanRemote<SimpleEntity>
{
    // empty since all methods are from parent class
}

/* 
 * Foo specific remote DAO bean
 */
@Stateless(mappedName = "FooDAOBean")
@Remote(EntityDAOBeanRemote.class)
public class FooDAOBean extends AEntityDAOBean<SimpleEntity> implements EntityDAOBeanRemote<Foo>
{
    @Override
    public Foo update(Foo foo) 
    { 
        // make specific foo things and update
        return foo;
    }
}

客户

在您的客户端使用 JNDI,您可以使用 JNDI 服务定位器模式调用 bean,例如:

    EntityDAOBeanRemote<Foo> fooDAOBeanRemote = jndiServiceLocator
        .getEntityDAOBeanRemote(Foo.class);

    EntityDAOBeanRemote<Bar> barDAOBeanRemote = jndiServiceLocator
        .getEntityDAOBeanRemote(Bar.class);

客户端 JSF

借助通用 JSF 转换器和用于 GUI 框架的 DAO 通用扩展(例如 PrimeFaces LazyDataModel),它可以节省大量时间,使新实体可以在 JSF bean 中快速访问并在 GUI 中进行编辑。

【讨论】:

    【解决方案2】:

    Java EE 应用程序架构显然是一个庞大的主题,但一种常见的方法是创建一个会话 EJB 以向您的客户端公开通用 API 调用,然后使用粗粒度实体 EJB 来处理您的持久数据。这些实体 EJB 可以管理许多更细粒度的 Java 对象和映射到您的数据库结构的类。

    这可能是一个很好的起点: https://docs.oracle.com/cd/A87860_01/doc/java.817/a83725/entity1.htm

    【讨论】:

    • 我不明白你的回答或为什么它被接受。实体 bean(如果这就是您所说的“实体 EJB”)和 Oracle 8i 是 15 年的技术
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    相关资源
    最近更新 更多