Mybatis中多对多映射详解

时间:2023-01-29 15:52:44

Mybatis中多对多映射详解


Mybatis中一对一映射详解 

Mybatis中一对多映射详解

     对于在mybatis中的多对多的处理,其实我们可以参照一对多来解决

        【注意】在这个例子中有三个字段都是一样的:id,这种情况一定要小心,要给列起别名的(上面的一对一和一对多中如果出现这种情况也是一样的处理方式)
1、建表语句:
        drop table student_course;
        drop table course;
        drop table student;
        如果需要可以使用 cascade constraints; 
        create table course (id number primary key,course_code varchar2(30) not null,course_name varchar2(30) not null);
        create table student (id number primary key,name varchar2(10) not null,gender varchar2(10) ,major varchar2(10) ,grade varchar2(10));
        create table student_course (id number primary key,student_id number references student(id),course_id number references course(id));        

2、pojo类:  

Course类实现    

package com.mybatis.pojo;
import java.util.List;
public class Course {
private Integer id;
private String courseCode; // 课程编号
private String courseName;// 课程名称
private List<Student> students;// 选课学生
// get/set
public Course() {}
public Course(Integer id, String courseCode, String courseName) {
super();
this.id = id;
this.courseCode = courseCode;
this.courseName = courseName;
}
public Course(Integer id, String courseCode, String courseName,
List<Student> students) {
this.id = id;
this.courseCode = courseCode;
this.courseName = courseName;
this.students = students;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCourseCode() {
return courseCode;
}
public void setCourseCode(String courseCode) {
this.courseCode = courseCode;
}
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Course [id=" + id + ", courseCode=" + courseCode
+ ", courseName=" + courseName + ", students=" + students
+ "]";
}
}
Student类实现:
package com.mybatis.pojo;
import java.util.List;
public class Student {
private Integer id;
private String name; // 姓名
private String gender; // 性别
private String major; // 专业
private String grade; // 年级
private List<Course> courses;// 所选的课程
public Student(Integer id, String name, String gender,String major, String grade, List<Course> courses) {
super();
this.id = id;
this.name = name;
this.gender = gender;
this.major = major;
this.grade = grade;
this.courses = courses;
}
public Student(Integer id, String name, String gender, String major,
String grade) {
super();
this.id = id;
this.name = name;
this.gender = gender;
this.major = major;
this.grade = grade;
}
public Student() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public List<Course> getCourses() {
return courses;
}
public void setCourses(List<Course> courses) {
this.courses = courses;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", gender="
+ gender + ", major=" + major + ", grade=" + grade
+ ", courses=" + courses + "]";
}

}
       在设置完上面的操作之后,我们进行配置mybatis-config.xml文件注册基本信息       
<?xml version="1.0" encoding="UTF-8"?> <!-- 进行dtd约束,其中-//mybatis.org//DTD Config 3.0//EN为公共约束, http://mybatis.org/dtd/mybatis-3-config.dtd为获取网络中提供的dtd约束 --><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"              "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <typeAliases>    <!-- 给pojo类起别名 -->        <typeAlias type="com.mybatis.pojo.Student" alias="Student" />        <typeAlias type="com.mybatis.pojo.Course" alias="Course" />    </typeAliases>    <!-- 配置数据库环境其中development为默认的数据库名称事务管理器transactionManager类型为JDBC类型,数据源dataSource使用连接池的方式 -->    <environments default="development">        <environment id="development">            <transactionManager type="JDBC"></transactionManager>            <dataSource type="POOLED">            <!-- 配置数据库信息这里使用oracle数据库 -->                <property name="driver" value="oracle.jdbc.driver.OracleDriver" />                <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl" />                <property name="username" value="briup" />                <property name="password" value="briup" />            </dataSource>        </environment>    </environments>    <!-- 配置xml文件映射路径,在这里可以进行sql的操作 -->    <mappers>        <mapper resource="com/mybatis/mappers/Many2ManyMapper.xml" />    </mappers></configuration>
配置Many2ManyMapper接口:       
package com.mybatis.mappers;
import java.util.List;
import com.mybatis.pojo.Course;
import com.mybatis.pojo.Student;
public interface Many2ManyMapper {
//插入student数据
public void insertStudent(Student student);
//插入course数据
public void insertCourse(Course course);
//通过id查询学生
public Student selectStudentById(Integer id);
//通过id查询课程
public Course selectCourseById(Integer id);
//学生x选课y
public void studentSelectCourse(Integer id,Student student, Course course);
//查询比指定id值小的学生信息
public List<Student> getStudentByIdOnCondition(Integer id);
//查询student级联查询出所选的course并且组装成完整的对象
public Student getStudentByIdWithCourses(Integer id);
}
配置Many2ManyMapper.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"><!-- com.mybatis.mappers.StudentMapper是我们定义接口的全限定名字 这样就可以使用接口调用映射的SQL语句了 这个名字一定要和接口对应上 --><mapper namespace="com.mybatis.mappers.Many2ManyMapper">	<insert id="insertStudent" parameterType="Student">	   insert into student values(#{id},#{name},#{gender},#{major},#{grade})	</insert>	<insert id="insertCourse" parameterType="Course">	   insert into course values(#{id},#{courseCode},#{courseName})	</insert>	<select id="selectStudentById" parameterType="int" resultType="Student">		select * from student where id=#{id}	</select>	<select id="selectCourseById" parameterType="int" resultType="Course">		select id,course_code as courseCode,course_name  courseName from course where id=#{id}	</select>	<insert id="studentSelectCourse">        <!-- param1代表方法中第一个参数 以此类推 -->            insert into                student_course(id,student_id,course_id)            values                (#{param1},#{param2.id},#{param3.id})	</insert>      <!-- 如果有特殊符号的话 需要用 <![CDATA[ 特殊符号 ]]>  例如 < & 等等 -->        <select id="getStudentByIdOnCondition" parameterType="int" resultType="Student">             <![CDATA[             select *             from student             where id <  #{id}             ]]>        </select>     <!--  这里使用了嵌套结果ResultMap的方式进行级联查询,当然也可以使用嵌套查询select -->     <!-- 映射一个基本的Student查询结果 -->        <resultMap id="StudentResult" type="Student">            <id property="id" column="id"/>            <result property="name" column="name"/>            <result property="gender" column="gender"/>            <result property="major" column="major"/>            <result property="grade" column="grade"/>        </resultMap>        <!-- 继承上面那个基本的映射,再扩展出级联查询 -->        <resultMap id="StudentResultWithCourses" type="Student" extends="StudentResult">            <collection property="courses" resultMap="CourseResult"></collection>        </resultMap>        <!-- 这里特别要是的是column="cid" 这是和select语句中的 c.id as cid对应的 一定一定一定要对应起来 -->        <resultMap id="CourseResult" type="Course">            <id property="id" column="cid"/>            <result property="courseCode" column="course_code"/>            <result property="courseName" column="course_name"/>        </resultMap>        <!--              注意:查询语句的中的c.id as cid这个地方,避免名字相同出现查询结果不正确的情况            同时在id="CourseResult"的resultMap中也有与这里对应的设置要特别特别注意        -->        <select id="getStudentByIdWithCourses" parameterType="int" resultMap="StudentResultWithCourses">            select s.id,s.name,s.gender,s.major,s.grade,c.id as cid,c.course_code,c.course_name,sc.id,sc.student_id,sc.course_id            from student s,course c,student_course sc            where              s.id=#{id}            and            s.id=sc.student_id              and              sc.course_id=c.id        </select></mapper>
        测试代码:
package com.mybatis.test;import java.util.List;import org.apache.ibatis.session.SqlSession;import org.junit.Test;import com.mybatis.mappers.Many2ManyMapper;import com.mybatis.pojo.Course;import com.mybatis.pojo.Student;import com.mybatis.utils.MyBatisSqlSessionFactory;public class Many2ManyMapperTest {		@Test	public void test_insertStudent()	{		SqlSession session=null;		session = MyBatisSqlSessionFactory.openSession();//使用封装之后的类		// 使用sqlsession获得映射接口的实现类对象,接口的引用指向实现类的对象		Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);		Student student=new Student(1,"Suwu150","男","计算机","21");	    mapper.insertStudent(student);	    session.commit();		System.out.println("执行完毕");	}	@Test	public void test_insertCourse()	{		SqlSession session=null;		session = MyBatisSqlSessionFactory.openSession();//使用封装之后的类		// 使用sqlsession获得映射接口的实现类对象,接口的引用指向实现类的对象		Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);		mapper.insertCourse(new Course(1,"001","corejava"));		mapper.insertCourse(new Course(2,"002","oracle"));	    session.commit();		System.out.println("执行完毕");	}	@Test	public void test_selectStudentById()	{		SqlSession session=null;		session = MyBatisSqlSessionFactory.openSession();//使用封装之后的类		// 使用sqlsession获得映射接口的实现类对象,接口的引用指向实现类的对象		Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);		Student student = mapper.selectStudentById(2);		System.out.println(student);		System.out.println("执行完毕");	}	@Test	public void test_selectCourseById()	{		SqlSession session=null;		session = MyBatisSqlSessionFactory.openSession();//使用封装之后的类		// 使用sqlsession获得映射接口的实现类对象,接口的引用指向实现类的对象		Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);		Course course = mapper.selectCourseById(2);		System.out.println(course);		System.out.println("执行完毕");	}	@Test	public void test_studentSelectCourse()	{		SqlSession session=null;		session = MyBatisSqlSessionFactory.openSession();//使用封装之后的类		// 使用sqlsession获得映射接口的实现类对象,接口的引用指向实现类的对象		Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);		Student student=new Student();		Course course=new Course();		student.setId(2);		course.setId(1);		mapper.studentSelectCourse(5, student, course);		session.commit();	}	@Test	public void test_getStudentByIdOnCondition()	{		SqlSession session=null;		session = MyBatisSqlSessionFactory.openSession();//使用封装之后的类		// 使用sqlsession获得映射接口的实现类对象,接口的引用指向实现类的对象		Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);		List<Student> list = mapper.getStudentByIdOnCondition(3);		System.out.println(list);	}	@Test	public void test_getStudentByIdWithCourses()	{		SqlSession session=null;		session = MyBatisSqlSessionFactory.openSession();//使用封装之后的类		// 使用sqlsession获得映射接口的实现类对象,接口的引用指向实现类的对象		Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);		Student student = mapper.getStudentByIdWithCourses(2);		System.out.println(student);	}}
  注:这是从student这边出发所做的一些操作,从course一边开始操作是一样的,因为俩者的关系是多对多(对称的).

      同时不论是一对一还是一对多还是多对多,都不能在mybatis中进行级联保存、更新、删除,我们需要使用sql语句控制每一步操作