Quick note about MyBatis association, collection and discriminator.
association
<association> deals with a “has-one” type relationship. For example, in our example, an Author has an User account with username and password:
And in xml map file, we need to define result Map of Author:
We could also extract User information as another individual resultMap which could be re-used:
To query by java:
Constructor
If we do not care about user id or some other property. We could use <constructor> to limit what we want based on constructors of object.
Subquery
Subquery/Inner query/Nested query is a query within another SQL query and embedded within the WHERE clause.
So there are in fact two statements here. Let’s define each select statement and resultMap:
In the above settings, <association> will pass userID as parameter to findById.
N+1 problem
But think about we have 10 authors, so here findById will be called 10 times! So we need to call 10 + 1 statements. It’s called “N+1” problem of subquery. Many people think it’s not as good as join query.
Solution
The solution is lazy load. Statement will be not queried until the point at which it is needed.
Let’s firstly find differences between subquery and join query.
Join query: Query one time. But it gets all the properties of two table, so it consumes resources.
Subquery: Query N+1 times. It depends on what we want in the final result. With lazy loading, we may not need to make N times queries if not necessary.
To set lazy loading in configuration file, this setting must be in front of others:
To test:
So here with lazy loading, if we never need to call getUser(), it only queries one time which is efficient!
collection
<collection> element works almost identically to <association>. But it is used to map a set of nested results like List.
In the following example, each User could have a list of visitors:
Then in xml map file, we use <collection> to indicate that list of visits.
To test:
discriminator
A single database query might return result sets of many different data types. So here <discriminator> is used to determine which data types or so-called resultMap to use according to a column value. It is like switch in other programming languages.
The following resultMap will return different data types according to value of vehicle_type.