[Learning] ResultMap mybatis source mapping results

A, ResultMap contain elements

    • constructor  - for, when the class is instantiated, the constructor injection results
      • idArg  - Parameter ID; ID mark as a result may help to improve the overall performance
      • Arg  - injected into the constructor will be a common result of
    • ID  - an ID result; as a result of the ID tag can help improve the overall performance
    • Result  - injected into a field or JavaBean property ordinary results
    • Association  - association of a complex type; many of the results of this type into the package
      • Results Mapping Nested - may itself be associated with a  resultMap  element, or a reference elsewhere
    • Collection  - a set of complex types
      • Results Mapping Nested - set itself be a  resultMap  element, or a reference elsewhere
    • discriminator  - value use the results to decide which  resultMap
      • Case  - based on the results of certain values map
        • Results Mapping Nested -  Case  itself be a  resultMap  element, and therefore may have the same structure and elements of a reference or elsewhere

 

id Current namespace a unique identifier that identifies a result mapping.
type Fully qualified class name, alias, or a type (aliases on the built-in type, may refer to the table above).
auto mapping If you set this property, MyBatis will result-oriented mapping on or off automatically mapped. This property will override the global property autoMappingBehavior. Default: not set (unset).

Second, a complex mapping sql statement corresponding ResultMap

sql statement

<!-- 非常复杂的语句 -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
  select
       B.id as blog_id,
       B.title as blog_title,
       B.author_id as blog_author_id,
       A.id as author_id,
       A.username as author_username,
       A.password as author_password,
       A.email as author_email,
       A.bio as author_bio,
       A.favourite_section as author_favourite_section,
       P.id as post_id,
       P.blog_id as post_blog_id,
       P.author_id as post_author_id,
       P.created_on as post_created_on,
       P.section as post_section,
       P.subject as post_subject,
       P.draft as draft,
       P.body as post_body,
       C.id as comment_id,
       C.post_id as comment_post_id,
       C.name as comment_name,
       C.comment as comment_text,
       T.id as tag_id,
       T.name as tag_name
  from Blog B
       left outer join Author A on B.author_id = A.id
       left outer join Post P on B.id = P.blog_id
       left outer join Comment C on P.id = C.post_id
       left outer join Post_Tag PT on PT.post_id = P.id
       left outer join Tag T on PT.tag_id = T.id
  where B.id = #{id}
</select>
View Code

resultMap

<!-- 非常复杂的结果映射 -->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection>
</resultMap>
View Code

 

Third, the relational query

Association (association) processing elements "has a" relationship type. For example, in our example, a user has a blog. The results associated with mapping and other similar types of mapping work. You need to specify the target property name and property of the javaType (often MyBatis can be inferred out on his own), in if necessary you can also set the type of JDBC, if you want to override the process of obtaining the result value, you can also set the type of processor.

The difference associated with that, you need to tell MyBatis how to load the association. MyBatis There are two different ways to load the associated:

  • Select nested query: to load the complex type desired by executing another mapped SQL statement.
  • Mapping Nested Results: The results of the mapping using nested repeated to process a subset of the connection results.
Attributes description
property Column is mapped to fields or properties result. If there is to match the JavaBean properties of a given name, then it will be used. Otherwise, MyBatis will look for a field given name. In either case, you can have complex property navigation using the usual dot-separated format. For example, you can map to something simple: "username", or mapped to some complex things: "address.street.number".
javaType A fully-qualified Java class name, alias, or a type (aliases on the built-in type, may refer to the table above). If you're mapping to a JavaBean, MyBatis can usually infer the type. However, if you are mapping to a HashMap, then you should explicitly specify javaType to ensure the desired behavior and consistent.
jdbcType JDBC type, supported JDBC type See "Supported JDBC type" Before this form. You may only need to insert, update, and delete and allow null values ​​in the column specified JDBC type. This is a JDBC requirement rather than MyBatis requirements. If you direct JDBC-oriented programming, you need to specify the type of the column there may be a null value.
type trades We discussed default type handlers previously. Using this property, you can override the default type of processor. The value is the fully qualified name of a class type processors, or a type alias.

 

(1) Select associated nested queries

Attributes description
column The column names in the database, or column alias. Under normal circumstances, and it is transmitted to  resultSet.getString (columnName)  method parameters the same. NOTE: When using a composite primary key, you can use  column = "{prop1 = col1, prop2 = col2}"  Such syntax for specifying a plurality of nested Select query is transmitted to the column name. This causes  prop1  and  prop2  as a parameter object, the parameter is set to correspond nesting Select statement.
select ID statement for mapping the complex property of loading, it specifies the column from the column to retrieve data attribute, passed as a parameter to the target select statement. Refer to the following example. NOTE: When using a composite primary key, you can use  column = "{prop1 = col1, prop2 = col2}"  Such syntax for specifying a plurality of nested Select query is transmitted to the column name. This causes  prop1  and  prop2  as a parameter object, the parameter is set to correspond nesting Select statement.
fetchType Optional. Valid values are  lazy  and  eager . When specifying an attribute are ignored in the global configuration parameter map  lazyLoadingEnabled value, using this property.

Example:

<resultMap id="blogResult" type="Blog">
  <association property="author" column="author_id" javaType="Author" select="selectAuthor"/>
</resultMap>

<select id="selectBlog" resultMap="blogResult">
  SELECT * FROM BLOG WHERE ID = #{id}
</select>

<select id="selectAuthor" resultType="Author">
  SELECT * FROM AUTHOR WHERE ID = #{id}
</select>
View Code

It's that simple. We have two select queries: one to load the blog (Blog), the other to load the Author (Author), and describes the results of blog mapping should be used  selectAuthor  statement to load its author property.

All other attributes will be loaded automatically, as long as their column and attribute names match.

Although this method is very simple, but poor performance on large data sets or large tables. This problem is known as "N + 1 query problem." Generally speaking, N + 1 query problem is like this:

  • You execute a single SQL statement to retrieve a list (the "+1").
  • Return to the list of each record, you execute a select query to load detailed information (that is, "N") for each record.

This problem will lead to hundreds of thousands of SQL statements to be executed. Sometimes, we do not want to have such consequences.

The good news is, MyBatis can delay the loading of such queries, so you can cost a lot of statements to run at the same time spread out. However, if after you load a list of records immediately through the list to get the nested data, will trigger lazy loading all queries, performance may become worse.

So there is another way.

Nested Results (2) associated with the mapping

Attributes description
resultMap Results Results nested ID mapping, this may be associated with a set of maps to the appropriate object tree. It can be used as an alternative to using additional select statement. It may be a multi-table join operation result of a single mapped to  the ResultSet . Such  ResultSet  parts of the data is repeated. In order to correctly mapped to the result set nested object tree, MyBatis allows you to "tandem" result maps, in order to solve the problem of nested results. An example of using nested result of the mapping table after.
columnPrefix When connecting multiple tables, you might have to use a column alias to avoid  ResultSet  produce duplicate column names. ColumnPrefix specify the column names prefixed with these prefixes will allow you map the column to an external result map. Please detail later with reference to Examples.
notNullColumn By default, when at least one attribute is mapped to a column is not null, the child object will be created. You can specify a non-empty column on this property to change the default behavior, the specify, Mybatis the only non-empty when you create a child object in these columns. You may be used to specify a plurality of columns separated by commas. Default: not set (unset).
auto mapping If you set this property, MyBatis will result-oriented mapping on or off automatically mapped. This property will override the global property autoMappingBehavior. Note that this result attributes to external mapping invalid, it is not with a  select  or  resultMap  element used. Default: not set (unset).

Example:

<select id="selectBlog" resultMap="blogResult">
  select
    B.id            as blog_id,
    B.title         as blog_title,
    B.author_id     as blog_author_id,
    A.id            as author_id,
    A.username      as author_username,
    A.password      as author_password,
    A.email         as author_email,
    A.bio           as author_bio
  from Blog B left outer join Author A on B.author_id = A.id
  where B.id = #{id}
</select>


<resultMap id="blogResult" type="Blog">
  <id property="id" column="blog_id" />
  <result property="title" column="blog_title"/>
  <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/>
</resultMap>

<resultMap id="authorResult" type="Author">
  <id property="id" column="author_id"/>
  <result property="username" column="author_username"/>
  <result property="password" column="author_password"/>
  <result property="email" column="author_email"/>
  <result property="bio" column="author_bio"/>
</resultMap>
View Code

 

Guess you like

Origin www.cnblogs.com/shangxiaofei/p/11279053.html