Mybatis ---- resultMap Type In Depth

Mybatis ---- resultMap Type In Depth

This article is mainly to introduce the relevant information about Mybatis the powerful resultMap function, the paper sample code described in great detail to all of us to learn or use Mybatis has certain reference value of learning, need friends Let's together learn it

Foreword

In Mybatis, there is a powerful element resultMap. When we want the data in JDBC ResultSets are converted to Java objects and reasonable, you can feel its extraordinary place. As the official put it:

MyBatis resultMap element is the most important and powerful elements. It allows you to extract the code freed 90% of the data from JDBC ResultSets, and allows you to make some JDBC does not support operations in some cases. In fact, at the time of writing the code for mapping complex statements such as connected, instead of a resultMap can achieve up thousands of lines of code for the same functions. ResultMap The idea is for the simple statements do not need to configure explicit mapping results, and for a bit more complex statements need only describe their relationship on the line.

First, field mapping

In Mybatis, the result of mapping the easiest way is processed by the type of alias typeAliases.

If you do this, then the first step you need to configure the path entity classes package:

mybatis.type-aliases-package=com.xxx.entity

All classes in this path, it will be registered TYPE_ALIASES container. We specify a return value type, the direct use of aliases can be.

For example, we have a User class:

@Data
public class User {
 private String id;
 private String username;
 private String password;
 private String address;
 private String email;
}

If the attribute name of the table in the database fields with the same User class, we can use it to return resultType.

<select id="getUsers" resultType="User">
    SELECT
        u.id,
        u.username,
        u.password,
        u.address,
        u.email
    FROM
        USER u
</select>

Of course, this is the ideal state, attributes, and field names are exactly the same situation. But in fact, inconsistency is there, this time we will resultMap debut.

If the User class remain the same, but the SQL statement has changed, it changed the id uid.

<select id="getUsers" resultType="User">
    SELECT
        u.id as uid,
        u.username,
        u.password,
        u.address,
        u.email
    FROM
        USER u
</select>

Then, in the result set, we will be lost id data. This time we can define a resultMap, to map the different fields.

<resultMap id="getUserByIdMap" type="User">
    <result property="id" column="uid"></result>
</resultMap>

Then, we put the above select statement to modify resultType resultMap="getUserByIdMap".

There is a column corresponding to a column name or alias database; Property or attribute is a field corresponding to the result set.

ResultMap This is the most simple, most basic usage: field mapping.

Below, we take a look at how several other labels are applied.

Element Name description
constructor When a class is instantiated, the constructor injection results
association Associated with an object
collection Associate multiple objects

Second, the construction method

If you want to inject the results of the constructor, the constructor elements can be used.

For example, we added a User class constructor:

public User(String id, String name) {
    this.id = id+"--------";
    this.username = name+"--------";
}

We need to define a constructor element in resultMap in:

<resultMap id="getUserByIdMap" type="User">
    <constructor>
        <idArg column="id" name="id" javaType="string"></idArg>
        <arg column="username" name="name" javaType="string"></arg>
    </constructor>
</resultMap>

Wherein, on behalf of the database field names or aliases column; name is the name of the parameter configuration method; parameter specifies the type of the javaType.

As you can imagine, such a designation constructor, we focus on the results of the id and username properties will change.

{
 "id": "1001--------",
 "username": "后羿--------",
 "password": "123456",
 "address": "北京市海淀区",
 "email": "[email protected]"
}

Third, the association

In the actual business, our customers usually have a role. Then the User class which are generally to an entity class to represent

@Data
public class User {
 //省略用户属性...
     
 //角色信息
 private Role role;
}

We query the user's time, if you would like to see its role information, we would write the query:

<select id="getUserById" resultType="User">
 SELECT
  u.id,
  u.username,
  u.password,
  u.address,
  u.email,
  r.id as 'role_id',
  r.name as 'role_name'
 FROM
  USER u
  LEFT JOIN user_roles ur ON u.id = ur.user_id
  LEFT JOIN role r ON r.id = ur.role_id
 where u.id=#{id}
 </select>

As above, we must query a single user and the user's role information. But here, we can not resultType=Userbe returned.

After all, User Role class is only one object, and no role_id and role_name field properties.

Therefore, we must use the association to associate them.

<resultMap id="userMap" type="User">
    <id property="id" column="id"></id>
    <result property="username" column="username"></result>
    <result property="password" column="password"></result>
    <result property="address" column="address"></result>
    <result property="email" column="email"></result>
     
    <association property="role" javaType="Role">
        <id property="id" column="role_id"></id>
        <result property="name" column="role_name"></result>
    </association>
</resultMap>

Finally, we can be a role information is displayed:

{
 "id": "1001",
 "username": "后羿",
 "password": "123456",
 "address": "北京市海淀区",
 "email": "[email protected]",
 "role": {
 "id": "3",
 "name": "射手"
 }
}

In fact, if you're sure the information is associated with one of the cases, there is a more simple method can replace the association, we are in the fifth part of this article - it is how to achieve the look associated objects automatically populated.

Fourth, the collection

1, nested results of mapping

Above we see a user Yi, its role is shooter; but most of the time, each of us can not just have a kind of role. So, we need to type in the User class character attributes into a List.

@Data
public class User {
 //省略用户属性...
     
 //角色信息
 private List<Role> roles;
}

Now becomes a user corresponding to the multiple roles, so it is not a simple association.

