Mybatis级联操作的实现

背景

Mybatis的级联操作主要是针对一对多、多对一和多对多的情况而设定的。级联是在resultMap标签中配置的。级联并不是必须的,好处就是获取关联数据便捷,但如果级联过多会增加系统的复杂度,同时降低系统的性能。

一对多

一个人对应多件衣服为例

只查询一次

(1)先来看一下 标签中的属性:
property:对象属性的名称,对应一对多中一的字段名
ofType:指定的是映射到集合属性中bean的类型
column:所对应的外键字段名称
select:使用另一个查询封装的结果
xml文件

 <!--一对多级联查询 resultMap-->
    <resultMap id="oneToMoreResultMap" type="com.lks.bean.User">
        <id column="id" property="id"></id>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="county" column="county"/>
        <result property="date" column="date"/>
        <!--对应一对多中一的字段名-->
        <collection property="clothes" ofType="com.lks.bean.Clothe">
            <id column="clothe_id" property="clotheId"></id>
            <result column="clothe_color" property="clotheColor"></result>
            <result column="user_id" property="userId"></result>
        </collection>
    </resultMap>

    <select id="oneToMoreQuery" parameterType="int" resultMap="oneToMoreResultMap">
        select id, name, age, county, date, clothe_id, clothe_color
        FROM users join clothes on users.id = clothes.user_id
        where users.id = #{id}
    </select>

主要注意的是collection标签的property属性要对应一对多中一的字段名
在这里插入图片描述
mapper接口

public interface UserMapper {
    List oneToMoreQuery(int id);
}

查询多次

当然也可以通过 < collection > 标签中 select 属性来执行另一个映射语句来返回预期的复杂类型结果
xml文件

  <!--一对多级联查询 resultMap2-->
    <resultMap id="oneToMoreResultMap2" type="com.lks.bean.User">
        <id column="id" property="id"></id>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="county" column="county"/>
        <result property="date" column="date"/>
        <!--对应一对多中一的字段名-->
        <collection property="clothes" ofType="com.lks.bean.Clothe" column="id" select="otherQuery">
            <id column="clothe_id" property="clotheId"></id>
            <result column="clothe_color" property="clotheColor"></result>
            <result column="user_id" property="userId"></result>
        </collection>
    </resultMap>
    <select id="otherQuery" parameterType="int" resultType="com.lks.bean.Clothe">
        select clothe_id, clothe_color
        FROM clothes
        where user_id = #{user_id}
    </select>
    <select id="oneToMoreQuery2" parameterType="int" resultMap="oneToMoreResultMap2">
        select id , name, age, county, date
        FROM users
        where id = #{id}
    </select>

这个 < collection > 标签的select意思是:根据 oneToMoreQuery2 方法查询出的结果对象中的 id 属性当做参数,传递给 otherQuery 方法再次进行查询,实际上是执行了两次查询操作。

多对一

多件衣服对应一个人为例

先来看一下 < association > 标签中的属性:

property:对象属性的名称
javaType:对象属性的类型
column:所对应的外键字段名称
select:使用另一个查询封装的结果
在Clothe类中新增User属性
在这里插入图片描述
和一对多的场景类似,只不过这里是借助了association标签来进行关联:
xml文件:

<!--多对一级联查询 resultMap-->
    <resultMap id="moreToOneResult" type="com.lks.bean.Clothe">
        <id column="clothe_id" property="clotheId"></id>
        <result column="clothe_color" property="clotheColor"></result>
        <result column="user_id" property="userId"></result>
        <!--对应多对一中多的字段名-->
        <association property="user" javaType="com.lks.bean.User">
            <id column="id" property="id"></id>
            <result property="name" column="name"/>
            <result property="age" column="age"/>
            <result property="county" column="county"/>
            <result property="date" column="date"/>
        </association>
    </resultMap>
    <select id="moreToOneQuery" parameterType="int" resultMap="moreToOneResult">
        select id, name, age, county, date, clothe_id, clothe_color
        FROM users join clothes on users.id = clothes.user_id
        where clothes.user_id = #{id}
    </select>

多对多

以用户和角色这个例子,一个用户可以属于多个角色,一个角色又可以分配多个用户,这就形成了一个多对多的关系,由于是多对多,就要使用到第三张表,这是一个关系表,用于记录两个表中的主键。
users表:
在这里插入图片描述
roles表:
在这里插入图片描述
user_role表:
在这里插入图片描述
查询user中的多角色
xml文件

<!--多对多级联查询 resultMap-->
    <resultMap id="moreToMoreResultMap" type="com.lks.bean.User">
        <id column="id" property="id"></id>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="county" column="county"/>
        <result property="date" column="date"/>
        <collection property="roles" ofType="com.lks.bean.Role" column="id">
            <id column="role_id" property="roleId"></id>
            <result column="role_name" property="roleName"></result>
        </collection>
    </resultMap>

    <select id="moreToMoreQuery" parameterType="int" resultMap="moreToMoreResultMap">
        select users.id, name, age, county, date, roles.role_id, role_name
        FROM users
        join user_role on users.id = user_role.user_id
        join roles on roles.role_id = user_role.role_id
        where users.id = #{id}
    </select>

查询role中的多用户
xml文件

<!--多对多级联查询 resultMap-->
    <resultMap id="moreToMoreResultMap" type="com.lks.bean.User">
        <id column="id" property="id"></id>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <result property="county" column="county"/>
        <result property="date" column="date"/>
        <collection property="roles" ofType="com.lks.bean.Role" column="id">
            <id column="role_id" property="roleId"></id>
            <result column="role_name" property="roleName"></result>
        </collection>
    </resultMap>

    <select id="moreToMoreQuery" parameterType="int" resultMap="moreToMoreResultMap">
        select users.id, name, age, county, date, roles.role_id, role_name
        FROM users
        join user_role on users.id = user_role.user_id
        join roles on roles.role_id = user_role.role_id
        where users.id = #{id}
    </select>

其实多对多就是两个一对多组成的,一对多掌握了,多对多也就很容易上手了。
所以最重要的还是要掌握住一对多和多对一的写法,一法通则万法通,最基础的掌握住了,一对一和多对多也就不难理解了。另外主要好好理解 < collection > 和 < association > 标签,mybatis中级联查询的实现就是通过这两个标签实现的。

猜你喜欢

转载自blog.csdn.net/lks1139230294/article/details/88087470
今日推荐