mybatis-嵌套查詢模式設計|數據庫設計|

案例數據庫介紹

  • 最近學習了ssm框架,所以準備把之前用原生Servlet做的一個小項目,改成ssm框架形式。沒想到帶來了這麼多問題,但是解決後還是學到了很多東西,這是根據我自己的理解記錄的一篇白話博文。
  • 這個案例中,表與表之間的關係是很典型的稍微複雜一點點的多對多關係。一個選課系統
  • 我的數據庫設計是這樣的:學生選課時,選擇的其實選的是教師和課程綁定的關係。三個實體課程、學生、教師兩兩之間都是多對多關係。廢話不多說直接上圖,直接明瞭。
    在這裏插入圖片描述

未改進代碼

在沒有學習mybatis框架前,我們如果要查詢表與表的關係時多對多的情況時,只能採取連接查詢,這樣就是的我們的sql語句特別複雜,看起來很難受,而且在寫這種sql語句時,也是一種挑戰,尤其是當多對多關係複雜時,我的這個小案例就是這樣。
mybatis讓我們只關心sql語句,簡化了開發。尤其是他可以使用嵌套查詢,讓我們不用再去使用複雜的連接查詢語句,這樣其實不僅簡化了sql語句,而且也降低了耦合,讓sql語句有有了很多的調用機會。
沒有改進前
學生類、教師類和課程類

public class Student {
    private Integer sid;//學生編號
    private String snum;//學號
    private String sname;//學生姓名
    private String spassword;// 密碼
    private String syear;//年級
    private String smajor;//專業
    private String sdept;//院系

public class Course {
    private Integer cid;//課程代碼
    private String cname;//課程名
    private String ctype;//課程性質
    private Integer ccredit;//學分
    private Integer ctime;//學時
    
public class Teacher {
    private Integer tid;// 教師編號
    private String tnum;//教師號
    private String tname;//教師姓名
    private String tpassword;//密碼
    private String tdept;//院系
    
//get/set、toString方法省略

選課類(這是改進前分析的實體類截圖,改進後這個類就不存在了)
在這裏插入圖片描述
教師課程綁定關係類

public class TeacherAndCourse {
    private Integer tcid;//授課代碼
    private String tcplace;//上課地點
    private String tctime;//上課時間
    private String tcgrade;//學年

    private List<Teacher> teacherList;//授課教師
    private List<Course> courseList;//授課課程
    
	//get/set、toString方法省略

這是查詢學生選課情況的各個Dao之間的調用關係:
在這裏插入圖片描述
這樣是可以查出數據的,但是數據是有問題的。

  1. 由於實體類的設計,使得查出來的數據很難在頁面上顯示,因爲由上圖我們知道最終返回給頁面的是一個List< Curricula > ,Curricula中有List< TeacherAndCourse > 和List< Studnet > ,在TeacherAndCourse 類中還有List< Course >和List< Teacher > 。頁面真的很難去顯示這些數據。
  2. 由於這種Dao層的設計,讓嵌套查詢了多次,使得查到的數據冗餘重複。
    我這裏根據數據庫得到的是三條相同的數據,因爲已經改進,所以數據只有截圖,用不同顏色表示了三段數據,馬賽克是姓名。
    在這裏插入圖片描述

兩個成功的案例

發現問題後,我回顧了一下課程里老師寫過的兩個案例。讓我受益匪淺,開始按照這種方式做。

訂單案例

在這裏插入圖片描述

權限、角色、用戶案例

在這裏插入圖片描述

改進後的代碼

開始改進代碼。

實體類改進

刪除選課類Curricula ,
給Student類添加 private List teacherAndCourseList;屬性,
給Teacher類添加private List courseList;屬性
給Course類添加private List teacherList;屬性

public class Student {
    private Integer sid;//學生編號
    private String snum;//學號
    private String sname;//學生姓名
    private String spassword;// 密碼
    private String syear;//年級
    private String smajor;//專業
    private String sdept;//院系

    private List<TeacherAndCourse> teacherAndCourseList;
public class TeacherAndCourse {
    private Integer tcid;//授課代碼
    private String tcplace;//上課地點
    private String tctime;//上課時間
    private String tcgrade;//學年

    private List<Teacher> teacherList;//授課教師
    private List<Course> courseList;//授課課程


public class Teacher {
    private Integer tid;// 教師編號
    private String tnum;//教師號
    private String tname;//教師姓名
    private String tpassword;//密碼
    private String tdept;//院系

