MyBatis中的collection两种使用方法及效率比较

2022-11-13 10:11:58 效率 两种 使用方法

collection主要是应对表关系是一对多的情况

查询的时候,用到联表去查询

接下来的小案例包括:市,学校,医院(随便写的),写一个最简单的demo

主要的功能就是查询出所有的市以及对应的市下面所有的学校和医院

实体类:医院

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Hospital {
    private int id;                 //医院编号
    private int urbanId;            //市的编号
    private String hospitalName;    //医院名称
    private Long people;            //医院人数
}

实体类:学校

@Data
@AllArgsConstructor
@NoArgsConstructor
public class School {
    private int id;               //学校编号
    private int urbanId;          //市的编号
    private String schoolName;    //学校名字
    private Long people;          //学校人数
}

实体类:市

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Urban {
    private int id;                   //市的编号
    private String cityId;            //省的编号(此博文没用到)
    private String urbanName;         //城市名字
    private List<School> schools;     //对应的所有的学校
    private List<Hospital> hospitals; //对应的所有的医院
}

第一种方式,采用select

首先我们要在学校和医院接口对应的xml中写出按照市的编号来查询出所有数据的xml

xml:医院

<?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.yh.mybatis.dao.mapper.HospitalMapper">
    <select id="findAllByUId" resultType="com.yh.mybatis.dao.pojo.Hospital">
        select * from hospital where urban_id = #{urbanId}
    </select>
<!--实际工作不建议用 *,id就是mapper接口中对应的方法名,resultType就是查询出结果后返回的list的泛型 
 urban_id = #{urbanId} 按照urban_id去查找-->
</mapper>

xml:学校

<?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.yh.mybatis.dao.mapper.SchoolMapper">
    <select id="urbanSchool" resultType="com.yh.mybatis.dao.pojo.School">
        select * from school where urban_id = #{urbanId}
    </select>
</mapper>

接下来就是在市的xml中对学校和医院的xml进行一个调用(用collection中select)

<?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.yh.mybatis.dao.mapper.UrbanMapper">
      <resultMap id="findAllUrbanSandH" type="com.yh.mybatis.dao.pojo.Urban">
        <collection property="schools" javaType="java.util.List" ofType="com.yh.mybatis.dao.pojo.School"
                    select="com.yh.mybatis.dao.mapper.SchoolMapper.urbanSchool"
                    column="{urbanId=id}">
        </collection>
        <collection property="hospitals" javaType="java.util.List" ofType="com.yh.mybatis.dao.pojo.Hospital"
                    select="com.yh.mybatis.dao.mapper.HospitalMapper.findAllByUId"
                    column="{urbanId=id}">
        </collection>
    </resultMap>
<!--
        resultMap中的 <id><result>都可以不写,直接写List<School>和List<Hospital>
                                    type还是sql的返回类型
        collection中  property 是Urban中对应的字段
                                    javaType 是这个字段的类型
                                    ofType 是这个字段的泛型  这一项和上一项其实都可以不写,写上了看着更清晰
                                    select 是子表的按照市的编号查询所有数据的方法 这里要写下全路径
                                    column 作为select语句的参数传入, 也就是把市的编号id 传给医院和学校xml的urbanId
-->
        <select id="findAllUrbanSandH" resultMap="findAllUrbanSandH">
        select * from urban
    </select>
</mapper>

第二种方式,执行一次sql

<?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.yh.mybatis.dao.mapper.UrbanMapper">
        <resultMap id="findAllUrbanSandH2" type="com.yh.mybatis.dao.pojo.Urban">
        <id property="id" column="id"/>
        <result property="cityId" column="city_id"/>
        <result property="urbanName" column="urban_name"/>
<!--这上面这几个字段就是urban表中,自带的那几个字段-->
        <collection property="schools" javaType="java.util.List" ofType="com.yh.mybatis.dao.pojo.School">
            <id property="id" column="sid"/>
            <result property="urbanId" column="surban_id"/>
            <result property="schoolName" column="school_name"/>
            <result property="people" column="speople"/>
        </collection>
<!--这上面就是school表中的字段
        javaType是urban类中定义的school的类型  可以不写
        ofType就是泛型,这个还是很有必要的,接下来的id result 就是这个类中定义的各种字段,要写全
        如果涉及到的任何表中,在数据库中有重复的字段名,那就必须要起别名。(例如各个表中的id)
        起别名直接在下面的sql中就可以。
-->
        <collection property="hospitals" javaType="java.util.List" ofType="com.yh.mybatis.dao.pojo.Hospital">
            <id property="id" column="hid"/>
            <result property="urbanId" column="hurban_id"/>
            <result property="hospitalName" column="hospital_name"/>
            <result property="people" column="hpeople"/>
        </collection>
    </resultMap>
        <select id="findAllUrbanSandH2" resultMap="findAllUrbanSandH2">
        select  urban.city_id
                ,urban.id
                ,urban.urban_name
                ,school.id sid
                ,school.urban_id surban_id
                ,school.school_name
                ,school.people speople
                ,hospital.id hid
                ,hospital.urban_id hurban_id
                ,hospital.hospital_name
                ,hospital.people hpeople
        from urban
            inner join school on urban.id = school.urban_id
            inner join hospital on urban.id = hospital.urban_id
    </select>
</mapper>

接下来就可以写两个接口来测试这两个xml配置是否正确,具体的代码在最上面的码云地址里,大家可以配合swagger进行测试。

比较

方案一:需要执行至少三次sql语句,开启三次事务才能完成本次请求。
方案二:需要执行一次sql语句,开启一次事务就能完成本次请求

方案二比方案一的效率要高,但是在使用的时候,方案一的代码可重用性要高

如果想要追求代码重用性可以选择方案一
如果比较在乎运行的性能可以选择方案二

到此这篇关于MyBatis中的collection两种使用方法及效率比较的文章就介绍到这了,更多相关MyBatis collection使用方法内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章