多對多 一個學生有多個課程 一個課程有多個學生
思路分析 :使用一個中間表 用學生表和課程表的主鍵作為中間表的聯合主鍵
1數據庫表的設計
課程表
學生表
中間表
2/實體類的設計
課程類
public class Course { private int cid; private String cname; private List<Student> students; public int getCid() { return cid; } public void setCid(int cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } public List<Student> getStudents() { return students; } public void setStudents(List<Student> students) { this.students = students; } @Override public String toString() { return "Course [cid=" + cid + ", cname=" + cname + "]"; } }
學生類
public class Student { private int sid; private String sname; private List<Course> courses; public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public List<Course> getCourses() { return courses; } public void setCourses(List<Course> courses) { this.courses = courses; } @Override public String toString() { return "Student [sid=" + sid + ", sname=" + sname + ", courses=" + courses + "]"; } }
3對應的mapper接口 和mapper.xml配置文件
1. API接口層:提供給外部使用的接口API,開發人員通過這些本地API來操縱數據庫。接口層一接收到調用請求就會調用數據處理層來完成具體的數據處理。
public interface StudentMapper { /** * 根據ID 查詢學生 * @param id * @return *方法名必須和配置文件中的方法名保持一致 */ public Student findStuById(int id); /** * 查詢學生時 把該學生所選的課程一並查出 * @param id * @return */ public Student findStuAndCou(int id); }
自定義返回結果集 雙向多對多有兩種映射方式
方式1:嵌套結果 使用嵌套結果映射來處理重復的聯合結果的子集 封裝聯表查詢的數據(去除重復的數據)
方式2:嵌套查詢 通過執行另外一個SQL映射語句來返回預期的復雜類型
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.szjx.mapper.StudentMapper"> <!-- 根據ID查詢學生 --> <select id="findStuById" parameterType="int" resultType="Student"> select * from student where sid=#{id} </select> <!-- 嵌套結果 根據ID查詢學生 並將學生所選課程一並查詢出 --> <select id="findStuAndCou" parameterType="int" resultMap="stuAndCou"> select s.* ,c.* from student s left outer join student_course sc on sc.sid=s.sid left outer join course c on sc.cid=c.cid where s.sid=#{id} </select> <!-- 自定義返回結果集 --> <resultMap type="Student" id="stuAndCou"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <!-- 實體類中的屬性值是一個集合 所以使用Collection --> <collection property="courses" ofType="Course"> <id property="cid" column="cid"/> <result property="cname" column="cname"/> </collection> </resultMap> </mapper>
public class Many2Many { private SqlSession sqlSession; private StudentMapper mapper; @Before public void before(){ //獲取session sqlSession=DBTools.getSession(); mapper=sqlSession.getMapper(StudentMapper.class); } @After public void after(){ //提交事務 sqlSession.commit(); } @Test //根據ID查詢一個學生 public void findStudentById(){ Student stu=mapper.findStuById(1); System.out.println(stu); } @Test //根據id查詢學生並查詢出學生所選課程 public void findStuAndCou(){ Student stu=mapper.findStuAndCou(1); System.out.println(stu); } }
繼承關系
這也是在網上學習剛看到的,應該屬於MyBatis動態Sql的范疇吧
最簡單的例子,寵物。
MyBatis有關繼承的映射示例
1數據庫表的設計
2.實體類的創建
父類 寵物類
public class PetBean implements Serializable{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
子類 貓類
public class CatBean extends PetBean{ private int fish; public int getFish() { return fish; } public void setFish(int fish) { this.fish = fish; } }
子類 狗類
public class DogBean extends PetBean{ private int bone; public int getBone() { return bone; } public void setBone(int bone) { this.bone = bone; } }
3 mapper接口 和mapper.xml配置文件
PetMapper
public interface PetMapper { //保存一只貓 public int saveCat(CatBean cat); //添加一直狗 public int saveDog(DogBean dog); //查詢所有的寵物 public List<PetBean> findAllPet(); //查詢所有的寵物貓 public List<CatBean> findAllCat(); }
PetMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.szjx.mapper.PetMapper"> <!-- 保存一直貓 --> <insert id="saveCat" parameterType="CatBean"> insert into pet(name,type,fish) values(#{name},'cat',#{fish}) </insert> <!-- 保存一只狗 --> <insert id="saveDog" parameterType="DogBean"> insert into pet(name,type,bone) values(#{name},'dog',#{bone}) </insert> <!-- 查詢所有動物 --> <select id="findAllPet" resultMap="petMap"> select * from pet </select> <!-- 查詢所有貓 --> <select id="findAllCat" resultMap="petMap"> select * from pet where type='cat' </select> <!-- 自定義返回結果集 --> <resultMap type="PetBean" id="petMap"> <id property="id" column="id"/> <result property="name" column="name"/> <!--discriminator:根據結果值決定使用哪個resultMap case:判斷條件 它的表現很像 Java 語言中的 switch 語句。 定義鑒別器指定了 column 和 javaType 屬性 --> <discriminator javaType="String" column="type"> <case value="cat" resultType="CatBean"> <result property="fish" column="fish" javaType="int"/> </case> <case value="dog" resultType="DogBean"> <result property="bone" column="bone" javaType="int"/> </case> </discriminator> </resultMap> </mapper>
4測試類
public class Extends { private SqlSession sqlSession; private PetMapper mapper; @Before public void before(){ //獲取session sqlSession=DBTools.getSession(); mapper=sqlSession.getMapper(PetMapper.class); } @After public void after(){ //提交事務 sqlSession.commit(); } @Test public void saveCat(){ //批量添加貓 for (int i = 0; i < 10; i++) { CatBean cat=new CatBean(); cat.setFish(1); cat.setName("加菲"+i); mapper.saveCat(cat); } } @Test public void saveDog(){ //批量添加狗 for (int i = 0; i <10; i++) { DogBean dog=new DogBean(); dog.setBone(2); dog.setName("哈士奇"+i); mapper.saveDog(dog); } } @Test public void findAllCat(){ //查詢所有的貓 List<CatBean> cList=mapper.findAllCat(); System.out.println(cList.size()); } @Test public void findAllPet(){ //查詢所有的寵物 List<PetBean> pList=mapper.findAllPet(); System.out.println(pList.size()); } }