Mybatis -- Multiple Table Association

Keywords: xml Attribute Mobile

There are three relationships between table and table operations: one-to-one, one-to-many, and many-to-many.
How to understand these three relationships?
Everyone has only one ID number, which is a one-to-one relationship.
Everyone can have more than one bank card. This is one-to-many relationship.
Everyone can have more than one bank card, and each bank can have more than one user. This is the multi-to-many relationship.

One-on-one

In the real-name system of accounts, there is only one user corresponding to an account. The pojo of account is as follows:

public class Account {
    private Integer id;
    private String name;
    private Float money;
    private Integer u_id;
	// The get and set methods are omitted here.
}

There are three ways to configure one-to-one relationships in Mobile:
1.1 Create a new pojo named Account User, which contains attributes of User and Accept. We operate on this new pojo directly. But this way obviously does not conform to our routine operation, I will not elaborate.

1.2 Don't we just want account to contain user information? We just add a user attribute to account.

public class Account {
    private Integer id;
    private String name;
    private Float money;
    private Integer u_id;
	// The get and set methods are omitted here.

	private User user;
}

The mapping relationship is mapped by resultMap. When configuring user, property needs to write user.xxx to map separately.

	<resultMap id="accounts" type="Account">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="money" property="money"></result>
        <result column="u_id" property="u_id"></result>
        <!--mapping user Attributes in-->
        <result column="uid" property="user.id"></result>
        <result column="uname" property="user.username"></result>
        <result column="address" property="user.address"></result>
        <result column="birthday" property="user.birthday"></result>
        <result column="sex" property="user.sex"></result>
        <result column="password" property="user.password"></result>
    </resultMap>

This method is also more troublesome, if the user has 100 attributes, you need more than 100 users, too uncomfortable.

1.3 When mapping relationships, associations are used to map. This is designed for a single object, so we can omit the user of property in the former method, and this method is more clear. When we look at associations, we know that this is a one-to-one relationship. Let's explain here, because it's a multi-table association, even if your table and entity fields are the same, result can't be omitted, otherwise null will appear after the query.

	<resultMap id="accounts" type="Account">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="money" property="money"></result>
        <result column="u_id" property="u_id"></result>
        <!--mapping user Attributes in-->
        <!--association Mapping a single object
        	property: Property name
        	javaType:Types corresponding to attributes
        -->
        <association property="user" javaType="user">
            <id column="uid" property="id"></id>
            <result column="uname" property="username"></result>
            <result column="address" property="address"></result>
            <result column="birthday" property="birthday"></result>
            <result column="password" property="password"></result>
            <result column="sex" property="sex"></result>
        </association>
    </resultMap>

One-to-many

A user can have multiple accounts and a list is used to store account objects, so our user's pojo is as follows:

public class User {
    private Integer id;
    private String username;
    private String password;
    private String address;
    private Date birthday;
    private String sex;
    // One user corresponds to multiple accounts
    private List<Account> accountList;
    // Omitting get and set methods
  }

When configuring xml, we use collection to configure one-to-many relationships, and the result in resultMap cannot be omitted.

	<resultMap id="users" type="User">
        <id column="uid" property="id"></id>
        <result column="uname" property="username"></result>
        <result column="password" property="password"></result>
        <result column="address" property="address"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <!--Collection : mapping accountList attribute
                property: The corresponding attribute name
                ofType: Element types in sets: association in javaType The effect is the same.
        -->
        <collection property="accountList" ofType="account">
            <id column="id" property="id"></id>
            <result column="name" property="name"></result>
            <result column="money" property="money"></result>
            <result column="u_id" property="u_id"></result>
        </collection>
    </resultMap>
    
	<select id="findAll" resultMap="users">
         select * from user u left join account a on u.uid = a.u_id
    </select>

Many-to-many

We can have more than one user (administrator, ordinary user), administrator, ordinary user can also be more than one user, we need an intermediate table user_role to correspond to the relationship between the two.

Many-to-many is actually the same as one-to-many. One-to-many is to configure a collection in the xml of the one side, and many-to-many is to configure a collection on both sides to correspond.
This means that both user s and role s contain a list of each other:

	public class Role {
    private Integer id;
    private String roleName;
    private String roleDesc;
	//    One role corresponds to multiple users
    private List<User> userList;
  }
	public class User {
    private Integer id;
    private String username;
    private String password;
    private String address;
    private Date birthday;
    private String sex;
	//    A user has multiple roles
    private List<Role> roleList;
  }

In userDao.xml, fields corresponding to role s

<mapper namespace="com.itheima.dao.UserDao">
    <resultMap id="users" type="user">
        <id column="uid" property="id"></id>
        <result column="uname" property="username"></result>
        <result column="address" property="address"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="password" property="password"></result>
        <!--One user corresponds to multiple roles: roleList-->
        <collection property="roleList" ofType="role">
            <id column="id" property="id"></id>
            <result column="roleName" property="roleName"></result>
            <result column="roleDesc" property="roleDesc"></result>
        </collection>
    </resultMap>

    <select id="findAll" resultMap="users">
      select u.* ,r.* from user u left join user_role ur on u.uid = ur.uid left join role r on r.id = ur.rid
    </select>
</mapper>

Fields corresponding to user in roleDao.xml

<mapper namespace="com.itheima.dao.RoleDao">
    <resultMap id="roles" type="role">
        <id column="id" property="id"></id>
        <result column="roleName" property="roleName"></result>
        <result column="roleDesc" property="roleDesc"></result>
        <collection property="userList" ofType="User">
            <id column="uid" property="id"></id>
            <result column="uname" property="username"></result>
            <result column="address" property="address"></result>
            <result column="birthday" property="birthday"></result>
            <result column="sex" property="sex"></result>
            <result column="password" property="password"></result>
        </collection>
    </resultMap>

    <select id="findAll" resultMap="roles">
      select r.*,u.* from role r left join user_role ur on r.id = ur.rid left join user u on u.uid = ur.uid
    </select>
</mapper>

Note: When toString() is written in User and Role, only one is written. For example, in User, toString() of roleList is written, in Role, toString() of userList is not written, and it will go into a dead cycle.

Posted by Dr John on Mon, 22 Jul 2019 02:02:35 -0700