文章目錄
- 多表查詢
- 一對一
- 一對多
多表查詢
一對一
- 開啟代碼片段編寫
專注于 SQL的 編寫
- JDBC 的寫法,注重于 SQL
- mybatis 在 一對一查詢時,核心在于
- 建立每個表對應的實體類
- 主鍵根據 主鍵 id 進行查詢,副標根據 設定外鍵進行查詢 在 SQL編寫上簡單很多
- 通過注解,對映射結果進行處理,讓二者產生聯系,來實現多表查詢
- 學生詳情實體類
package com.yanyu.mybatis2.po;import lombok.Data;/*** @Author yanyu666_508200729@qq.com* @Date 2025/4/6 21:26* @description:student_detail 表的 字段映射實體類*/
@Data
public class StudentDetail {private Integer id;private Integer studentId;private String addr;
}
- 學生實體類
package com.yanyu.mybatis2.po;import lombok.Data;/*** @Author yanyu666_508200729@qq.com* @Date 2025/4/6 21:25* @description:student 表的 字段映射實體類*/
@Data
public class Student {private Integer id;private String name;private String stuid;private String major;
// 連接 學生詳情的字段StudentDetail studentDetail;}
- 接口設計
- 分別編寫查詢student student_detail 的操作,根據 各自的主鍵 id
- 處理映射結果集
package com.yanyu.mybatis2.mapper;import com.yanyu.mybatis2.po.Student;
import com.yanyu.mybatis2.po.StudentDetail;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;/*** @Author yanyu666_508200729@qq.com* @Date 2025/4/6 21:39* @description:多表查詢,一對一*/
public interface StudentOneToOne {
// 根據 id 主鍵 查詢 副標 學生詳情 結果自然就是 StudentDetail@Select("""select id,student_id,addr from student_detail where student_id=#{student_id}""")
// 進行副表的結果映射@Results({@Result(id = true,column = "id",property = "id"),@Result(column = "student_id",property = "studentId"),@Result(column = "addr",property = "addr")})StudentDetail selectStudentDetail(Integer student_id);//注意開啟駝峰(appllication.properties)
// 根據 主表的 主鍵 id 進行 查詢、@Select("""select id,name,stuid,major from student where id=#{id}""")
// 映射結果@Results({@Result(id = true,column = "id",property = "id"),@Result(column = "name",property = "name"),@Result(column = "stuid",property = "stuid"),@Result(column = "major",property = "stuid"),@Result(column = "id",property = "studentDetail",one = @One(select = "com.yanyu.mybatis2.mapper.StudentOneToOne.selectStudentDetail",fetchType = FetchType.LAZY))
// 將主表 student 的主鍵 id 作為 參數傳遞到 副表查詢 的 方法中,本質 : student.id = student_detail.student_id})Student selectStudent(Integer id);/** FetchType.LAZY 的作用
延遲加載(Lazy Loading):當設置為 FetchType.LAZY 時,關聯的實體或集合不會在主實體被加載時立即加載。相反,它們會在真正需要訪問這些關聯數據時才被加載。
* 這種策略可以減少數據庫查詢的次數,提高性能,尤其是在關聯數據量較大時。
按需加載:只有在訪問關聯屬性時,Hibernate 才會發起額外的數據庫查詢來加載這些數據。
對比 FetchType.EAGER
FetchType.EAGER:表示立即加載。當主實體被加載時,關聯的實體或集合也會被立即加載。這種策略適用于關聯數據量較小且經常需要一起使用的場景,但可能會導致性能問題
* ,尤其是在關聯數據量較大或關聯關系較復雜時。
FetchType.LAZY:表示延遲加載。只有在真正需要訪問關聯數據時才會加載,適用于關聯數據量較大或關聯關系較復雜的情況,可以有效減少不必要的數據庫查詢。* */
}
一對多
- 與一對一類似
- 主表根據 id 查,副表根據 student_id 查
- 副表映射的每個實體類都是一個對象,以集合形式出現在 主表的實體類中
package com.yanyu.mybatis2.po;/*** @Author yanyu666_508200729@qq.com* @Date 2025/4/6 22:32* @description:課程實體類*/
@Data
public class Course {private Integer id;private Integer studentId;private String name;
// 一個學生對應多個 課程,課程以集合形式出現在 學生類中}
package com.yanyu.mybatis2.po;import lombok.Data;import java.util.List;/*** @Author yanyu666_508200729@qq.com* @Date 2025/4/6 22:34* @description:學生與課程*/
@Data
public class StudentCourse {private Integer id;private String name;private String stuid;private String major;private List<Course> courses;
}
package com.yanyu.mybatis2.mapper;import com.yanyu.mybatis2.po.Course;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;import java.util.List;/*** @Author yanyu666_508200729@qq.com* @Date 2025/4/6 22:37* @description:*/
public interface StudentCourse {
// 根據 student_id 查課程 并 按 副表 主鍵 id 進行分組@Select("""select id,student_id,name from coursewhere student_id = #{student_id}order by id""")@Results(id = "studentCourse",value = {@Result(id = true, column = "id", property = "id"),@Result(column = "student_id", property = "studentId"),@Result(column = "name", property = "name")})List<Course> selectCourse(Integer student_id);
// 主表@Select("""select id,name,stuid,major from studentwhere id = #{id}""")@Results({@Result(id = true,column = "id",property = "id"),@Result(column = "name",property = "name"),@Result(column = "stuid",property = "stuid"),@Result(column = "major",property = "major"),@Result(column = "id",property = "courses",many = @Many(select = "com.yanyu.mybatis2.mapper.StudentCourse.selectCourse",fetchType = FetchType.LAZY))
// 將主表 student 的主鍵 id 作為 參數傳遞到 副表查詢 的 方法中,本質 : student.id = course.student_id})com.yanyu.mybatis2.po.StudentCourse selectStudentCourse(Integer id);}
- 調錯:看得懂就看(cause caused by),看不到,直接把錯誤復制,百度
- 注意接口名和實體類名一樣時,要特別留意 包名
小結:
- 各自查詢各自的,然后再利用 one = @one many = @Many 進行關聯