    private List<Course> courseList;

public class Course {
    private Integer cid;//課程代碼
    private String cname;//課程名
    private String ctype;//課程性質
    private Integer ccredit;//學分
    private Integer ctime;//學時

    private List<Teacher> teacherList;

Dao層改進

StudentDao#findBySid(String “學生id”):

/**
* 通過學號查詢選課記錄
*
* @return
*/
@Select("SELECT * FROM t_stu WHERE sid=#{sid}")
@Results({
       @Result(property = "oid",column = "oid"),
       @Result(property = "snum",column = "snum"),
       @Result(property = "sname",column = "sname"),
       @Result(property = "spassword",column = "spassword"),
       @Result(property = "syear",column = "syear"),
       @Result(property = "smajor",column = "smajor"),
       @Result(property = "sdept",column = "sdept"),

       @Result(property = "teacherAndCourseList",column = "sid",javaType = java.util.List.class,
               many = @Many(select = "com.bjwlxy.choosecourse.dao.TeacherAndCourseDao.findBySid",fetchType = FetchType.EAGER))
})
public Student findBySid(String sid);

TeacherAndCourseDao#findBySid(String “學生id”):
注意這裏的"select * from t_tc where tcid in (select tcid from t_option where sid=#{sid})",是通過sql去查tcid。

@Select("select * from t_tc where tcid in (select tcid from t_option where sid=#{sid})")
@Results({
        @Result(id = true,property = "tcid",column = "tcid"),
        @Result(property = "tcplace",column = "tcplace"),
        @Result(property = "tctime",column = "tctime"),
        @Result(property = "tcgrade",column = "tcgrade"),
        @Result(property = "teacherList",column = "tid",javaType = java.util.List.class,
                many = @Many(select = "com.bjwlxy.choosecourse.dao.TeacherDao.findById",fetchType = FetchType.EAGER)),
        @Result(property = "courseList",column = "cid",javaType = java.util.List.class,
                many = @Many(select = "com.bjwlxy.choosecourse.dao.CourseDao.findById",fetchType = FetchType.EAGER)),
})
public List<TeacherAndCourse> findBySid(Integer sid);

TeacherDao#findById(String “教師id”)

@Select("select * from t_teacher where tid=#{tid}")
public List<Teacher> findById(Integer tid);

CourseDao#findById(String “課程id”)

@Select("select * from t_course where cid=#{cid}")
public List<Course> findById(Integer cid);

這樣得到的數據是比較合理,也比較方便展示的。
在這裏插入圖片描述
分析一下數據:

  1. 現在由於domain層中的設計,得到的就是一個學生對象,而學生對象中包含了選課信息。這是比較合理的。
  2. Dao層的設計,使得方法重用性變高了,
Student{
  sid=null, snum='201796084111', sname='xxxx', spassword='123456', syear='2017', smajor='軟件工程', sdept='計算機學院',
   teacherAndCourseList=
       [TeacherAndCourse
           {tcid=1, tcplace='石鼓校區綜合樓605', tctime='週二4,5節,週四1,2節', tcgrade='2019-2020',
           teacherList=[Teacher{tid=2, tnum='1022', tname='xxxx', tpassword='123456', tdept='計算機學院',
           courseList=null}], courseList=[Course{cid=1, cname='計算機原理', ctype='專業核心課', ccredit=2, ctime=18, teacherList=null}]},
       TeacherAndCourse
           {tcid=2, tcplace='石鼓校區綜合樓605', tctime='週二4,5節,週五4,5節', tcgrade='2019-2020',
           teacherList=[Teacher{tid=1, tnum='1021', tname='xxxx', tpassword='123456', tdept='計算機學院',
           courseList=null}], courseList=[Course{cid=1, cname='計算機原理', ctype='專業核心課', ccredit=2, ctime=18, teacherList=null}]},
       TeacherAndCourse
           {tcid=3, tcplace='石鼓校區綜合樓605', tctime='週三5,6節,週四1,2節', tcgrade='2019-2020',
           teacherList=[Teacher{tid=1, tnum='1021', tname='xxxx', tpassword='123456', tdept='計算機學院',
           courseList=null}],courseList=[Course{cid=2, cname='java程序設計', ctype='專業核心課', ccredit=2, ctime=16, teacherList=null}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章