java的orm框架 mybatis 多對多 一對多關係的關聯對映和查詢--簡單易懂,理解才是王道
mybatis作為輕量級orm框架,需要配置很多sql 語句,sql是比較好控制的,所以都比較喜歡,而一般其他的orm都要學一大堆各種古怪配置,概念,看完文件仍是不明所以。
mybatis的整個流程處理來看,主要有【三方面】
1、sql語句查詢後的結果集,簡單看做一個二維表格
2、mybatis的mapper.xml,配置對應的sql語句和查詢介面方法名id,java的mapper.java【介面】類 (完成orm, 資料庫–>mapper.xml【orm紐帶】—>mapper.java–>java業務程式碼)
3、java業務程式碼呼叫,呼叫mybatis通過反射生成的代理類 (【MapperProxyFactory】生成【MapperProxy】,具體代理類)。呼叫java的mapper.java介面方法,實現查詢和其他資料庫操作,還需要實體物件entity對應表模型,供介面方法呼叫返回時,資料填充到實體物件,然後返回。
【單表查詢】【自身表查詢】
單一表的查詢是最簡單的操作
//mapper.xml 片段
<select id="selectCourse" resultType="entity.Course">
select * from course where id = #{id}
</select>
//mapper.java 片段
public interface CourseMapper {
Course selectCourse(int id);
}
//業務.java 片段
CourseMapper mapper = session.getMapper(CourseMapper.class);
Course course = mapper.selectCourse(1 );
【一對多】兩表關聯【多對多】三表關聯,查詢,還有其他【各種複雜】的sql對映
理解了mybatis的處理過程,其實一對多和多對多都是一樣的,mybatis完成的只是把sql的查詢結果,一個【二維表格通過xml配置對映為java物件】,供我們java面向物件程式設計,mybatis就是完成這個過程的【封裝】
比如,多對多sql,
student表,
course課程表,
sc選課表(只存前兩表id)
表結構
student學生表 id name age stuNum學生號
sc 選課表 id stuNum courseNum
course 課程表 id name takeTime學時 courseNum課程號
SELECT
student.id stu_id,
student.name stu_name,
course.id course_id,
course.name course_name,
course.courseNum course_num
from
student INNER JOIN sc
on
student.stuNum = sc.stuNum
INNER JOIN course
on
sc.courseNum = course.courseNum
WHERE
course.courseNum = "c001"
上面是具體sql,(查詢每個課程的,選課學生)。然後是mybatis的處理
//CourseMapper.xml 一個select 一個對應的resultMap
<select id="getStu" resultMap="courseStu">
SELECT
student.id stu_id,
student.name stu_name,
course.id course_id,
course.name course_name,
course.courseNum course_num
from
student INNER JOIN sc
on
student.stuNum = sc.stuNum
INNER JOIN course
on
sc.courseNum = course.courseNum
WHERE
course.courseNum = #{courseNum}
</select>
<resultMap type="entity.Course" id="courseStu">
<id property="id" column="course_id" />
<result property="name" column="course_name" />
<result property="courseNum" column="course_num" />
<collection property="students" ofType="entity.Student">
<id property="id" column="stu_id" />
<result property="name" column="stu_name" />
</collection>
</resultMap>
//CourseMapper.java mapper.java介面類
public interface CourseMapper {
Course getStu(String courseNum);
}
//Course.java 實體類 對應表course
public class Course {
private int id;
private String name;
private int takeTime;
private String courseNum;
//students非表結構欄位,對應resutlMap的collection
private List<Student> students;
//... normal getter and setter
}
//Test.java 業務呼叫
Course course1 = mapper.getStu("c001");
System.out.println(course1.getStudents().get(0).getName());
上面程式碼比較多,可以下載“完整專案”看看。
【總結】
1、業務呼叫getStu()後,mybatis根據mapper.xml的sql查到結構後(上面的結果圖)
2、mybatis根據mapper.xml的配置(resultMap), 把sql的結果轉為一個Course實體物件 (注意屬性students,不是表結構),Course的students設為三個student物件 (student 是普通實體類,都是表結構的引數屬性)
3、mybatis 把上面的Course返回給getStu()的呼叫者
【多對多查詢需要做的】
1、設定例項類的List屬性值(Course)
2、配置mapper.xml的resultMap(property是實體類的屬性,column是sql結果集的欄位[執行sql後看看欄位名稱],collection配置List型別的屬性),定義sql結構集(欄位)與java實體類物件屬性的對映
3、介面呼叫,和業務呼叫測試