9、Spring Data JPA 之 表与表关系建立(多对多)

多对多

有两个实体类,Teacher 和 Student,它们之间存在多对多的关系

实体类

Student

@Entity
@Table(name = "t_student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "student_id")
    private Integer studentId;
    @Column(name = "s_name")
    private String name;
    @Column(name = "s_gender")
    private String gender;

    /**
     *  mappedBy 对方配置映射关系的属性名称
     */
    @ManyToMany(mappedBy = "students", cascade = CascadeType.ALL)
    private List<Teacher> teachers = new ArrayList<>();

    public List<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(List<Teacher> teachers) {
        this.teachers = teachers;
    }

    public Integer getStudentId() {
        return studentId;
    }

    public void setStudentId(Integer studentId) {
        this.studentId = studentId;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "studentId=" + studentId +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

Teacher

@Entity
@Table(name="t_teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "emp_id")
    private Integer empId;
    @Column(name = "t_name")
    private String name;

    @ManyToMany(targetEntity = Student.class, cascade = CascadeType.ALL)
    @JoinTable(name = "tb_teacher_student",
            //joinColumns,当前对象在中间表中的外键
            joinColumns = {@JoinColumn(name = "tb_teacher_id", referencedColumnName = "emp_id")},
            //inverseJoinColumns 对方对象在中间表的外键
            inverseJoinColumns = {@JoinColumn(name = "tb_student_id", referencedColumnName = "student_id")}
    )
    private List<Student> students = new ArrayList<>();

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "empId=" + empId +
                ", name='" + name + '\'' +
                '}';
    }
}

接口

StudentDao

/**
 * 符合Spring Data Jpa 的 dao层接口规范
 *      JpaRepository<操作的实体类类型,实体类中主键属性的类型>
 *          #封装了基本CRUD操作
 *      JpaSpecificationExecutor <操作的实体类类型>
 *          #封装了复杂查询(分页)
 */
public interface StudentDao extends JpaRepository<Student, Integer>,JpaSpecificationExecutor<Student>{

}

TeacherDao

/**
 * 符合Spring Data Jpa 的 dao层接口规范
 *      JpaRepository<操作的实体类类型,实体类中主键属性的类型>
 *          #封装了基本CRUD操作
 *      JpaSpecificationExecutor <操作的实体类类型>
 *          #封装了复杂查询(分页)
 */
public interface TeacherDao extends JpaRepository<Teacher, Integer>,JpaSpecificationExecutor<Teacher>{

}

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
public class ManyToManyTest {
    @Autowired
    private TeacherDao teacherDao;
    @Autowired
    private StudentDao studentDao;

    /**
     * 级联添加
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testAdd(){
        Teacher teacher = new Teacher();
        teacher.setName("林老师");

        Student student = new Student();
        student.setName("小黑");
        student.setGender("男");

        /**
         * 当两方都拥有维护中间表的权力时,中间表的联合主键会重复出现两次或报错
         * 这时有有一方就需要放弃维护权
         */
        //配置用户到角色关系,可以贵中间表中的数据进行维护
        teacher.getStudents().add(student);
        //配置角色到用户的关系,可以对中间表的数据进行维护
        student.getTeachers().add(teacher);

        teacherDao.save(teacher);
    }

    /**
     * 级联删除
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testRemove(){
        //查询1号用户
        Student student = studentDao.findOne(1);
        System.out.println(student);
        //删除1号用户
        studentDao.delete(student);

    }

}
posted @ 2020-08-18 08:58  lawrence林  阅读(238)  评论(0编辑  收藏  举报