Because the association process is linked to a type; and here we are associated with multiple types, so we need to use the collection properties.

Our overall resultMap would this be the following:

<resultMap id="userMap" type="User">
    <id property="id" column="id"></id>
    <result property="username" column="username"></result>
    <result property="password" column="password"></result>
    <result property="address" column="address"></result>
    <result property="email" column="email"></result>
     
    <collection property="roles" ofType="Role">
        <id property="id" column="role_id"></id>
        <result property="name" column="role_name"></result>
    </collection>
</resultMap>

In this case, even if you have more than one role can be displayed correctly:

{
 "id": "1003",
 "username": "貂蝉",
 "password": "123456",
 "address": "北京市东城区",
 "email": "[email protected]",
 "roles": [
  {
   "id": "1",
   "name": "中单"
  },
  {
   "id": "2",
   "name": "打野"
  }
 ]
}

2, Nested Select for Collection

In most business systems, we will have a menu of the table, for example like this, a Menu table:

id name url parent_id
1 System Management 0
1001 User Management /user 1
1002 Role Management /role 1
1003 Unit Management /employer 1
2 Monitoring platform 0
2001 System monitoring /system/monitor 2
2002 Data monitoring /data/monitor 2

Here we give the menu is divided into two. We returned to the front-end menu when grading is required, it is impossible these seven data show same level. Well, here we are Menu entity classes are as follows:

@Data
public class Menu {
 private String id;
 private String name;
 private String url;
 private String parent_id;
 private List<Menu> childMenu;
}

A menu, the menu comprising a list of two, here represented by childMenu.

SQL statement, if there is no parent_id field properties, we will check all the previous menu:

<select id="getMenus" resultMap="menusMap">
    SELECT
        m.id,
        m.name,
        m.url,
        m.parent_id
    FROM
        m_menu m
    where 1=1
    <choose>
        <when test="parent_id!=null">
            and m.parent_id = #{parent_id}
        </when>
        <otherwise>
            and m.parent_id = '0'
        </otherwise>
    </choose>
</select>

This query, without any transmission parameters, we will get data of two level menu.

So in the case of this method is invoked only once, how to check out all the information menu, press the hierarchical display it?

We look menusMap definition:

<resultMap id="menusMap" type="Menu">
    <id property="id" column="id"></id>
    <result property="name" column="name"></result>
    <result property="url" column="url"></result>
    <result property="m_desc" column="m_desc"></result>
    <result property="parent_id" column="parent_id"></result>
     
    <collection property="childMenu" ofType="Menu" select="getMenus" column="{parent_id=id}"></collection>
</resultMap>

Key point of view collection elements:

property="childMenu"Corresponding to the child menu list menu;

ofType="Menu"Corresponding to the type of data returned;

select="getMenus"Specifies the id SELECT statement;

column="{parent_id=id}"It is the expression parameter.

The whole meaning of the collection can be understood:

Is acquired by getMenus SELECT statement childMenu properties result in a menu; SELECT statement above, the need to pass a parameter parent_id; this parameter is a menu id.

In this way, we can get all the information on the menu has been graded.

[
 {
  "id": "1",
  "name": "系统管理",
  "parent_id": "0",
  "childMenu": [
   {
    "id": "1001",
    "name": "用户管理",
    "url": "/user",
    "parent_id": "1"
   },
   {
    "id": "1002",
    "name": "角色管理",
    "url": "/role",
    "parent_id": "1"
   },
   {
    "id": "1003",
    "name": "单位管理",
    "url": "/employer",
    "parent_id": "1"
   }
  ]
 },
 {
  "id": "2",
  "name": "平台监控",
  "parent_id": "0",
  "childMenu": [
   {
    "id": "2001",
    "name": "系统监控",
    "url": "/system/monitor",
    "parent_id": "2"
   },
   {
    "id": "2002",
    "name": "数据监控",
    "url": "/data/monitor",
    "parent_id": "2"
   }
  ]
 }
]

V. the associated object autofill

We know that, parse the returned value when in Mybatis.

The first step is to obtain the type of the return value, to get Class object, and then obtain the constructor, and returns an instance is provided access, and then put it into MetaObject packaged objects.

After rs get results from the database, the call will MetaObject.setValue(String name, Object value)be filled objects.

In this process, it is interesting, it will. Separate the name attribute.

If the name attribute contains the symbol, they found. Attribute name before the symbol, think of it as a solid object to handle.

The author described here may not intuitive, we look at an example.

In the third part of this article, we have an example of a user corresponds to a role.

Wherein, User class is defined as follows:

@Data
public class User {
 //省略用户属性...
     
 //角色信息
 private Role role;
}

Here, we need to define resultMap, direct return resultType = User can. But the need to modify the alias role of information, focusing Symbol

<select id="getUserList" resultType="User">
    SELECT
        u.id,
        u.username,
        u.password,
        u.address,
        u.email,
        r.id as 'role.id',
        r.name as 'role.name'
    FROM
        USER u
            LEFT JOIN user_roles ur ON u.id = ur.user_id
            LEFT JOIN role r ON r.id = ur.role_id
</select>

Thus, to resolve the Mybatis role.id properties when it comes to after. Delimited found, Role alias corresponds Role object, Role object will be initialized, and the value to the id attribute.

to sum up

That's all for this article, I hope the contents of this paper has some reference value of learning for everyone to learn or work.

Guess you like

Origin www.cnblogs.com/XtsLife/p/12079933.html