最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis復(fù)雜Sql查詢實(shí)現(xiàn)示例介紹

 更新時(shí)間:2022年12月27日 11:35:29   作者:一個(gè)雙子座的Java攻城獅  
在利用mybatis做查詢的時(shí)候,一般返回結(jié)果用resulttype,這種情況必須是查詢的結(jié)果在對(duì)應(yīng) 的pojo類中有對(duì)應(yīng)的,一般都是單表查詢,但是對(duì)于一些復(fù)雜的情況,比如需要用到多表查詢的時(shí)候,resultType不再適用,此時(shí)一般用resultMap來(lái)表示返回的結(jié)果

resultMap 結(jié)果映射

resultMap 元素是 MyBatis 中最重要最強(qiáng)大的元素,之前所寫的 sql 語(yǔ)句,返回值都是簡(jiǎn)單的基本數(shù)據(jù)類型或者某一個(gè)實(shí)體類,比如下面這段 sql 返回的就是最簡(jiǎn)單的 User 類型。

<select id="getUserById" resultType="user" parameterType="int">
    select * from user where id=#{id};
</select>

現(xiàn)在思考一下下面這種情況,如果實(shí)體類中定義的某一個(gè)字段和數(shù)據(jù)庫(kù)中的字段不一致怎么辦?

public class User {
    private int id;
    private String lastname;
    //.....
}

比如我定義了一個(gè) User 類,包含 id 和 lastname 兩個(gè)屬性,而數(shù)據(jù)庫(kù)中這兩個(gè)字段的名字為 id 和 name。此時(shí)再執(zhí)行查詢時(shí)結(jié)果如下:lastname 這個(gè)字段直接為 null。

這時(shí)候我們就可以使用 resultMap 來(lái)解決這個(gè)問(wèn)題,resultMap 可以將數(shù)據(jù)庫(kù)中的字段映射到實(shí)體類上。column 代表數(shù)據(jù)庫(kù)中的字段名,properties 代表實(shí)體類中的字段名,通過(guò)映射之后 Mybatis 就可以找到對(duì)應(yīng)的字段。

<resultMap id="UserMap" type="User">
    <!--column代表數(shù)據(jù)庫(kù)中的字段名,properties代表實(shí)體類中的字段名-->
    <result column="id" property="id"/>
    <result column="name" property="lastname"/>
</resultMap>
<select id="getUserById" resultMap="UserMap" parameterType="int">
  select * from user where id=#{id};
</select>

準(zhǔn)備數(shù)據(jù)

接下來(lái)結(jié)合學(xué)生與教室的案例模擬復(fù)雜場(chǎng)景:

//創(chuàng)建教室表
create table classroom
(
id int not null AUTO_INCREMENT,
classname VARCHAR(40) not null,
PRIMARY KEY (id)
);
//創(chuàng)建學(xué)生表
create table student
(
id int not null AUTO_INCREMENT,
name VARCHAR(40) not null,
classid int not null,
PRIMARY KEY (id),
FOREIGN key (classid) REFERENCES classroom(id)
);
//創(chuàng)建一些數(shù)據(jù)
insert into classroom VALUES (1,'101班');
insert into classroom VALUES (2,'102班');
insert into student VALUES(1,'Amy',1);
insert into student VALUES(2,'Bob',1);
insert into student VALUES(3,'javayz',1);

多對(duì)一查詢(association)

現(xiàn)在要實(shí)現(xiàn)一個(gè)多對(duì)一的查詢需求,查詢所有的學(xué)生,并將每個(gè)學(xué)生所在的教室包含在內(nèi)。由于現(xiàn)在的情況是多學(xué)生和教室的關(guān)系是多對(duì)一,因此在構(gòu)建實(shí)體類時(shí)在 Student 類上要加上 ClassRoom 變量。

在 Java 的實(shí)體類代碼中分別建立 Student 和 ClassRoom 的類:

