springDataJpa——多表

一、环境搭建

springDataJpa的基本环境搭建在上篇已经讲到,这里不再赘述。环境配置具体链接如下springDataJpa环境搭建

二、OneToMany

1、实体类

这里我们以一个父亲与儿子的关系为例描述一对多,创建的实体类如下

1.1、Father类
package com.xsl.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
//@Entity注解声明这个是一个对应表的有实体
@Entity
//@Table创建表,指定表名
@Table(name = "father")
public class Father {
	//@Id主键
    @Id
    // @GeneratedValue主键生成策略,这里使用的mysql所以自增
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    //@Column字段与数据库表列映射
    @Column(name = "fid")
    Long fid;
    @Column(name = "name")
    String name;
//一的一方放弃外键的维护权
//    @OneToMany(targetEntity = Son.class)
//    @JoinColumn(name = "s_fid",referencedColumnName = "fid")
    @OneToMany(mappedBy = "father",cascade = CascadeType.ALL)//mappedBy放弃维护权,cascade:设置级联
    private Set<Son> sons = new HashSet<>();

//以下为构造器、getter、setter、toString方法
    public Set<Son> getSons() {
        return sons;
    }

    public void setSons(Set<Son> sons) {
        this.sons = sons;
    }

    public Father(Long fid ,String name) {
        this.fid = fid;
        this.name = name;
    }

    public Father() {
    }

    public Father(String name) {
        this.name = name;
    }

    public Long getFid() {
        return fid;
    }

    public void setFid(Long fid) {
        this.fid = fid;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Father{" +
                "fid=" + fid +
                ", name='" + name + '\'' +
                '}';
    }
}
1.2、Son类
package com.xsl.entity;

import javax.persistence.*;

@Entity
@Table(name = "son")
public class Son {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sid")
    private Long sid;
    @Column(name = "name")
    private String name;
	//维护关系,targetEntity指对方的字节码
    @ManyToOne(targetEntity = Father.class)
    //referencedColumnName指的是依照的主要列的字段名
    @JoinColumn(name = "s_fid",referencedColumnName = "fid")
    private Father father;

    public Father getFather() {
        return father;
    }

    public void setFather(Father father) {
        this.father = father;
    }

    public Son(Long sid, String name) {
        this.sid = sid;
        this.name = name;
    }

    public Son(String name) {
        this.name = name;
    }

    public Son() {
    }

    public Long getSid() {
        return sid;
    }

    public void setSid(Long sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Son{" +
                "sid=" + sid +
                ", name='" + name + '\'' +
                '}';
    }
}
2、DAO层

DAO层定义两个接口,继承JpaRepository<K,T>,JpaSpecificationExecutor<K,T>即可

3、测试
package com.xsl.test;

import com.xsl.dao.FatherDao;
import com.xsl.dao.SonDao;
import com.xsl.entity.Father;
import com.xsl.entity.Son;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ManyTableTest {

    @Autowired
    private FatherDao fatherDao;

    @Autowired
    private SonDao sonDao;

    /**
     * 多表
     */
    @Test
    //多表要添加事务保证connection是同一个
    @Transactional
    //不要自动回滚
    @Rollback(false)
    public void test(){
        Father father = new Father("肖生亮");
        Son son = new Son("肖生亮的儿子");
        son.setFather(father);
        fatherDao.save(father);
        sonDao.save(son);
    }

    /**
     * 级联添加
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testCascadeAdd(){
        Father father = new Father("肖生亮");
        Son son = new Son("肖生亮的儿子");
        son.setFather(father);
        father.getSons().add(son);
        fatherDao.save(father);
    }

    @Test
    @Transactional
    @Rollback(false)
    public void testCascadeDelete(){
        Father one = fatherDao.findOne(5l);
        fatherDao.delete(one);
    }

}

二、ManyToMany

1、实体类

这里我们以一个学生与老师的关系为例描述多对多,创建的实体类如下

1.1、Teacher类
package com.xsl.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name="teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    @Column(name = "name")
    private String name;
//放弃维护权
//    @ManyToMany(targetEntity = Student.class)
//多对多其实是增加一个表来维护两实体的关系
//    @JoinTable(
//            name = "sys_tea_stu",joinColumns =
//            //当前表在中间表中的键,两张表各取一个字段作为联合主键
//            {@JoinColumn(name = "sys_tea_id",referencedColumnName = "id")},
//            //对方对象在中间表的键
//            inverseJoinColumns = {@JoinColumn(name = "sys_stu_id",referencedColumnName = "id")}
//    )
    @ManyToMany(mappedBy = "teachers")
    private Set<Student> students = new HashSet<>();

    public Teacher() {
    }

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

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

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

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Teacher(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Teacher(String name) {
        this.name = name;
    }
}
1.2、Student类
package com.xsl.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "student")
public class Student {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name;

    @ManyToMany(targetEntity = Teacher.class,cascade = CascadeType.ALL)
    @JoinTable(
            name = "sys_tea_stu",joinColumns =
            //当前表在中间表中的外键
            {@JoinColumn(name = "sys_stu_id",referencedColumnName = "id")},
            //对方对象在中间表的外键
            inverseJoinColumns = {@JoinColumn(name = "sys_tea_id",referencedColumnName = "id")}
            )
    private Set<Teacher> teachers = new HashSet<>();

    public Student() {
    }

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

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

    public Student(String name) {
        this.name = name;
    }

    public Student(Long id, String name) {
        this.id = id;
        this.name = name;
    }

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

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
2、DAO层

DAO层定义两个接口,继承JpaRepository<K,T>,JpaSpecificationExecutor<K,T>即可

3、测试
package com.xsl.test;

import com.xsl.dao.StudentDao;
import com.xsl.dao.TeacherDao;
import com.xsl.entity.Student;
import com.xsl.entity.Teacher;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.Set;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ManyToManyTest {

    @Autowired
    private StudentDao studentDao;
    @Autowired
    private TeacherDao teacherDao;

    @Test
    @Transactional
    @Rollback(false)
    public void test(){
        Student student = new Student("肖生亮");
        Teacher teacher = new Teacher("钱小红");
        //如果两方都有维护权,两方都添加,会报异常(主键冲突)
        student.getTeachers().add(teacher);
        studentDao.save(student);
    }

    @Test
    @Transactional
    @Rollback(false)
    public void testCascadeDelete(){
        //cascade操作会把级联的两个关系和中间表一起删掉,慎用
        Student one = studentDao.findOne(4l);
        studentDao.delete(one);
    }

    /**
     * 测试对象导航查询
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testSelect(){
        Student one = studentDao.getOne(3l);
        Set<Teacher> teachers = one.getTeachers();
        for (Teacher tea :
                teachers) {
            Set<Student> students = tea.getStudents();
            System.out.println(students);
        }


    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值