简体   繁体   中英

Spring - Decoupling Vs Performance

I have an application that has the following java files:

Services:

AccountService.java
UserService.java
MessageService.java

DAOs:

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.

(1) According to Spring's decoupling standards, this is how the calls should be made:

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

But the problem is, this approach makes 3 DB calls.

(2) For better Performance, I would do:

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. That is really bad, since (in the non-hypothetical) we have a LOT of DAOs

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

This is false. There are no "decoupling standards" with Spring. Please find me a reference in the Spring documentation that tells you how you must structure your persistence layer code.

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.

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.

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. 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.

The alternative is to use an ORM such as Hibernate, mapping each of your tables to an entity. Then define the logical relationships between those entities. For example, a 1:M relationship between users and messages. As your tables change, your mappings will need to change, but your SQL won't (because Hibernate will generate it).

For most relationships, Hibernate is very good at creating joins to retrieve related entities in one query. 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. Don't let (your idea of) Spring's guidelines make you write code that gets the wrong results.

It sounds like a join in SQL is the right approach.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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