package com.cn.pojo;
public class ClassRoom {
    private int id;
    private String classname;
    public ClassRoom(){}
    public int getId() {
        return id;
    }
    public String getClassname() {
        return classname;
    }
    public void setId(int id) {
        this.id = id;
    }
    public void setClassname(String classname) {
        this.classname = classname;
    }
    @Override
    public String toString() {
        return "ClassRoom{" +
                "id=" + id +
                ", classname='" + classname + '\'' +
                '}';
    }
}
package com.cn.pojo;
public class Student {
    private int id;
    private String name;
    private ClassRoom classRoom;
    public Student(){}
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public ClassRoom getClassRoom() {
        return classRoom;
    }
    public void setId(int id) {
        this.id = id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", classRoom=" + classRoom +
                '}';
    }
}

定義一個(gè) StudentMapper 接口:

package com.cn.mapper;
import java.util.List;
import com.cn.pojo.Student;
public interface StudentMapper {
    List<Student> selectAllStudent();
}

編寫 StudentMapper.xml

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cn.mapper.StudentMapper">
    <select id="selectAllStudent" resultMap="StudentAndClassRoom">
        select s.id sid,s.name sname,c.id cid,c.classname cname
        from student s,classroom c
        where s.classid=c.id
    </select>
    <resultMap id="StudentAndClassRoom" type="com.cn.pojo.Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="classRoom" javaType="com.cn.pojo.ClassRoom">
            <result property="id" column="cid"/>
            <result property="classname" column="cname"/>
        </association>
    </resultMap>
</mapper>

上面的這種 sql 編寫模式稱為結(jié)果嵌套查詢,首先通過(guò)一段 sql 查詢語(yǔ)句將需要的信息查詢出來(lái),接著通過(guò) resultMap 對(duì)結(jié)果進(jìn)行拼接。這里使用 association 將 classRoom 的信息拼接到了 classRoom 類中,實(shí)現(xiàn)多對(duì)一查詢。

別忘了在配置類里把 mapper 映射加上,編寫測(cè)試類:

public class StudentMapperTest {
    public static void main(String[] args) {
        // 獲取SqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = mapper.selectAllStudent();
        System.out.println(students);
    }
}

一對(duì)多查詢(collection)

一個(gè)教室里有多個(gè)學(xué)生,如果想要查詢每個(gè)教室中的所有學(xué)生,就會(huì)用到一對(duì)多查詢。

修改兩個(gè)實(shí)體類,命名為 Student2 和 ClassRoom2,因?yàn)橐粋€(gè)教室中有多個(gè)學(xué)生,因此在教室類中通過(guò) List<Student2> 的方式引入 Student2 類

public class Student2 {
    private int id;
    private String name;
    private int classId;
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", classId=" + classId +
                '}';
    }
}
import java.util.List;
public class ClassRoom2 {
    private int id;
    private String classname;
    private List<Student2> students;
    @Override
    public String toString() {
        return "ClassRoom{" +
                "id=" + id +
                ", classname='" + classname + '\'' +
                ", students=" + students +
                '}';
    }
}

接著編寫 Mapper 接口和對(duì)應(yīng)的 Mapper.xml

import java.util.List;
import com.cn.pojo.ClassRoom2;
public interface ClassRoomMapper {
    List<ClassRoom2> getClassRoomByid( int id);
}
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cn.mapper.ClassRoomMapper">
    <select id="getClassRoomByid" resultMap="ClassRoomAndStudent" parameterType="int">
        select c.id cid,c.classname cname,s.id sid,s.name sname,s.classid classid
        from student s,classroom c
        where s.classid=c.id and c.id=#{id}
    </select>
    <resultMap id="ClassRoomAndStudent" type="com.cn.pojo.ClassRoom2">
        <result property="id" column="cid"/>
        <result property="classname" column="cname"/>
        <!--對(duì)于集合屬性,需要使用collection來(lái)實(shí)現(xiàn)-->
        <collection property="students" ofType="com.cn.pojo.Student2">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="classId" column="classid"/>
        </collection>
    </resultMap>
</mapper>

依舊是通過(guò)結(jié)果嵌套查詢的方式,通過(guò) sql 語(yǔ)句查詢出結(jié)果,再通過(guò) resultMap 進(jìn)行組裝,一對(duì)多查詢用的是 collection。

在配置文件中增加 mapper 映射器之后,編寫一個(gè)測(cè)試類:

public class TeacherMapperTest {
    public static void main(String[] args) {
        // 獲取SqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        ClassRoomMapper mapper = sqlSession.getMapper(ClassRoomMapper.class);
        List<ClassRoom2> classRoom = mapper.getClassRoomByid(1);
        System.out.println(classRoom);
    }
}

總結(jié)成一點(diǎn):對(duì)象的關(guān)聯(lián)(多對(duì)一)使用 association,集合的關(guān)聯(lián)(一對(duì)多)使用 collection。

懶加載

在上面的兩個(gè)例子中,一次 sql 查詢就將兩個(gè)表的數(shù)據(jù)一次性查詢了出來(lái),這種方式就是即時(shí)加載。但是在某些業(yè)務(wù)場(chǎng)景下,可能只需要學(xué)生的信息或者教室的信息,而不需要兩者的聯(lián)表數(shù)據(jù),這種時(shí)候就可以使用懶加載。

以上邊的 association 案例解釋懶加載的實(shí)現(xiàn)。

上邊的例子中,通過(guò)聯(lián)表查詢一次性就查詢出了學(xué)生信息和教室信息:

select s.id sid,s.name sname,c.id cid,c.classname cname
from student s,classroom c
where s.classid=c.id

如果想要通過(guò)懶加載實(shí)現(xiàn),就需要把 sql 語(yǔ)句轉(zhuǎn)換為:

select * from student;
select * from classroom where id = #{classid}

按照這個(gè)思路,建立 StudentLazyMapper 類:

package com.cn.mapper;
import java.util.List;
import com.cn.pojo.Student;
public interface StudentLazyMapper {
    List<Student> selectAllStudent();
}

創(chuàng)建對(duì)應(yīng)的 StudentLazyMapper.xml 文件,將原先的一條 sql 轉(zhuǎn)換為兩條 sql:

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cn.mapper.StudentLazyMapper">
    <select id="selectAllStudent" resultMap="studentAndClassRoom">
        select * from student
    </select>
    <resultMap id="studentAndClassRoom" type="com.cn.pojo.Student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="classRoom" javaType="com.cn.pojo.ClassRoom" column="classid" select="selectClassRoomById">
            <result property="id" column="id"/>
            <result property="classname" column="classname"/>
        </association>
    </resultMap>
    <select id="selectClassRoomById" resultType="com.cn.pojo.ClassRoom">
        select * from classroom where id = #{classid}
    </select>
</mapper>

在 mybatis-config.xml 中增加 mapper 映射,為了更好地看到懶加載效果,開(kāi)啟控制臺(tái)日志輸出,完整 xml 如下:

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
    <!--每個(gè)mapper.xml都需要在mybatis配置文件中進(jìn)行配置-->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
        <mapper resource="mapper/StudentMapper.xml"/>
        <mapper resource="mapper/StudentLazyMapper.xml"/>
    </mappers>
</configuration>

新建一個(gè)測(cè)試類 StudentMapperLazyTest:

public class StudentMapperLazyTest {
    public static void main(String[] args) {
        // 獲取SqlSession
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentLazyMapper mapper = sqlSession.getMapper(StudentLazyMapper.class);
    List<Student> students = mapper.selectAllStudent();
    System.out.println(students.get(0).getId());
    }
}

這個(gè)時(shí)候是還沒(méi)開(kāi)啟懶加載的,從運(yùn)行結(jié)果可以看出,雖然代碼中只需要得到 student 的 id,但是卻查詢了兩張表:

在配置文件的 setting 節(jié)點(diǎn)下開(kāi)啟懶加載的配置:

<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>

再次運(yùn)行測(cè)試代碼:

可以看到,只有 student 一張表被查詢,實(shí)現(xiàn)了懶加載

