zoukankan      html  css  js  c++  java
  • Mybatis中使用collection进行多对多双向关联示例(含XML版与注解版)

    Mybatis中使用collection进行多对多双向关联示例(含XML版与注解版)

    XML版本:

    实体类:

    @Data
    @NoArgsConstructor
    public class Course {
        protected Integer id;
        protected String name;
        protected List<Student> students = new ArrayList<Student>();
    
        public Course(Integer id) {
            this.id = id;
        }
        
        public Course(String name) {
            this.name = name;
        }
    
        public String toLazyString() {
            return "Course:{id: " + this.id + "; name: " + this.name + "}";
        }
    
    }
    
    @Data
    @ToString
    @NoArgsConstructor
    public class Student {
        protected Integer id;
        protected String name;
        protected List<Course> courses = new ArrayList<Course>();
        
    
        public Student(Integer id) {
            this.id = id;
        }
    
        public Student(String name) {
            this.name = name;
        }
    
        public String toLazyString() {
            return "Student:{id: " + this.id + " ; name: " + this.name + "}";
        }
    }
    @Data
    @ToString
    @NoArgsConstructor
    public class StudentCourse {
        private Integer studentId;
        private Integer courseId;
        private Integer score;
    
        public StudentCourse(Integer studentId, Integer courseId) {
            this.studentId = studentId;
            this.courseId = courseId;
        }
    
        public StudentCourse(Integer score) {
            this.score = score;
        }
    }
    @Data
    @ToString
    public class StudentExt extends Student {
        private String courseName;
        private String courseScore;
    }

    Mapper接口:

    public interface CourseMapper {
        public Course selectById(Integer id);
    
        public int insertCourse(Course course);
    
        public int updateCourse(Course course);
    
        public int deleteCourse(Course course);
    }
    public interface StudentMapper {
        public Student selectById(Integer id);
        public int insertStudent(Student employee);
        public int updateStudent(Student employee);
        public int deleteStudent(Student employee);
        public List<Student> selectStudentByCourseAndScore(@Param("course") Course course,
                @Param("studentCourse") StudentCourse studentCourse);
    }
    public interface StudentCourseMapper {
        public int insertStudentCourse(@Param("student") Student student, @Param("course") Course course);
        public int deleteStudentCourse(@Param("student") Student student, @Param("course") Course course);
        public int deleteStudentCourseByStudent(@Param("student") Student student);
    }

    Mapper映射文件:

    <?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.sunwii.mybatis.mapper.CourseMapper">
        <resultMap type="Course" id="CourseMap_basic">
            <id property="id" column="cid" />
            <result property="name" column="name" />
        </resultMap>
        <resultMap type="Course" id="CourseMap" extends="CourseMap_basic">
             <!-- 多对多关联:使用select引用方式 -->
            <collection property="students" column="cid" ofType="Student" select="com.sunwii.mybatis.mapper.StudentMapper.selectByCourse" fetchType="lazy">
            </collection>
        </resultMap>
        
        <select id="selectById" parameterType="Integer"
            resultMap="CourseMap">
            select id as cid, name from t_course c where c.id=#{id}
        </select>
        
        
    
        <select id="selectByStudent" parameterType="Integer"
            resultMap="CourseMap_basic">
            select c.id as cid, c.name from t_course c inner join t_student_course sc 
            on c.id=sc.course_id and sc.student_id=#{studentId}
        </select>
    
        <insert id="insertCourse" parameterType="Course" keyColumn="id"
            keyProperty="id" useGeneratedKeys="true">
            insert into t_course(name)
            values(#{name})
        </insert>
    
    
        <update id="updateCourse" parameterType="Course">
            update t_course set
            name=#{name}
            where id=#{id}
        </update>
    
        <delete id="deleteCourse" parameterType="Course">
            delete from t_course
            where
            id=#{id}
        </delete>
    </mapper>
    <?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.sunwii.mybatis.mapper.StudentMapper">
        <resultMap type="Student" id="StudentMap_basic">
            <id property="id" column="sid" />
            <result property="name" column="name" />
        </resultMap>
        <resultMap type="StudentExt" id="StudentMap_basic_ext" extends="StudentMap_basic">
            <result property="courseName" column="cousename" />
            <result property="courseScore" column="coursescore" />
        </resultMap>
        <resultMap type="Student" id="StudentMap" extends="StudentMap_basic">
            <!-- 多对多关联:单向。方式四:使用select引用方式 -->
            <collection property="courses" column="sid"
                ofType="Course"
                select="com.sunwii.mybatis.mapper.CourseMapper.selectByStudent"
                fetchType="lazy" />
        </resultMap>
        <select id="selectById" parameterType="Integer"
            resultMap="StudentMap">
            select id as sid, name from t_student s where s.id=#{id}
        </select>
    
        <select id="selectByCourse" parameterType="Integer"
            resultMap="StudentMap_basic">
            select s.id as sid, s.name from t_student s inner join t_student_course sc 
            on s.id=sc.student_id and sc.course_id=#{courseId}
        </select>
        
        
        <select id="selectStudentByCourseAndScore"
            resultMap="StudentMap_basic_ext">
            select s.id as sid, s.name,c.name as cousename,sc.score as coursescore from t_student s 
            inner join t_student_course sc 
            on s.id=sc.student_id and sc.score>=#{studentCourse.score} 
            inner join t_course c on c.id=sc.course_id and c.name=#{course.name}
        </select>
    
        <insert id="insertStudent" parameterType="Student"
            keyColumn="id" keyProperty="id" useGeneratedKeys="true">
            insert into t_student(name) values(#{name})
        </insert>
    
    
        <update id="updateStudent" parameterType="Student">
            update t_student set name=#{name} where id=#{id}
        </update>
    
        <delete id="deleteStudent" parameterType="Student">
            delete from t_student where id=#{id}
        </delete>
    </mapper>
    <?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.sunwii.mybatis.mapper.StudentCourseMapper">
        <insert id="insertStudentCourse">
            insert into
            t_student_course(student_id,course_id)
            values(#{student.id},#{course.id})
        </insert>
    
    
        <delete id="deleteStudentCourse">
            delete from
            t_student_course where
            student_id=#{student.id} and course_id=#{course.id}
        </delete>
        
        
    
        <delete id="deleteStudentCourseByStudent">
            delete from
            t_student_course where
            student_id=#{student.id}
        </delete>
    </mapper>

    业务层实现类:

    @Service
    public class CourseServiceImpl implements CourseService {
        @Autowired
        private CourseMapper CourseMapper;
    
        @Override
        public Course getCourse(Integer id) {
            return CourseMapper.selectById(id);
        }
    
        @Override
        @Transactional
        public void insertCourse(Course course) {
            CourseMapper.insertCourse(course);
        }
    
        @Override
        @Transactional
        public void updateCourse(Course course) {
            CourseMapper.updateCourse(course);
        }
    
        @Override
        @Transactional
        public void deleteCourse(Course course) {
            CourseMapper.deleteCourse(course);
        }
    
    }
    @Service
    public class StudentServiceImpl implements StudentService {
        @Autowired
        private StudentMapper studentMapper;
        @Autowired
        private CourseMapper courseMapper;
        @Autowired
        private StudentCourseMapper studentCourseMapper;
    
        @Override
        public Student getStudent(Integer id) {
            return studentMapper.selectById(id);
        }
    
        @Override
        @Transactional
        public void insertStudent(Student student) {
            List<Course> courses = student.getCourses();
    
            // 如果需要的话,就先新增课程
            if (courses != null) {
                for (Course course : courses) {
                    if (course != null && course.getId() == null) {
                        courseMapper.insertCourse(course);
                    }
                }
            }
            studentMapper.insertStudent(student);
    
            // 添加选课表
            if (courses != null) {
                for (Course course : courses) {
                    if (course != null) {
                        studentCourseMapper.insertStudentCourse(student, course);
                    }
                }
            }
        }
    
        @Override
        @Transactional
        public void updateStudent(Student student) {
            List<Course> courses = student.getCourses();
    
            if (courses != null) {
                // 如果需要的话,就先新增课程
                for (Course course : courses) {
                    if (course != null && course.getId() == null) {
                        courseMapper.insertCourse(course);
                    }
                }
            }
    
            studentMapper.updateStudent(student);
    
            // 修改选课表
            if (courses != null) {
                //删除旧的选课表记录
                studentCourseMapper.deleteStudentCourseByStudent(student);
                
                for (Course course : courses) {
                    if (course != null) {
                        studentCourseMapper.insertStudentCourse(student, course);
                    }
                }
            }
        }
    
        @Override
        @Transactional
        public void deleteStudent(Student student) {
            studentMapper.deleteStudent(student);
            
            //删除选课表记录
            studentCourseMapper.deleteStudentCourseByStudent(student);
        }
        
        @Override
        public List<Student> getStudentByCourseAndScore(String courseName,Integer score) {
            return studentMapper.selectStudentByCourseAndScore(new Course(courseName), new StudentCourse(score));
        }
    
    }

    测试类:

    public class TestMany2Many {
        private ApplicationContext context = SpringUtil.getContext();
        private StudentService studentService = (StudentService) context.getBean(StudentService.class);
        private CourseService courseService = (CourseService) context.getBean(CourseService.class);
    
        /**
         * 插入学生信息(可以同时新增不存在的课程,同时进行选课)
         */
        @Test
        public void testStudentInsert() {
            // 多对多:添加。
            Student student = new Student();
            student.setName("sssss-1");
    
            // 级联新增的课程
            Course course = new Course("course-1");
    
            // 非新增的课程
            Course course2 = courseService.getCourse(2);
    
            student.getCourses().add(course2);
            student.getCourses().add(course);
    
            studentService.insertStudent(student);
        }
    
        /**
         * 新增学生信息(可以暂时没有选课)
         */
        @Test
        public void testEmployeeInsert2() {
            // 多对多:添加。
            Student student = new Student();
            student.setName("sssss-2");
    
            studentService.insertStudent(student);
        }
    
        /**
         * 查询学生信息(可以有延迟加载选课记录)
         */
        @Test
        public void testStudentSelect() {
            // 多对一:查询。
            int id = 1;
            Student student = studentService.getStudent(id);
    
            System.out.println(student.toLazyString());
            System.out.println(student);
        }
    
        /**
         * 更新学生信息(选课记录是否要更改、是否要删除和重新插入、是否要清空取决于程序)
         */
        @Test
        public void testStudentUpdate() { // 多对多:添加。
            int id = 4;
            Student student = studentService.getStudent(id);
            student.setName("sssss-444444444-2");
    
            // 级联新增的课程
            Course course = new Course("course-xx");
    
            // 非新增的课程
            Course course2 = courseService.getCourse(1);
    
            student.getCourses().add(course);
            student.getCourses().add(course2);
    
            // 设置0长度代表清空课程
            // student.setCourses(new ArrayList<Course>());
    
            // 设置为null代表不修改
            // student.setCourses(null);
    
            studentService.updateStudent(student);
        }
    
        /**
         * 删除学生信息(会把选课记录删除)
         */
        @Test
        public void testStudentDelete() {
            int id = 4;
            studentService.deleteStudent(new Student(id));
        }
    
        /**
         * 查询一门课程(以及学生信息)
         */
        @Test
        public void testCourseSelect() { // 多对多:查询
            int id = 1;
            Course course = courseService.getCourse(id);
            System.out.println(course.toLazyString());
            System.out.println(course);
        }
    
        /**
         * 查询“数学"成绩90分以上的学生
         */
        @Test
        public void testCourseWithScoreSelect() { // 多对多:查询
            int id = 1;
            String courseName = "数学";
            Integer score = 90;
    
            List<Student> students = studentService.getStudentByCourseAndScore(courseName, score);
    
            
            for (Student student : students) {
                System.out.print(student.toLazyString()+"-------");
                StudentExt studentExt = (StudentExt)student;
                System.out.println(studentExt.getCourseName()+":"+studentExt.getCourseScore());
                //System.out.println(courseName+":"+score);
            }
            
            //结果:
            //Student:{id: 1 ; name: 小红}-------数学:95
            //Student:{id: 3 ; name: 小青}-------数学:92
    
        }
    
    }

    注解版本:

    注解版本只是将Mapper映射文件去掉,将映射注解到Mapper接口中(如果需要则再添加动态sql提供器类),其它东西不变。

    Mapper接口(注解版):

    public interface CourseMapper {
        public static final String selectById = "select id as cid,name from t_course where id=#{id}";
        public static final String selectByStudent = ""
                + "select c.id as cid, c.name from t_course "
                + "c inner join t_student_course sc on "
                + "c.id=sc.course_id and sc.student_id=#{studentId}";
        public static final String insert = "insert into t_course(name) values(#{name})";
        public static final String update = "update t_course set name=#{name}";
        public static final String delete = "delete from t_course where id=#{id}";
        
        public static final String many2many = "com.sunwii.mybatis.mapper.StudentMapper.selectByCourse";
        
        @Select(selectById)
        @Results(id = "CourseMap", value = { @Result(property = "id", column = "cid"),
                @Result(property = "name", column = "name"),
                @Result(property = "students", column = "cid", 
                many = @Many(
                        select = many2many, 
                        fetchType = FetchType.LAZY)) 
        })
        public Course selectById(Integer id);
        
        @Select(selectByStudent)
        @Results(id = "CourseMap_basic", value = { 
                @Result(property = "id", column = "cid"),
                @Result(property = "name", column = "name")
        })
        public List<Course> selectByStudent(Student studentId);
    
        @Insert(insert)
        @Options(keyColumn = "id", keyProperty = "id", useGeneratedKeys = true)
        public int insertCourse(Course course);
    
        @Update(update)
        public int updateCourse(Course course);
    
        @Delete(delete)
        public int deleteCourse(Course course);
    }
    public interface StudentMapper {
        public static final String selectById = "select id as sid,name from t_student where id=#{id}";
        public static final String selectByCourse = ""
                +    "select s.id as sid, s.name from t_student s "
                +     " inner join t_student_course sc"
                +     " on s.id=sc.student_id and sc.course_id=#{courseId}";
        public static final String selectStudentByCourseAndScore = ""
                +    "select s.id as sid, s.name,c.name as cousename,sc.score as coursescore "
                +    "from t_student s  inner join t_student_course sc "
                +   "on s.id=sc.student_id and sc.score>=#{studentCourse.score} "
                +     "inner join t_course c on c.id=sc.course_id and c.name=#{course.name}";
        public static final String insert = "insert into t_student(name) values(#{name})";
        public static final String update = "update t_student set name=#{name} where id=#{id}";
        public static final String delete = "delete from t_student where id=#{id}";
        
        public static final String many2many = "com.sunwii.mybatis.mapper.CourseMapper.selectByStudent";
        
        
        
        @Select(selectById)
        @Results(id="StudentMap",value= {
                @Result(property = "id", column = "sid"),
                @Result(property = "name", column = "name"),
                @Result(property = "courses",column = "sid",
                many=@Many(
                        select = many2many,
                        fetchType = FetchType.LAZY
                ))
        })
        public Student selectById(Integer id);
    
        @Insert(insert)
        @Options(keyColumn = "id", keyProperty = "id", useGeneratedKeys = true)
        public int insertStudent(Student employee);
    
        @Update(update)
        public int updateStudent(Student employee);
    
        @Delete(delete)
        public int deleteStudent(Student employee);
    
        @Select(selectByCourse)
        @Results(id="StudentMap_basic", value = {
                @Result(property = "id", column = "sid"),
                @Result(property = "name", column = "name")
        })
        public List<Student> selectByCourse(Integer courseId);
        
        @Select(selectStudentByCourseAndScore)
        @Results(id="StudentMap_basic_ext", value = {
                @Result(property = "id", column = "sid"),
                @Result(property = "name", column = "name"),
        })
        public List<Student> selectStudentByCourseAndScore(@Param("course") Course course,
                @Param("studentCourse") StudentCourse studentCourse);
        
    }
    public interface StudentCourseMapper {
        public static final String insert="insert into t_student_course(student_id,course_id) values(#{student.id},#{course.id})";
        public static final String delete="delete from t_student_course where student_id=#{student.id} and course_id=#{course_id}";
        public static final String deleteByStudent="delete from t_student_course where student_id=#{student.id}";
        
        @Insert(insert)
        public int insertStudentCourse(@Param("student") Student student, @Param("course") Course course);
    
        @Delete(delete)
        public int deleteStudentCourse(@Param("student") Student student, @Param("course") Course course);
    
        @Delete(deleteByStudent)
        public int deleteStudentCourseByStudent(@Param("student") Student student);
    }

    由于注解版在定义resultMap(即@Results)时无法使用type属性定义返回的封装类型,所以测试类需要修改一点:

    /**
         * 查询“数学"成绩90分以上的学生
         */
        @Test
        public void testCourseWithScoreSelect() {
            int id = 1;
            String courseName = "数学";
            Integer score = 90;
    
            List<Student> students = studentService.getStudentByCourseAndScore(courseName, score);
    
            
            for (Student student : students) {
                System.out.print(student.toLazyString()+"-------");
                //注解版无法使用resultMap的type属性,不能直接转化
                //StudentExt studentExt = (StudentExt)student;
                //System.out.println(studentExt.getCourseName()+":"+studentExt.getCourseScore());
                System.out.println(courseName+":"+score);
            }
            
            //结果:
            //Student:{id: 1 ; name: 小红}-------数学:95
            //Student:{id: 3 ; name: 小青}-------数学:92
    
        }
  • 相关阅读:
    闭包的一个经典例子
    手机归属地查询API
    安卓模拟器导入通讯录
    使用RazorGenerator实现项目模块分离
    .met mvc 一种判断是否已登录的方式
    stl 空间配置器理解
    STL 生成全排列
    KMP算法理解
    解决八皇后问题,递归与非递归方式两种
    获取第K大的数
  • 原文地址:https://www.cnblogs.com/dreamyoung/p/11804936.html
Copyright © 2011-2022 走看看