MyBatis多表查询(基于XML)

一、MyBatis表之间的关系

表之间的关系可以分为一对一、一对多、多对一和多对多四种关系。

  • 一对一:例如:一个人只能有一个身份证号。
  • 一对多:例如:一个用户可以有多个订单。
  • 多对一:例如:多个订单可以属于一个用户。
  • 多对多:例如:一个学生可以被多个老师教过,一个老师教多个学生。

特例:如果从多个订单中拿出某一个订单,那么它只属于一个用户。
在MyBatis中,多对一关系被看成一对一关系。因此,MyBatis表之间的关系有一对一、一对多、多对多三种关系组成。

二、一对一关系

一个账户只能属于一个用户,账户和用户之间属于一对一关系。
在这里插入图片描述
在这里插入图片描述
通过select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid=u.id;语句,得到下表结果。
在这里插入图片描述

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
    private User user;
    //get、set和toString方法省略
}
public interface IAccountDao {
    // 查询所有账户
    List<Account> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.uos.dao.IAccountDao">
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="aid" />
        <result property="uid" column="uid"/>
        <result property="money" column="money"/>
        <association property="user" column="uid" javaType="User">
            <id property="id" column="id"/>
            <result property="username" column="username"/>
            <result property="address" column="address"/>
            <result property="sex" column="sex"/>
            <result property="birthday" column="birthday"/>
        </association>
    </resultMap>
    <!--查询所有-->
    <select id="findAll" resultMap="accountUserMap" >
        select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid=u.id;
    </select>
</mapper>

一对多实现查询的关键点:
①在Account实体类中添加一个User对象,使得Account和User之间建立起联系。
②在配置文件中,使用<association></association>标签来封装User对象的结果集。

三、一对多关系

一个用户可以有多个账户,用户和账户是一对多的关系。
通过select u.*,a.id as aid,a.uid,a.money from user u left join account a on u.id=a.uid;语句,得到如下结果:
在这里插入图片描述

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private List<Account> account;
}
public interface IUserDao {
    // 查询用户所有的信息
    List<User> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.uos.dao.IUserDao">
    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id" />
        <result property="username" column="username"/>
        <result property="address" column="address"/>
        <result property="sex" column="sex"/>
        <result property="birthday" column="birthday"/>
        <collection property="account" ofType="Account">
            <id property="id" column="aid"/>
            <result property="uid" column="uid"/>
            <result property="money" column="money"/>
        </collection>
    </resultMap>
    <!--查询所有-->
    <select id="findAll" resultMap="userAccountMap" >
        select u.*,a.id as aid,a.uid,a.money from user u left join account a on u.id=a.uid;
    </select>
</mapper>

一对多查询实现的关键点:
①在User实体类中添加List<Account> account字段。
②在配置文件中使用<collection></collection>标签来封装account对象的结果集。

四、多对多关系

一个用户可以有多个角色,一个角色可以对应多个用户,用户和角色的关系属于多对多的关系。
多对多的关系我们可以参照一对多的关系进行配置,一对多的关系可以看成是多对多关系的一个组成部分
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1、用户部分

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private List<Role> roles;
}
public interface IUserDao {
    // 查询用户所有的信息
    List<User> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.uos.dao.IUserDao">
    <resultMap id="userMap" type="user">
        <id property="id" column="id" />
        <result property="username" column="username"/>
        <result property="address" column="address"/>
        <result property="sex" column="sex"/>
        <result property="birthday" column="birthday"/>
        <collection property="roles" ofType="com.uos.domain.Role">
            <id property="roleId" column="rid"/>
            <result property="roleName" column="role_name"/>
            <result property="roleDesc" column="role_desc"/>
        </collection>
    </resultMap>
    <!--查询所有-->
    <select id="findAll" resultMap="userMap" >
        select u.*,r.id as rid,r.role_name,r.role_desc from user u
           left outer join user_role ur on u.id = ur.uid
           left outer join role r on ur.rid = r.id
    </select>
</mapper>

2、角色部分

public class Role implements Serializable {
    private Integer roleId;
    private String roleName;
    private String roleDesc;
    private List<User> users;
}
public interface IRoleDao {
    List<Role> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.uos.dao.IRoleDao">
    <resultMap id="roleMap" type="role">
        <id property="roleId" column="rid" />
        <result property="roleName" column="role_name"/>
        <result property="roleDesc" column="role_desc"/>
        <collection property="users" ofType="com.uos.domain.User">
            <id property="id" column="id"/>
            <result property="username" column="username"/>
            <result property="address" column="address"/>
            <result property="sex" column="sex"/>
            <result property="birthday" column="birthday"/>
        </collection>
    </resultMap>
    <!--查询所有-->
    <select id="findAll" resultMap="roleMap" >
        select u.*,r.id as rid,r.role_name,r.role_desc from role r
            left outer join user_role ur on r.id = ur.rid
            left outer join user u on u.id = ur.uid
    </select>
</mapper>

3、小总结

实现MyBatis多对多的关系时,我们需要中间表(user_role)来进行转换,灵活使用SQL语句来进行查询,我们这里使用的是左外连接查询方式,最后将查询的结果封装到结果集即可。

原创文章 154 获赞 48 访问量 8546

猜你喜欢

转载自blog.csdn.net/weixin_41842236/article/details/105768170
今日推荐