到此這篇關(guān)于MyBatis復(fù)雜Sql查詢實(shí)現(xiàn)示例介紹的文章就介紹到這了,更多相關(guān)MyBatis Sql查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • Java實(shí)戰(zhàn)之自助進(jìn)行多張圖片合成拼接

    Java實(shí)戰(zhàn)之自助進(jìn)行多張圖片合成拼接

    在當(dāng)今數(shù)字化時(shí)代,圖像處理技術(shù)在各個(gè)領(lǐng)域都發(fā)揮著至關(guān)重要的作用,本文為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)多張圖片合成拼接,需要的可以了解下
    2025-02-02
  • SpringCloud-Hystrix-Dashboard客戶端服務(wù)監(jiān)控的實(shí)現(xiàn)方法

    SpringCloud-Hystrix-Dashboard客戶端服務(wù)監(jiān)控的實(shí)現(xiàn)方法

    這篇文章主要介紹了SpringCloud-Hystrix-Dashboard客戶端服務(wù)監(jiān)控的實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 詳解Spring的StringUtils踩坑記錄

    詳解Spring的StringUtils踩坑記錄

    這篇文章主要介紹了詳解Spring的StringUtils踩坑記錄,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • SpringMvc定制化深入探究原理

    SpringMvc定制化深入探究原理

    SpringMVC是一種基于Java,實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式,請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦,這篇文章主要介紹了SpringMvc定制化原理
    2022-10-10
  • SpringBoot3整合pageHelper實(shí)現(xiàn)分頁(yè)功能

    SpringBoot3整合pageHelper實(shí)現(xiàn)分頁(yè)功能

    PageHelper是一個(gè)開(kāi)源的Java分頁(yè)插件,它提供了方便的分頁(yè)查詢功能,適用于大多數(shù)基于Java的持久層框架(如MyBatis、Hibernate等),本文給大家介紹了springboot3整合pageHelper實(shí)現(xiàn)分頁(yè)功能的方法,需要的朋友可以參考下
    2024-08-08
  • Java 關(guān)系運(yùn)算符詳情及案例(下)

    Java 關(guān)系運(yùn)算符詳情及案例(下)

    這篇文章主要介紹了Java 關(guān)系運(yùn)算符詳情及案例的實(shí)現(xiàn),主要續(xù)上篇文章,上一篇文章我們講到“等于”運(yùn)算符 (==)、“不等于”運(yùn)算符(!=)、“大于”運(yùn)算符(>) ,這篇文章繼續(xù)給大家講解相關(guān)知識(shí),需要的朋友可以參考一下
    2021-12-12
  • Java如何跳過(guò)https的ssl證書驗(yàn)證詳解

    Java如何跳過(guò)https的ssl證書驗(yàn)證詳解

    這篇文章主要介紹了Java跳過(guò)https的ssl證書驗(yàn)證的解決思路,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面我們來(lái)深入學(xué)習(xí)下吧
    2019-06-06
  • Java基礎(chǔ)篇之HashMap指定初始值

    Java基礎(chǔ)篇之HashMap指定初始值

    這篇文章主要給大家介紹了關(guān)于Java基礎(chǔ)篇之HashMap指定初始值的相關(guān)資料,HashMap是Java中常用的數(shù)據(jù)結(jié)構(gòu),它提供了高效的鍵值對(duì)存儲(chǔ)和查詢功能,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • JavaFX實(shí)現(xiàn)拖拽結(jié)點(diǎn)效果

    JavaFX實(shí)現(xiàn)拖拽結(jié)點(diǎn)效果

    這篇文章主要為大家詳細(xì)介紹了JavaFX實(shí)現(xiàn)拖拽結(jié)點(diǎn)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Java CAS操作與Unsafe類詳解

    Java CAS操作與Unsafe類詳解

    這篇文章主要介紹了Java CAS操作與Unsafe類的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-02-02

最新評(píng)論

株洲县| 陈巴尔虎旗| 合山市| 曲麻莱县| 清远市| 高要市| 定边县| 石柱| 澄迈县| 明星| 新安县| 余庆县| 辉南县| 临武县| 蕉岭县| 金塔县| 渑池县| 武穴市| 西安市| 东宁县| 古蔺县| 奎屯市| 镶黄旗| 壶关县| 阿图什市| 昭苏县| 勐海县| 阿克苏市| 晋中市| 沙雅县| 伽师县| 巴塘县| 宁都县| 太和县| 海伦市| 平顺县| 县级市| 康马县| 太和县| 仁布县| 包头市|