MyBatis的关联关系补充 多对多 继承
多对多 一个学生有多个课程 一个课程有多个学生
思路分析 :使用一个中间表 用学生表和课程表的主键作为中间表的联合主键
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()); } }