一对一单向外键
@OneToOne :一对一关联关系。
@JoinColumn (name = "id_card_id"):name指定关联的字段,其实就是指当前表的外键。
CREATE TABLE id_card(
id INT AUTO_INCREMENT PRIMARY KEY,
pid VARCHAR(18) NOT NULL COMMENT'身份证号',
sname VARCHAR(255) NOT NULL COMMENT'姓名'
)ENGINE = INNODB AUTO_INCREMENT = 10 DEFAULT CHARSET = UTF8;
CREATE TABLE student(
sid INT AUTO_INCREMENT PRIMARY KEY,
id_card_id INT,
gender VARCHAR(255) NOT NULL,
INDEX index_id_card_id (id_card_id),
CONSTRAINT fk_id_card_id FOREIGN KEY(id_card_id) REFERENCES id_card(id)ON DELETE CASCADE ON UPDATE CASCADE
)ENGINE = INNODB AUTO_INCREMENT = 10 DEFAULT CHARSET = UTF8;
package com.springboot.springbootlearning.dataobject;
import javax.persistence.*;
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer sid;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id_card_id" ,unique = true)
private IdCard idCard;
private String gender;
public Student() {
}
public Student(IdCard idCard, String gender) {
this.idCard = idCard;
this.gender = gender;
}
//省略get和set
}
package com.springboot.springbootlearning.dataobject;
import javax.persistence.*;
@Entity
public class IdCard {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(length = 18)
private String pid; //学生身份证号
private String sname; //学生姓名
public IdCard() {
}
public IdCard(String pid, String sname) {
this.pid = pid;
this.sname = sname;
}
//省略get和set
}
package com.springboot.springbootlearning.repository;
import com.springboot.springbootlearning.dataobject.IdCard;
import com.springboot.springbootlearning.dataobject.Student;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class StudentRepositoryTest {
@Autowired
private StudentRepository studentRepository;
@Test
public void save()
{
List<Student> list = new ArrayList<>();
IdCard idCard = new IdCard("123456789","张三");
Student student1 = new Student(idCard,"男");
list.add(student1);
Student student2 = new Student();
student2.setGender("女");
list.add(student2);
Assert.notNull(studentRepository.saveAll(list));
}
}
一对一双向外键
只需要改变IdCard类的代码即可,其他代码与一对一单向外键一样。
@OneToOne(mappedBy="idCard")
双向关联,那么在IdCard类中也需要一个属性Student。@OneToOne表示身份证(IdCard)和学生(Student)是一对一的关系并且关联上学生(Student)。最后,mappedBy="idCard”,可以这么理解,mappedBy定义在关系的被拥有方,mappedBy定义所在的类(不管是单个还是集合的形式)在关系拥有者那一方的名称是“idCard",例如在本例题里,Student类里面有一个IdCard属性,而该属性的名称就是“idCard"。
package com.springboot.springbootlearning.dataobject;
import javax.persistence.*;
@Entity
public class IdCard {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(length = 18)
private String pid; //学生身份证号
private String sname; //学生姓名
@OneToOne(mappedBy = "idCard")
private Student student;
public IdCard() {
}
public IdCard(String pid, String sname) {
this.pid = pid;
this.sname = sname;
}
//省略get和set方法
}
一对一双向外键联合主键
1.创建主键类。
2.主键类必须实现Serializable接口,重写hashCode和equals()方法。
主键类:@Embeddable
实体类:@EmbeddedId