MyBatis Advanced Mapping

Source: Internet
Author: User

<select id= "selectblog_by_id" parametertype= "int" resultmap= "Blog_result" >
Select
b.ID,
B.title,
B.AUTHOR_ID,
a.ID,
A.username,
A.password,
A.email,
A.bio
From
Blog B left Join Author a
On
b.author_id = a.ID
where
b.ID = #{id}
</select>

<resultmap type= "Blog" id= "Blog_result" >

<id column= "id" property= "id"/>
<result column= "title" property= "title"/>

<!--map associated objects--
<association property= "Author" javatype= "Author" >
<id column= "author_id" property= "id"/>
<result column= "username" property= "username"/>
<result column= "password" property= "password"/>
<result column= "Email" property= "email"/>
<result column= "bio" property= "bio"/>
</association>
</resultMap>

1.Resultmap

Resultmap property: Type is a Java entity class; ID is the identity of this resultmap.

Resultmap can set the mapping:

1. constructor – A constructor used to reflect the result to a class that is instantiated well

a) idarg–id parameter; Mark the result set as ID for easy global invocation

b) The usual result of arg– reflection to the constructor

2.id–id Results, mark the result set as ID to facilitate global invocation

3.result – normal result reflected to the JavaBean property

4.Association – the combination of complex types; the types of multiple result compositions

a) nested result mappings– several resultmap own nested associations, or can be referenced to a

5.Collection – Complex Type set a collection of complex types

6. Nested the set ofresult mappings –resultmap can also be referenced to a

7. DiscriminatoR – Uses a result value to determine which resultmap to use

A) Case scenario for the result mapping of case– basic values

I. Nested result mappings– A case scenario is itself a result map, so you can include some of the same elements, or you can refer to an external resultmap.

Best Practice : generating Resultmap incrementally , unit tests are very helpful. If you try to generate a huge resultmap like the above , it can go wrong and work very hard. Start with a simple, step-up expansion, and unit testing. There is a drawback to using framework development, and they are sometimes like a black-out. The best way to ensure that you have the behavior you expect is to do unit testing. This is also useful for submitting bugs.

2.id, result

The ID, result is the simplest mapping, the ID is the primary key mapping, and the result is the mapping of other basic database table fields to entity class properties.

<resultmap type= "Blog" id= "Blog_result" >
< ID column= "id" property= "id"/>
<result column= "title" property= "title"/>
</resultMap>

These are the basic content of the result mapping. Both the ID and result map a single column value to a single property or field of a simple data type (string, integer, double-precision floating-point number, date, and so on).

The only difference between the two is that the result of the ID representation will be the identity attribute used when comparing the object instance. This helps to improve overall performance, especially caching and embedding result mappings (i.e., federated mappings).

  Property : The field or attribute that is mapped to the column result. If a match is present, and the JavaBeans property of the given name is the same, then it will be used. Otherwise MyBatis will look for the field given the name. In both cases, you can use the usual point-and-click Complex property navigation. For example, you can map something like this: "username", or map to something complex: "Address.street.number".

  Column : the names of the columns obtained from the database, or the renamed labels for the column names. This is also the same string that is usually passed to the resultset.getstring (columnName) method parameter.

  Javatype: The fully qualified name of a Java class, or a type alias (a list of the above built-in type aliases). If you map to a javabean,mybatis you can usually determine the type. However, if you are mapping to HashMap, then you should explicitly specify javatype to guarantee the desired behavior.

  jdbctype: The type in the list of supported JDBC types after this table. The JDBC type is just a column that needs to be processed to insert, update, and delete operations that may be empty. This is the need for JDBC, not mybatis. If you are programming directly with JDBC, you need to specify this type-but only for values that may be empty.

  Typehandler: We discussed the default type processor earlier. With this property, you can override the default type processor. This property value is either the fully qualified name of the class or the implementation of a type processor, or a type alias.

3.constructor< constructor > 

<resultmap type= "Blog" id= "Blog_result_cs" >
<constructor>
<idarg column= "id" javatype= "int"/>
<arg column= "title" Javatype= "String"/>
</constructor>
</resultMap>

For most data transfer objects (data Transfer object,dto) types, properties can work, and like most domain models, directives may be where you want to use immutable classes. Tables that typically contain reference or query data are rarely or fundamentally unchanged, and are appropriate for immutable classes. Construction method injection allows you to set the value of a property for a class at initialization time without exposing the public method. MyBatis also supports private properties and private JavaBeans properties for this purpose, but some people prefer the constructor method injection. This is supported by the Constructor (constructor) element.

Package Com.accp.mybatis.model;

public class Blog {
Private Integer ID;
Private String title;
Private Integer Authorid;

Public Blog () {
}

Public Blog (integer ID, String title, Integer authorid) {
Super ();
System.out.println ("Use of the participating blog");
This.id = ID;
This.title = title;
This.authorid = Authorid;
}
//........
}

In order to inject the result into this constructor, MyBatis needs to identify the construction method by its type of argument. Java does not have a method for self-examination (or reflection) of parameter names. So when creating a construction method element, the parameters are guaranteed to be ordered in order, and the data type is also deterministic.

4.association< Correlation mapping > 

<!--map associated objects--
<association property= "Author" javatype= "Author" >
<id column= "author_id" property= "id"/>
<result column= "username" property= "username"/>
<result column= "password" property= "password"/>
<result column= "Email" property= "email"/>
<result column= "bio" property= "bio"/>
</association>

The correlation element handles the "have one" type of relationship. For example, in our example, a blog has a user. Correlation mapping works on this result. You specify the target property to get the column of the value, the Java type of the property (in many cases mybatis can calculate it yourself), and if necessary, the JDBC type, if you want to overwrite or get the result value also need type controller.

The difference in association is that you need to tell mybatis how to load the association. MyBatis There are two different ways to do this:

(1) Nested query: Returns the expected complex type by executing another SQL mapping statement.

(2) Nested results: Use nested result mappings to handle a subset of duplicate union results.

  Property : The field or attribute that is mapped to the column result. If a match is present, and the JavaBeans property of the given name is the same, then it will be used. Otherwise MyBatis will look for the field given the name. In both cases, you can use the usual point-and-click Complex property navigation. For example, you can map something like this: "username", or map to something complex: "Address.street.number".

  Column : columns name from database, or renamed column label. This is the same string that is normally passed to the resultset.getstring (ColumnName) method. Note: to process a composite primary key, you can specify multiple column names to be passed to the nested query statement through the syntax of column= "{prop1=col1,prop2=col2}". This causes PROP1 and PROP2 to be set to the target nested query statement in the form of a Parameter object.

  Javatype: The fully qualified name of a Java class, or a type alias (a list of the above built-in type aliases). If you map to a javabean,mybatis you can usually determine the type. However, if you are mapping to HashMap, then you should explicitly specify javatype to guarantee the desired behavior.

  Jdbctype: The fully qualified name of a Java class, or a type alias (a list of the above built-in type aliases). If you map to a javabean,mybatis you can usually determine the type. However, if you are mapping to HashMap, then you should explicitly specify javatype to guarantee the desired behavior.

  Typehandler: We discussed the default type processor earlier. With this property, you can override the default type processor. This property value is either the fully qualified name of the class or the implementation of a type processor, or a type alias.

Federated nesting selection (Nested Select for association)

  Select: through this property, another mapping statement that loads a complex type is referenced by ID. The value returned from the specified column property is set as a parameter to the target SELECT statement. There will be an example below the table. Note: You can use syntax such as column= "{prop1=col1,prop2=col2}" to set multiple column names into nested statements when working with key combinations. This will set the Prop1 and prop2 to the parameter object of the target nested statement.

5.SELECT < joint search >  

<resultmap type= "Blog" id= "Blog_result" >
<association property= "Author" column= "author_id"
Javatype= "Author" select= "Selectauthorbyid"/>
</resultMap>

<select id= "Selectauthorbyid" parametertype= "int" resulttype= "Author" >
SELECT * from Author where id = #{id}
</select>

<!--
Select Association, which is recommended for one-to-one situations.
Here, if Selectblogbyid returns more than one blog, it will bring n+1 problems
-
<select id= "Selectblogbyid" parametertype= "int" resultmap= "Blog_result" >
SELECT * from Blog where id = #{id}
</select>

We have two query statements: one to load the blog, the other to load the author, and the result map of the blog describes what the "Selectauthorbyid" statement should be used to load its Author property.
All other properties will be loaded automatically, assuming their columns and property names match.

This is a simple approach, but will not perform well for large data collections and lists. The problem is the "n+1 query problem" that we are familiar with. To summarize, the n+1 query problem can be caused by:

1. You execute a separate SQL statement to get a list of results (that is, "+1").

2. For each record returned, you execute a query statement to load the details for each (that is, "N").

Associated Nested results

  Resultmap: This is the ID of the result map, which can map the associated nested results to an appropriate object graph. This is an alternative way to invoke another query statement. This allows you to combine multiple tables to synthesize into a single result set. Such a result set may contain duplicates, the repeating group of the data needs to be decomposed, and reasonably mapped to a nested object graph. To make it easy, MyBatis lets you "link" the result map to handle nested results. Examples are easy to follow, and there is an example behind the table.

  

<select id= "Selectblog" parametertype= "int" 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>

Note This federated query, and take protection to ensure that all results are renamed with a unique and clear name. This makes the mapping very simple. Now we can map this result:

  

<resultmap id= "Blogresult" type= "Blog" >
<id property= "blog_id" column= "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>

very Important : The ID element plays a very important role in nested result mappings. You should typically specify one or more properties that can be used to uniquely identify the result. In fact, if you don't use it (the ID element), it can have a serious performance problem, but the MyBatis still works fine. The fewer properties you choose, the better they can uniquely identify the result. The primary key is an obvious choice (that is, the Federated primary key).

Now, the example above uses an external result mapping element to map the association. This allows author result mappings to be reused. However, if you do not need to reuse it, or you simply refer to all of your results mapped into a single described result map. You can nest result mappings. Here are the same examples that are used in this way:

<resultmap id= "Blogresult" type= "Blog" >
<id property= "blog_id" column= "id"/>
<result property= "title" column= "Blog_title"/>
<association property= "Author" column= "blog_author_id"
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"/>
</association>
</resultMap>

6.collection< Collection >

<collection property= "Posts" oftype= "Post" >
<id property= "id" column= "id"/>
<result property= "Subject" column= "Subject"/>
<result property= "Body" column= "body"/>
</collection>

The function of the collection element is almost identical to the association. In fact, they are very similar.

Let's go on to the example above, a blog with only one author. But blogs have lots of articles. In the blog class, this can be represented by the following notation:
Private list<post> posts;

To map the nested result collection to the list, we use the collection element. Just like associative elements, we can use nested queries from joins, or nest results.

Nested queries for collections

First, let's look at using nested queries to load articles for blogs.

<resultmap type= "Blog" id= "Blog_result" >
<association property= "Author" column= "author_id"
Javatype= "Author" select= "Selectauthorbyid"/>

<collection property= "Posts" javatype= "ArrayList" column= "id" oftype= "Post" select= "Selectblogpost"/>
</resultMap>

<select id= "Selectblogpost" resulttype= "Post" parametertype= "int" >
SELECT * from Post where Blog_id=#{id}
</select>

<select id= "Selectauthorbyid" parametertype= "int" resulttype= "Author" >
SELECT * from Author where id = #{id}
</select>

<!--
Select Association, which is recommended for one-to-one situations.
Here, if Selectblogbyid returns more than one blog, it will bring n+1 problems
-
<select id= "Selectblogbyid" parametertype= "int" resultmap= "Blog_result" >
SELECT * from Blog where id = #{id}
</select>

First, you should be aware that we are using a collection element. Then pay attention to the new "OfType" attribute. This property is important for distinguishing between javabean (or field) attribute types and the types that the collection contains. So you can read the following map:

<collection property= "Posts" javatype= "ArrayList" column= "id" oftype= "Post" select= "Selectblogpost"/>

Read as: "The collection of posts in the ArrayList of the post type. ”

Nested results of the collection 

<select id= "Selectblog" parametertype= "int" resultmap= "Blogresult" >
Select
b.ID as blog_id,
B.title as Blog_title,
b.author_id as blog_author_id,
P.id as post_id,
P.subject as Post_subject,
P.body as Post_body,
From Blog B
Left outer join Post P on b.id = p.blog_id
where b.id = #{id}
</select>

Now use the article Mapping Collection Mapping blog, can be simply written as:

<resultmap id= "Blogresult" type= "Blog" >
<id property= "id" column= "blog_id"/>
<result property= "title" column= "Blog_title"/>
<collection property= "Posts" oftype= "Post" >
<id property= "id" column= "post_id"/>
<result property= "Subject" column= "Post_subject"/>
<result property= "Body" column= "Post_body"/>
</collection>
</resultMap>

Remember the importance of the ID element.
If you refer to a longer form that allows for more reuse of your result mappings, you can use the following alternative mapping

<resultmap id= "Blogresult" type= "Blog" >
<id property= "id" column= "blog_id"/>
<result property= "title" column= "Blog_title"/>
<collection property= "Posts" oftype= "Post" resultmap= "Blogpostresult"/>
</resultMap>
<resultmap id= "Blogpostresult" type= "Post" >
<id property= "id" column= "post_id"/>
<result property= "Subject" column= "Post_subject"/>
<result property= "Body" column= "Post_body"/>
</resultMap>

7.disdiscriminator discriminator

<discriminator javatype= "int" column= "Draft" >
<case value= "1" resulttype= "Draftpost"/>
</discriminator>

Sometimes a single database query might return a number of different (but hopefully somewhat associative) result sets of data types. Discriminator elements are designed to handle this situation, as well as inheritance hierarchies that include classes. The discriminator is very easy to understand because it behaves much like a switch statement in the Java language.

The definition discriminator specifies the column and Javatype properties. The column is where MyBatis looks for comparison values. Javatype is the appropriate type to be used to ensure equivalence testing (although strings are useful in many cases). Like what:

<resultmap id= "Vehicleresult" type= "Vehicle" >
<id property= "id" column= "id"/>
<result property= "vin" column= "vin"/>
<result property= "Year", column= "year"/>
<result property= "make" column= "make"/>
<result property= "model" column= "model"/>
<result property= "Color" column= "Color"/>
<discriminator javatype= "int" column= "Vehicle_type" >
<case value= "1" resultmap= "Carresult"/>
<case value= "2" resultmap= "Truckresult"/>
<case value= "3" resultmap= "Vanresult"/>
<case value= "4" resultmap= "Suvresult"/>
</discriminator>
</resultMap>
<resultmap id= "Carresult" type= "Car" >
<result property= "Doorcount" column= "Door_count"/>
</resultMap>

In the example above, MyBatis will get each record from the result set, and then compare the value of its vehicle type. If it matches an instance of any discriminator, then the result mapping specified by this instance is used.
There is another syntax to do a concise mapping style. Like what:

<resultmap id= "Vehicleresult" type= "Vehicle" >
<id property= "id" column= "id"/>
<result property= "vin" column= "vin"/>
<result property= "Year", column= "year"/>
<result property= "make" column= "make"/>
<result property= "model" column= "model"/>
<result property= "Color" column= "Color"/>
<discriminator javatype= "int" column= "Vehicle_type" >
<case value= "1" resulttype= "Carresult" >
<result property= "Doorcount" column= "Door_count"/>
</case>
<case value= "2" resulttype= "Truckresult" >
<result property= "boxsize" column= "Box_size"/>
<result property= "Extendedcab" column= "Extended_cab"/>
</case>
<case value= "3" resulttype= "Vanresult" >
<result property= "Powerslidingdoor" column= "Power_sliding_door"/>
</case>
<case value= "4" resulttype= "Suvresult" >
<result property= "allwheeldrive" column= "all_wheel_drive"/>
</case>
</discriminator>
</resultMap>

  

  

MyBatis Advanced Mapping

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.