java ee EJB中的服务层和dao层

Posted

技术标签:

【中文标题】java ee EJB中的服务层和dao层【英文标题】:Service layer and dao layer in java ee EJBs 【发布时间】:2014-08-15 12:39:16 【问题描述】:

问题:任何人都可以在 Java EE 和 EJB 的上下文中展示具有两种不同方法的特定 DAO 类(或多个)。以及一个在一个事务边界中调用这两种方法并进行回滚的服务类?

我有一个 EJB,但我想将它用作服务层,就像在 spring @Transactional 方法中一样。

1) 这是个好主意吗?

2) 如何在一种方法中的一个“事务”中调用多个 dao 方法?我想我必须对 transaction.begin() 和 .提交()?任何人都可以显示一个代码示例吗?

一些主要优点是:

a- 所有小的不可变 DAO 事务都将在建立的单个数据库连接中“一次性”提交(single transactional boundries

b- 如果说我在服务器中有 4 个 dao 调用,而第三个调用失败,因为它是一个事务边界,我可以做 roll backs

c- 我的immutable DAO methods 在许多其他地方将是re-usable

Java EE 示例:

import com.....entities.Users;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

@Stateless
public class UsersBean 

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")

    public Users sayHello() 
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("CommunityPU");
        EntityManager em = emf.createEntityManager();
        Users user =  em.find(Users.class, 1);
        em.close();
        emf.close();
        return user;
    


对比春天:

@Controller
class MyControllerClass 

      @RequestMapping...
      method()
         ServiceCall()...
      //put something to modelAndView object here and redirect to jsp page.
      return "home"; // this will redirect data to home.jsp

      


//Service class /////////

@Service
class MyServiceClass
      @Transactional
      SomeServiceMethod() 
        DaoMethod(); 
        SomeMoreDaoMethods();
      



//Dao class ////////

@Autowired
EntityManager em;

@Repository
class MyDaoClass
   DaoMethdon()em.find(...)



/view/myjsps.jsp  path to view directory set in spring.xml

编辑 - 1(交叉问题以进一步澄清答案)


1) DAO 本身会是EJB 吗?或 EJBs 是严格的 service layers 调用其他 immutable dao methods(位于 dao 类中)。

2) 我们不会在EJBs 中使用entitymanager,而是在Daos 中使用。正确的?

3) 使用@Transactional 怎么样(直到Java EE 7 只有EJB,其中事务性和@Transactional 注释不存在。)或@TransactionAttribute

4) 如果我们使用非@stateless 会怎样。那么它不会在一个事务边界中管理 daos 而不使用回滚?

RND 链接:

https://***.com/a/17840851

http://docs.oracle.com/javaee/5/tutorial/doc/bncij.html

【问题讨论】:

【参考方案1】:

是个好主意吗?

是的。基本上,这就是 EJB 的用途。

如何在一个方法中的一个“事务”中调用多个 dao 方法?

你就去做吧:

 @Stateless
 public class MyService 

     @Inject
     private FirstDao firstDao;

     @Inject
     private SecondDao secondDao;

     // stateless EJBs are transactional by defaults.
     public void doStuff() 
         firstDao.doSomething();
         secondDao.doSomethingElse();
     

默认情况下,EJB 是事务性的。您不需要以编程方式启动和提交事务。容器会为您执行此操作:如果 2 个 DAO 调用中的任何一个引发运行时异常,则事务将回滚。否则,它将提交。

还请注意,您的服务 EJB 不应使用实体管理器。这就是 DAO 的用途:处理持久性。所以 DAO 应该是使用实体管理器的那个:

public class FirstDao 
    @PersistenceContext
    private EntityManager em;

    ...

关于你最后的问题:

    DAO 本身可以是 EJB,但这不是必需的,因为事务通常由服务层划分。 我已经回答过了。当然 Data 访问对象是必须使用 EntityManager 的对象,因为它们的工作是处理持久性,而 EntityManager 用于访问数据库。 按照您想要的方式进行操作。重要的是您的服务应该是事务性的,无论您以何种方式使它们具有事务性。引入了事务性以消除对 EJB 的需求并具有事务性 CDI bean。如果你喜欢这样,那很好。

小提示:不可变方法没有意义。某物(如对象)在其状态永不改变时是不可变的。方法没有状态。

【讨论】:

+1 谢谢,我得到你的观点超过 90%。请参阅编辑 -1 了解我的交叉问题。 肯定假设我总是使用 EJB,所以第 3 点 @Traansactional 在这里无效?我也加了4个。最后,我所说的不可变是指那些不能进一步分解的方法/动作。例如getUserById(id)return em.find(user.class, id); 你真的应该阅读答案。正如我在回答中所说的那样:默认情况下 EJB 是事务性的。我还说过:引入事务是为了消除对 EJB 的需求并拥有事务 CDI bean。你的第4点没有意义。如果您不使用@Stateless,那么您将不再定义 EJB。 我阅读了答案,这是一个很好的答案。对于第 4 点)还有其他类型的 EJB。 @Stateless @Statefull , singleton 它们都是 EJB。我的回答是:默认情况下 EJB 是事务性的。基本上每个 EJB 教程(和规范)都涵盖了这一点。读一读。

以上是关于java ee EJB中的服务层和dao层的主要内容,如果未能解决你的问题,请参考以下文章

服务层和 DAO 层中的 Spring 事务

java中dao层和service层的区别是啥?

JPA 和 EJB 以及分离的 DAO 和服务层

创建服务层和DAO层(接口+实现)或仅实现

泛型 Dao、服务层和多个匹配的 bean

服务层和控制器中的代码分离