1. 程式人生 > >java的orm框架 mybatis 多對多 一對多關係的關聯對映和查詢--簡單易懂,理解才是王道

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多表聯查
上面是具體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、介面呼叫,和業務呼叫測試