Java 简单CRUD的EJB3会话Bean设计

Java 简单CRUD的EJB3会话Bean设计,java,jakarta-ee,ejb-3.0,ejb,session-bean,Java,Jakarta Ee,Ejb 3.0,Ejb,Session Bean,我正在编写一个应用程序,它的唯一目的是执行CRUD操作以维护数据库中的记录。某些表/实体之间存在关系。我看到的创建会话bean的大多数示例都处理复杂的业务逻辑/操作,这些业务逻辑/操作与许多我没有的实体交互 既然我的应用程序非常基础,那么会话bean的最佳设计是什么 我在考虑每个实体有一个会话bean,它定义了CRUD方法。然后我考虑将所有这些会话bean组合成一个会话bean。然后我发现这篇博文很有趣,但我必须承认我并不完全理解它(什么是ServiceFacade?) 我倾向于会话bean/实

我正在编写一个应用程序,它的唯一目的是执行CRUD操作以维护数据库中的记录。某些表/实体之间存在关系。我看到的创建会话bean的大多数示例都处理复杂的业务逻辑/操作,这些业务逻辑/操作与许多我没有的实体交互

既然我的应用程序非常基础,那么会话bean的最佳设计是什么

我在考虑每个实体有一个会话bean,它定义了CRUD方法。然后我考虑将所有这些会话bean组合成一个会话bean。然后我发现这篇博文很有趣,但我必须承认我并不完全理解它(什么是ServiceFacade?)

我倾向于会话bean/实体类,但希望听到更多有经验的意见

谢谢



哎呀,这里有一个博客链接:

不知道你在说什么博客:)但在你的特殊情况下,我可能会使用一个会话bean实现一个类似以下的接口:

public interface GenericCrudService {
    public <T> T create(T t);
    public <T> T find(Class<T> type, Object id);
    public <T> void delete(T t);
    public <T> T update(T t);
    public List findWithNamedQuery(String queryName);
    public List findWithNamedQuery(String queryName, int resultLimit);
    public List findWithNamedQuery(String namedQueryName, 
                                   Map<String, Object> parameters);
    public List findWithNamedQuery(String namedQueryName, 
                                   Map<String, Object> parameters,
                                   int resultLimit);
    public <T> List<T> findWithNativeQuery(String sql, Class<T> type);
}
公共接口通用crudservice{
公共T创建(T T);
public T find(类类型、对象id);
公共无效删除(T);
公共T更新(T);
公共列表findWithNamedQuery(字符串queryName);
公共列表findWithNamedQuery(字符串queryName,int resultLimit);
公共列表findWithNamedQuery(字符串namedQueryName,
地图参数);
公共列表findWithNamedQuery(字符串namedQueryName,
映射参数,
int resultLimit);
公共列表findWithNativeQuery(字符串sql,类类型);
}
bean如下所示:

@Stateless
@Remote(GenericCrudService.class)
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class GenericCrudServiceBean implements GenericCrudService {
    @PersistenceContext
    private EntityManager em;

    @Override
    public <T> T create(T t) {
        em.persist(t);
        return t;
    }

    @Override
    public <T> T find(Class<T> type, Object id) {
        return em.find(type, id);
    }

    @Override
    public <T> void delete(T t) {
        t = em.merge(t);
        em.remove(t);
    }

    @Override
    public <T> T update(T t) {
        return em.merge(t);
    }

    @Override
    public List findWithNamedQuery(String queryName) {
        return em.createNamedQuery(queryName).getResultList();
    }

    @Override
    public List findWithNamedQuery(String queryName, int resultLimit) {
        return em.createNamedQuery(queryName).setMaxResults(resultLimit)
                .getResultList();
    }

    @Override
    public List findWithNamedQuery(String namedQueryName,
                                   Map<String, Object> parameters) {
        return findWithNamedQuery(namedQueryName, parameters, 0);          
    }

    @Override
    public List findWithNamedQuery(String namedQueryName,
                                   Map<String, Object> parameters,
                                   int resultLimit) {
        Query query = this.em.createNamedQuery(namedQueryName);
        if(resultLimit > 0) {
            query.setMaxResults(resultLimit);            
        }
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        return query.getResultList();
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T>  List<T> findWithNativeQuery(String sql, Class<T> type) {
        return em.createNativeQuery(sql, type).getResultList();
    }
}
@无状态
@远程(GenericCrudService.class)
@TransactionAttribute(TransactionAttribute类型.必填)
公共类GenericCrudServiceBean实现GenericCrudService{
@持久上下文
私人实体管理者;
@凌驾
公共T创建(T){
em.t;
返回t;
}
@凌驾
无法找到公共对象(类类型、对象id){
返回em.find(类型,id);
}
@凌驾
公共作废删除(T){
t=em.merge(t);
em.remove(t);
}
@凌驾
公共T更新(T){
返回em.merge(t);
}
@凌驾
公共列表findWithNamedQuery(字符串queryName){
返回em.createNamedQuery(queryName).getResultList();
}
@凌驾
公共列表findWithNamedQuery(字符串queryName,int resultLimit){
返回em.createNamedQuery(queryName).setMaxResults(resultLimit)
.getResultList();
}
@凌驾
公共列表findWithNamedQuery(字符串namedQueryName,
地图参数){
返回findWithNamedQuery(namedQueryName,参数,0);
}
@凌驾
公共列表findWithNamedQuery(字符串namedQueryName,
映射参数,
int resultLimit){
Query Query=this.em.createNamedQuery(namedQueryName);
如果(结果限制>0){
setMaxResults(resultLimit);
}
对于(Map.Entry:parameters.entrySet()){
setParameter(entry.getKey(),entry.getValue());
}
返回query.getResultList();
}
@凌驾
@抑制警告(“未选中”)
公共列表findWithNativeQuery(字符串sql,类类型){
返回em.createNativeQuery(sql,类型).getResultList();
}
}
另见

1大多数应用程序不应该直接向客户端公开原始CRUD,而是将CRUD屏蔽在实现业务规则和封装对域存储访问的服务后面(EntityManager)。

很抱歉,我忘了将链接发布到博客,我已经编辑/添加了它。它与您的解决方案非常相似,但指出“接口实现实际上是一个服务,它总是必须在ServiceFacade后面执行”,这一点我还没有弄清楚。我花了一段时间才理解泛型类(仍然掌握泛型)。但是,我知道他们在干什么。谢谢您上面的实现是否如您所说的那样,
shield CRUD落后于实现业务规则的服务,并封装了对EntityManager的访问。您似乎没有封装对
EntityManager
的访问。如何修复上述代码以封装
EntityManager
。还有一个问题,当我尝试从我的
托管Bean
访问EJB时,我必须执行
@EJB private GenericCrudService myEJB
,而不是
@EJB private GenericCrudService myEJB
。我认为后者更有意义,因为
GenericCrudService
只是一个简单的接口,
GenericCrudServiceBean
是一个无状态Bean我还有几个关于我的解决方案的问题,我在这里发布了一个新问题,请帮助: