Mybatis多表連接查詢

Mybatis多表連接查詢 需要藉助<resultMap>標籤

1.<resultMap>標籤的使用

在MyBatis中, 查詢標籤有兩個屬性, resultType和resultMap. 都代表返回結果的類型. 區別在於:

  • resultType指定的一個類型, MyBatis會進行自動映射(Auto-Mapping). 列名和屬性名一致則進行映射, 否則屬性被賦值爲null.
  • resultMap屬性指定的是標籤的id值. 表示MyBatis不進行自動映射, 需要程序員自己定義映射關係.

2.表格設計

# 選中數據庫
use db_ssm;
# 創建班級表
create table tb_class (
    id integer primary key auto_increment,
    name varchar(10) not null,
    room varchar(10)
);

# 創建學生表
create table tb_student (
    id integer primary key auto_increment,
    name varchar(20) not null,
    gender char(1),
    birthday date,
    cid integer
);

# 建立約束
alter table tb_student add constraint fk_cid foreign key (cid) references tb_class (id);

# 添加數據
insert into tb_class values
(default, 'Java', '505'),
(default, 'UI', '510'),
(default, '大數據', '405');

insert into tb_student values
(default, '張無忌', '男', '1998-12-12', 1),
(default, '趙敏', '女', '1999-12-12', 2),
(default, '謝遜', '男', '1998-12-12', 2),
(default, '成昆', '男', '1998-12-12', 3),
(default, '周芷若', '女', '1998-12-12', 3),
(default, '小昭', '女', '1998-12-12', 3);

3.實體類創建

  • Clazz類, 班級表. 學生泛型的List集合, 表示班級下所有的學生信息.
  • Student類, 學生表. 班級對象, 表示學生所屬的班級信息.
    如果需要toString方法, 注意不要出現無限遞歸的情況. 防止發生堆棧溢出異常.

4.多表連接查詢的幾種情況

  a)多對一查詢: 基於學生查班級, 使用標籤<association>

  • 關聯方式查詢
    通過多表關聯的SQL語法進行查詢, 需要使用join, on, …來實現查詢. 執行一條SQL語句就可以將所有需要的數據全部查詢到. 我們需要做的就是將查到的數據進行映射即可.
<resultMap id="smap" type="student" autoMapping="true">
    <!--關聯單個對象要使用association-->
    <association property="clazz" javaType="clazz" autoMapping="true">
        <id column="cid" property="id" />
        <result column="cname" property="name" />
    </association>
</resultMap>

<select id="selAll" resultMap="smap">
    select
        s.*, c.name cname, c.room
    from
        tb_student s
    left join
        tb_class c
    on
        s.cid = c.id
</select>

  • N+1方式查詢
    表示所有數據要獲取到需要執行N+1條SQL語句. 每次查詢都是單表查詢, 查多次就拿到所有數據了.
<resultMap id="smap2" type="student">
    <!--映射單個對象-->
    <association
            property="clazz"
            javaType="clazz"
            select="com.bjsxt.mapper.ClazzMapper.selById"
            column="cid" />
</resultMap>
<select id="selAll2" resultMap="smap2">
    select * from tb_student
</select>
<mapper namespace="com.bjsxt.mapper.ClazzMapper">
    <select id="selById" resultType="clazz">
        select * from tb_class where id=#{id}
    </select>
</mapper>

b)一對多查詢: 基於班級查學生, 使用標籤<collection>

  • 關聯查詢
<resultMap id="cmap" type="clazz" autoMapping="true">
    <!--關聯集合對象, 使用collection標籤-->
    <collection property="students" javaType="list" ofType="student" autoMapping="true">
        <id column="sid" property="id" />
        <result column="sname" property="name" />
    </collection>
</resultMap>

<select id="selAll" resultMap="cmap">
    select
        c.*, s.id sid, s.name sname, s.gender, s.birthday
    from
        tb_class c
    left join
        tb_student s
    on
        c.id = s.cid
</select>
  • N+1查詢
<resultMap id="cmap2" type="clazz">
    <!--如果這一列作爲參數繼續傳遞, 會導致自動映射失敗-->
    <id column="id" property="id" />
    <collection
            property="students"
            javaType="list"
            ofType="student"
            select="com.bjsxt.mapper.StudentMapper.selByCid"
            column="id" />
</resultMap>
<select id="selAll2" resultMap="cmap2">
    select * from tb_class
</select>
<mapper namespace="com.bjsxt.mapper.StudentMapper">
    <select id="selByCid" resultType="student">
        select * from tb_student where cid=#{cid}
    </select>
</mapper>

c)業務裝配方式查詢

   a)關聯查詢:
  • sql語句是關聯語法, 需要使用join…on…
  • 只需要執行1條SQL語句
  • 默認情況下, 不會自動映射, 可以通過設置autoMapping=true開啓自動映射
   b)N+1查詢:
  • SQL語句都是單表查詢
  • 需要執行N+1次查詢才能得到結果
  • 默認情況下, 就會自動映射.

注意:多表連接查詢儘量開啓懶加載 減少資源浪費

開啓延遲加載的方式有兩種

  • 1:全局配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="jdbc.properties"/>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <!--開啓延時加載-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="true"/>
    </settings>
    <typeAliases>
        <package name="com.jdbc.pojo"/>
    </typeAliases>
    <environments default="development">

        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--<mapper resource="com/jdbc/mapper/StudentMapper.xml"/>-->
        <package name="com.jdbc.mapper"></package>
    </mappers>
</configuration>
  • 2.給某個方法單獨配置 fetchType=“lazy”
    <collection property=“courses” ofType=“course” autoMapping=“true” fetchType=“lazy”>
<?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.jdbc.mapper.TeacherMapper">

    <!--public List<Course> getCourseById(Integer id);-->
    <resultMap id="myMap1" type="teacher">
        <id column="tid" property="tid"/>
        <result column="tname" property="tname"/>
        <collection property="courses"  ofType="course" autoMapping="true" fetchType="lazy">
        </collection>

    </resultMap>
    <select id="getCourseById" resultMap="myMap1">
   SELECT  t.TId tid,t.Tname tname,c.CId cid,c.Cname cname
    from teacher t LEFT JOIN course c on
     t.tid = c.TId where t.TId =#{id}
  </select>


    <resultMap id="myStep" type="teacher" autoMapping="true">

        <collection property="courses" select="com.jdbc.mapper.CourseMapper.getCourseById" column="tid" ofType="course">

        </collection>
    </resultMap>

    <select id="getTeacherById" resultMap="myStep" >

        select * from teacher where tid = #{id}
    </select>


</mapper>

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章