javaweb应用程序中的体系结构层

javaweb应用程序中的体系结构层,java,spring,hibernate,jsf,jpa,Java,Spring,Hibernate,Jsf,Jpa,我正在开发一个JavaWeb应用程序,并尝试遵循一些模式,如dao/dto。目前,我正在考虑这样的基本架构层: 我遇到了一些关于图层的问题。该方案是这样的:DAO接收DTO并从数据库返回对象(实体),服务层也接收DTO,使用DAO并对返回的对象执行所有必需的逻辑。UI Bean、服务、DAO和DTO类是特定于实体的-每个实体都有自己的层 现在,我是否需要在视图中使用UI bean,或者这是一种过分的做法,UI视图可以直接将服务类用作UI bean?如果没有,为什么我需要UI bean 另一个问

我正在开发一个JavaWeb应用程序,并尝试遵循一些模式,如dao/dto。目前,我正在考虑这样的基本架构层:

我遇到了一些关于图层的问题。该方案是这样的:DAO接收DTO并从数据库返回对象(实体),服务层也接收DTO,使用DAO并对返回的对象执行所有必需的逻辑。UI Bean、服务、DAO和DTO类是特定于实体的-每个实体都有自己的层

  • 现在,我是否需要在视图中使用UI bean,或者这是一种过分的做法,UI视图可以直接将服务类用作UI bean?如果没有,为什么我需要UI bean

  • 另一个问题是关于DTO。我已经创建了具有所有必需属性的实体,据我所知,DTO类类似于实体类的反射。那么为什么我需要这些DTO类呢?如果我使用它们,我发现它需要一些从实体到DTO的转换,反之亦然。我是否在服务层进行转换?视图(例如html页面)是否也会显示对象属性而不是实际实体的数据(如调用
    {UIBean.entityProperty}


  • 首先,我只会在前端部分使用DTO bean,但是既然你已经提到了UI bean,我想这些会很好地完成任务,facade使用这些来将它们传递给控制器以显示web组件。 在服务和外观之间,您将后端的实体映射到dto bean。 这样,前端将完全松耦合到后端

    关于你的第二个问题,我想指出一个确切的原因,为什么你的用户界面应该总是使用dto或视图bean。 您可以将多个后端实体bean组合成一个dto bean,以便在前端进行更轻松的处理

    一般来说,我总是记住DTO的公共访问,eta一个web服务公开它或一个web前端或一个swing应用程序,或。。。
    仅在dao和服务层中使用的实体类永远不会更高。

    根据经验法则,尝试根据上下文划分逻辑层。启发你的理论,但要小心使用。我用几个例子来说明我对layer兴趣的理解。这个愿景当然不完整,但我希望它能帮助你回答你的问题

  • 那么,使用UIBean而不是服务DTO是不是太过分了?我认为这取决于你的背景 也许在您的UI bean中有用户输入数据?例如,您必须使用JSR303注释来验证它们。如果这些注释在这个层中有意义,那么它们对于底层是无用的。这就是为什么会有一个带有JSR303注释的UIBean和一个没有JSR303注释的DTOBean

    但如果它们完全相同,为什么要重复呢?也许在UIBean层,日期可以表示为字符串类型,您希望在DTO层操作日期类型而不是字符串这就是为什么需要在层之间调整数据,以处理对特定层有意义的对象。例如,您可以添加BOAdapter(在UIView和服务之间)和DTOAdapter(在服务和DAO之间)。这些适配器可用于在每个POJO的格式内转换数据。例如,您可以在BO(=UIBean)中有一个用三个字符串表示的日期,并且您希望数据有一个日期对象,因此您可以在BOAdapter中对其进行转换:

    public class BOAdapter(){
       private BOAdapter(){}
       public static DTO toDTO(BO objectBO){
          DTO objectDTO = new DTO();
          SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-aa");
          objectDTO.setDate(df.parse(objectBO.getYear()+"-"+objectBO.getMonth()+"-"+objectBO.getDay());
          [...]
    }
    }
    
  • 为什么我需要数据适配器?也许您的数据库至少包含两个表customer和address,它们之间有完整性约束。JPA将自动生成正确的代码。但是你真的需要所有这些代码到UIView吗?我的意思是,如果您正在编码的功能只需要客户的姓名、姓氏和出生日期,那么他们的地址就没有用处了。这也是为什么您需要在层之间调整数据,以处理对特定层有意义的对象的原因。在这种情况下,您可以创建一个只包含姓名、姓氏和出生日期信息的DTO对象,并在DTOAAPTER中创建一个方法,将自定义DTO转换为重JPA对象,以便与数据库正常工作 但是我需要整个实体来编码我的爱好?除了JSR303之外,您可能还需要在这个层中添加验证约束。因此,除了实体之外还有DTO类可能会很有趣,原因与BO对象相同


    但我的实体大,怎么容易复制呢?尝试使用工具自动映射数据(如推土机)。如果不是太大,请手动执行。

    因为您有Spring标签

    我将用Spring数据存储库替换您的[DAO]。所以大多数时候,您编写接口方法/@query注释,Spring数据编写工具

    用JPA实体替换DTO。所以我可以用逆向工程


    [UIBean]将大部分是JPA实体的组合。经过一些验证

    谢谢,但这并不能回答我的问题。我问的是是否需要额外的(UIBean)层作为服务层和DAO层的补充。另外,如果需要DTO,或者我可以使用实体类,因为DTO类反映实体类,需要在DTO和实体对象之间进行转换。我正在考虑使用DTO,因为我听人说,将实体暴露于UI和服务是一种糟糕的做法,你必须有某种DTO。我认为,这一切都在这里,还可以阅读相关帖子…