首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >控制器层可以直接调用持久层吗?

控制器层可以直接调用持久层吗?
EN

Stack Overflow用户
提问于 2013-05-21 06:32:30
回答 3查看 1.4K关注 0票数 2

我有JSF、Spring和Mybatis的webapp。这些框架分别在控制器层、业务层和dao层使用。在我的DAO层中,我有CRUD操作的方法。现在,在我的控制器层,我需要使用插入操作。为此,我可以使用以下配置:

控制器层

我使用JSF和注解

代码语言:javascript
运行
复制
@ManagedBean
public class Controller{
    @ManagedProperty("#{business}")
    private Business business;

    public void insert(){
        business.insert();
    }
}

业务层

我使用Spring和注解

代码语言:javascript
运行
复制
public interface Business{
    public void insert();
}

@Service("business")
public class BusinessImpl implements Business{
    @Autowired
    private DaoMapper mapper;

    @Override
    @Transactional
    public void insert(){
        mapper.insert();
    }
}

DAO层

我使用的是Mybatis (马提斯-弹簧图书馆)

代码语言:javascript
运行
复制
public interface DaoMapper{
    public void insert();
}

但是,在这种情况下,我的业务层只调用DAO层,而不实现任何其他操作,因此我认为应该使用以下配置:

控制器层

代码语言:javascript
运行
复制
@ManagedBean
public class Controller{
    @ManagedProperty("#{daoMapper}")
    private DaoMapper mapper;

    public void insert(){
        mapper.insert();
    }
}

DAO层

代码语言:javascript
运行
复制
public interface DaoMapper{

    @Transactional
    public void insert();
}

我已经测试过了,工作也很好,但是我想知道我是不是在做不好的练习。

编辑

实际上,DaoMapper接口是一个MyBatis类映射器,它是与XML ()相关联的。我不知道这是不是一个DAO类。我想我应该叫它Persisence LayerMapper Layer

来源:http://www.infoq.com/articles/ddd-in-practice

如你所见。表示层,在我的例子中是Controller层(我想我又犯了一个错误命名),直接调用DTO (或者这就是我所理解的)

如果在我的控制器或表示层(无论您称之为什么),我需要使用insert或update操作,我可以直接从mapper类调用,或者我必须为这个类对mapper类的新调用创建一个业务类。

现在。如果可以使用此配置,我有一个疑问:

假设在我的业务类的方法中,我需要调用来插入操作。这就像:

代码语言:javascript
运行
复制
@Service("business")
public class BusinessImpl implements Business{
    @Autowired
    private DaoMapper mapper;

    @Override
    @Transactional
    public void insert(){
        mapper.insert();
    }
}

但是方法从DaoMapper接口插入已经有了DaoMapper注释。方法@Transactional注释将影响插入两次。这不是个问题吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-21 07:12:02

我建议不要直接在控制器中使用DAO。照我的想法。Dao层是来自数据库的映射,就像您想要更改另一个数据库(例如。从sql到nosql),唯一的办法就是创建一个新的DAO并注入它,而控制器和服务函数却一点也不改变。控制器也是如此,它的主要职责是处理请求和响应,工作应该由业务/服务层来完成。如果这是错误的,感激地指出

票数 3
EN

Stack Overflow用户

发布于 2013-05-21 06:57:29

如果您想要删除层,您可以有控制器和服务,但跳过DAO。您的服务可以直接调用映射程序,因为您没有任何特定的查询代码。我知道一些著名的Java人,比如Adam,认为DAO是一种死模式。dao

票数 1
EN

Stack Overflow用户

发布于 2021-05-09 11:57:27

服务层定义域模型(业务逻辑)的操作及其原子性。

我建议无论如何都要有服务层。它具有重要的功能。它实现域模型的“谓词”/操作,它也是通过@Transactional定义操作原子性的好地方。在我看来,用MyBatis对@Transactional映射器方法进行注释是一种糟糕的做法。实体(在您的例子中是MyBatis结果POJO)是域模型的“名词”。

没有动作的域模型是无用的。

域模型中只有“名词”是无用的,您需要能够对它执行一些操作(“谓词”)。“谓词”由服务层实现。这就是为什么我认为服务层在99.9%的情况下是必要的。到目前为止,您只遇到了业务逻辑操作为1:1到CRUD操作的简单情况。但这是两件不同的事情。可能会有更复杂的案件。想象一下,在网上银行应用程序中,您拥有注册新客户的用例。这是一个涉及多个实体的业务逻辑操作:您需要创建用户,还需要创建与该用户关联的银行帐户。这种情况必须发生在单个SQL事务中。“动词”-“名词”的分离是相当自然的方法。

控制器处理web方面,它们不是用于实现域模型的操作。

控制器是网页控制器或REST控制器。它们处理与页面模型相关的方面(在JSF情况下是@ManagedBean),或者定义RESTful API ( Spring中的@RestController)。它们不打算实现域模型的操作。同样,由于这种推理,使用实体作为RESTful API的DTO也是一种糟糕的做法。实体是领域模型“名词”,RESTful API的DTO定义了RESTful API层的表示。这些都是不同的东西。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16663552

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档