简体   繁体   English

春季-去耦与性能

[英]Spring - Decoupling Vs Performance

I have an application that has the following java files: 我有一个具有以下java文件的应用程序:

Services: 服务:

AccountService.java
UserService.java
MessageService.java

DAOs: DAO:

AccountDAO.java
UserDAO.java
MessageDAO.java

Tables: 表格:

ACCOUNTS
USERS
MESSAGES

In MessageService.java , I have a function newMessage() that has to query data from all the 3 tables. MessageService.java ,我具有一个newMessage()函数,该函数必须从所有3个表中查询数据。

(1) According to Spring's decoupling standards, this is how the calls should be made: (1)根据Spring的去耦标准,这是应该如何进行调用的方法:

                     AccountDAO.java -- ACCOUNTS
                    /
MessageService.java -- MessageDAO.java -- MESSAGES
                    \
                     UserDAO.java -- USERS

But the problem is, this approach makes 3 DB calls. 但是问题是,这种方法进行了3次DB调用。

(2) For better Performance, I would do: (2)为了获得更好的性能,我会这样做:

MessageService.java -- MessageDAO.java -- Join ACCOUNTS, MESSAGES and USERS

But this way, it's tightly coupled and if there's a change in USERS table, I'll have to change MessageDAO.java (and all other DAOs that I have, that use the USERS table) too. 但是这样,它紧密地联系在一起,如果USERS表发生变化,我也必须更改MessageDAO.java(以及我拥有的所有其他DAO,都使用USERS表)。 That is really bad, since (in the non-hypothetical) we have a LOT of DAOs 真的很糟糕,因为(非假设的)我们有很多DAO

Which approach is considered a better practice? 哪种方法被认为是更好的做法? Or is there another approach that I'm missing? 还是我错过了另一种方法?

According to Spring's decoupling standards, this is how the calls should be made 根据Spring的去耦标准,这就是调用的方式

This is false. 这是错误的。 There are no "decoupling standards" with Spring. Spring没有“解耦标准”。 Please find me a reference in the Spring documentation that tells you how you must structure your persistence layer code. 请在Spring文档中找到我的参考,该参考告诉您如何构造持久层代码。

Typically, you would have one DAO for each "entity" that your application wants to operate on, but it would be foolish to take this pattern to the extreme of deconstructing a query that joins multiple tables together into three distinct queries. 通常,对于应用程序要操作的每个“实体”,您将都有一个DAO,但是将这种模式应用到将一个将多个表连接成三个不同查询的查询解构的极端情况是愚蠢的。

If you need to have a newMessage() method that joins some tables together in a query, choose which DAO that makes the most sense in - probably the MessageDAO and write the query/method in the way that makes sense. 如果您需要一个newMessage()方法来将查询中的某些表连接在一起,请选择最有意义的MessageDAO可能是MessageDAO然后以有意义的方式编写查询/方法。

But there is no rule saying that you must have distinct queries for each entity and that one DAO class is not allowed to make queries that touch the tables of other entities. 但是没有规则说每个实体都必须有不同的查询,并且不允许一个DAO类进行涉及其他实体表的查询。 This is too extreme and has no benefit. 这太极端了,没有好处。

If one the other hand you are worried about the maintainability of having multiple data layer classes that are aware of all of your tables, then look into an ORM solution as parsifal mentioned to alleviate some of this work. 另一方面,如果您担心拥有多个可以了解所有表的数据层类的可维护性,那么可以考虑使用parsifal提到的ORM解决方案来减轻这项工作。

The alternative is to use an ORM such as Hibernate, mapping each of your tables to an entity. 另一种方法是使用ORM(例如Hibernate)将每个表映射到一个实体。 Then define the logical relationships between those entities. 然后定义这些实体之间的逻辑关系。 For example, a 1:M relationship between users and messages. 例如,用户和消息之间的1:M关系。 As your tables change, your mappings will need to change, but your SQL won't (because Hibernate will generate it). 随着表的更改,您的映射将需要更改,但是您的SQL不需要更改(因为Hibernate会生成它)。

For most relationships, Hibernate is very good at creating joins to retrieve related entities in one query. 对于大多数关系,Hibernate非常擅长创建联接以在一个查询中检索相关实体。 You can control whether this happens; 您可以控制是否发生这种情况。 I recommend using lazy loads as a default for most relationships, and switching to eager loads as-needed. 对于大多数关系,我建议将延迟加载作为默认设置,并根据需要切换到紧急加载。

Doing this as 3 separate queries might impact correctness if the data might change between one query and the next. 如果数据可能在一个查询和下一个查询之间改变,则作为3个单独的查询执行此操作可能会影响正确性。 Don't let (your idea of) Spring's guidelines make you write code that gets the wrong results. 不要让(您的想法)Spring的准则使您编写得到错误结果的代码。

It sounds like a join in SQL is the right approach. 听起来像加入SQL是正确的方法。

Whichever method you follow, it's always about finding a sweet spot between decoupling and performance. 无论采用哪种方法,始终都是要在去耦和性能之间找到一个最佳位置。 It holds with even the selection of number of layers, etc. 它甚至可以选择层数等。

So I guess as @mattb recommended, it's completely fine to join tables in a DAO if it makes sense in the particular context 所以我想按照@mattb的建议,如果在特定上下文中有意义,那么在DAO中联接表是完全可以的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM