SpringData JPA中一对一关系映射注解@OneToOne应用

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringData JPA中一对一关系映射注解@OneToOne应用相关的知识,希望对你有一定的参考价值。

SpringData JPA中一对一关系映射注解@OneToOne应用

Spring Data JPA中有一对一,一对多,多对多等关系映射,本次主要学习一对一关系映射。
一对一关系映射在生活中十分常见。例如一个大学生只有一张一卡通,一张一卡通只属于一个大学生。再如人与身份证的关系也是一对一。

在Spring Data JPA中,可用两种方式描述一对一映射关系,一种是通过外键的方式,即一个实体通过外键关联到另一个实体,另一种是通过关联表来保存两个实体一对一的关系映射。

下面学习使用Spring Data JPA实现人与身份证的一对一关系映射。

1-创建基于Spring Data JPA的SpringBoot Web应用,并在mysql中创建名为springbootjpa的数据库。

2-在pom.xml文件中添加相关依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ch6_1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <!--配置SpringBoot的核心启动器-->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <!--添加starter模块-->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--JPA依赖模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--添加MySQL依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>

        </dependency>
        <!-- 添加JDBC依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


</project>

3-在配置文件application.properties中配置数据源。


server.port=8080
#数据源信息配置
spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?characterEncoding=utf8&useSSL=false
#数据库用户名
spring.datasource.username = root
#数据库密码
spring.datasource.password = 123456
#数据库驱动
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#指定数据库类型
spring.jpa.database = MYSQL
#指定是否在日志中显示SQL语句
spring.jpa.show-sql = true
#指定自动创建,更新数据库表等配置
spring.jpa.hibernate.ddl-auto = update
#让控制器输出JSON字符串格式更美观
spring.jackson.serialization.indent-output = true
#上传文件时候,默认上传文件大小是1MB,max-file-size设置单个文件上传大小
spring.servlet.multipart.max-file-size=50MB
#默认总文件大小为10MB,max-request-size设置总上传文件的大小
spring.servlet.multipart.max-request-size=500MB

4-在src/main/java目录下创建com.entity包,在该包中创建名为Person和IdCard的持久化类。

Person类:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "person_table")
@JsonIgnoreProperties(value = {"hibernateLazyInitializer"})
public class Person implements Serializable {
    private static final long serialVersionUID = 1L ;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id ;
    private String pname ;
    private String psex ;
    private int page ;
    @OneToOne(
            optional = true , //身份证号可以为空,小孩子可以没有身份证号
            fetch = FetchType.LAZY, //加载一个实体,不会立即从数据库中加载
            targetEntity = IdCard.class, //与该实体类关联的目标实体类
            cascade = CascadeType.ALL //同时选择级联新建、删除、刷新、更新
    )
    @JoinColumn(
            name = "id_Card_id", //指定Person表的id_Card_id列作为外键与IdCard表对应的id列进行关联
            referencedColumnName = "id", //指定参考的主键
            unique = true //指定id_Card_id列的值不可重复
    )
    @JsonIgnore
    private IdCard idCard ;

    public int getId() {
        return id;
    }

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

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public String getPsex() {
        return psex;
    }

    public void setPsex(String psex) {
        this.psex = psex;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public IdCard getIdCard() {
        return idCard;
    }

    public void setIdCard(IdCard idCard) {
        this.idCard = idCard;
    }
}

IdCard类:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Calendar;

@Entity
@Table(name = "idcard_table")
@JsonIgnoreProperties(value = {"hibernateLazyInitializer"})
public class IdCard implements Serializable {
    private static final long serialVersionUID = 1L ;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id ; //主键自动递增
    private String code ;
    @Temporal(value = TemporalType.DATE) //指定日期格式
    private Calendar birthday ;
    private String address ;

    @OneToOne(
            optional = false, //有身份证号的人必须存在,person不能为空
            fetch = FetchType.LAZY,//加载一个实体,不会立即从数据库加载
            mappedBy = "idCard",//与Person类的idCard属性一致
            cascade = CascadeType.ALL //同时进行级联新建、删除、刷新、更新
    )
    private Person person ;

    public int getId() {
        return id;
    }

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

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Calendar getBirthday() {
        return birthday;
    }

    public void setBirthday(Calendar birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }
}

上述实体类中,@OneToOne注解有5个属性:targetEntity,cascade,fetch,optional,mappedBy.
targetEntity属性:定义关系类的类别。
cascade属性:定义类与类别之间的级联关系。定义的级联关系将被容器视作为对当前类对象及其关联的对象采取相同的操作。CascadeType.ALL 表示同时进行级联新建、删除、刷新、更新。
fetch属性:分为两种,FetchType.LAZY代表懒加载,即定义的属性不会立即从数据库中加载,FetchType.EAGER为急加载,定义的属性会立即从数据库中加载。
optional属性:为true时,表示对应类的属性可以为空,反之,不能为空。
mappedBy属性:一定是定义在关系的被维护端,指向关系的维护端。

5-在src/main/java目录下创建数据com.repository包,在该包中创建两个接口并继承JpaRepository接口,实现数据访问层。

import com.entity.IdCard;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface IdCardRepository extends JpaRepository<IdCard, Integer> {
    //根据人员id查询身份信息
    public IdCard findByPerson_id(Integer id) ;

    //根据地址和身份证号码查询身份信息
    public List<IdCard> findByAddressAndCode(String address, String code) ;
}

import com.entity.Person;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PersonRepository extends JpaRepository<Person, Integer> {
    //根据身份ID查询人员信息
    public Person findByIdCard_id(Integer id) ;

    //根据人名和性别查询人员信息
    public List<Person> findByPnameAndPsex(String pname, String psex) ;

}

6-在src/main/java目录下创建com.service包,该包为业务层,在该包中创建业务层的接口和接口的实现类。


import com.entity.IdCard;
import com.entity.Person;

import java.util.List;

public interface PersonAndIdCardService {
    public void saveAll() ;
    public List<Person> findAllPerson() ;
    public List<IdCard> findAllIdCard() ;
    public IdCard findByPerson_id(Integer id) ;
    public List<IdCard> findByAddressAndCode(String address, String code) ;
    public Person findByIdCard_id(Integer id) ;
    public List<Person> findByPnameAndPsex(String pname, String psex) ;
    public IdCard getOneIdCard(Integer id) ;
    public Person getOnePerson(Integer id) ;
}
import com.entity.IdCard;
import com.entity.Person;
import com.repository.IdCardRepository;
import com.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
@Service
public class PersonAndIdCardServiceImpl implements PersonAndIdCardService {
    @Autowired
    private IdCardRepository idCardRepository ;
    @Autowired
    private PersonRepository personRepository ;
    @Override
    public void saveAll() {
        //先保存身份证,身份证实体是被维护端
        IdCard idCard = new IdCard() ;
        idCard.setCode("123456789");
        idCard.setAddress("南昌");
        Calendar calendar = Calendar.getInstance() ;
        calendar.set(2021, 11, 11) ;
        idCard.setBirthday(calendar);

        IdCard idCard1 = new IdCard() ;
        idCard1.setCode("1111111111");
        idCard1.setAddress("南京");
        Calendar calendar1 = Calendar.getInstance() ;
        calendar1.set(2021, 11, 12) ;
        idCard1.setBirthday(calendar1);

        IdCard idCard2 = new IdCard() ;
        idCard2.setCode("222222222");
        idCard2.setAddress("杭州");
        Calendar calendar2 = Calendar.getInstance() ;
        calendar2.set(2021, 11, 13) ;
        idCard2.setBirthday(calendar2);

        List<IdCard>  idCards = new ArrayList<>() ;
        idCards.add(idCard) ;
        idCards.add(idCard1) ;
        idCards.add(idCard2) ;
        idCardRepository.saveAll(idCards) ;

        //保存人员
        Person p1 = new Person() ;
        p1.setPname("王国栋");
        p1.setPsex("男");
        p1.setPage(24);
        p1.setIdCard(idCard);

        Person p2 = new Person() ;
        p2.setPname("何卓忆");
        p2.setPsex("女");
        p2.setPage(20);
        p2.setIdCard(idCard1);

        Person p3 = new Person() ;
        p3.setPname("唐乃乔");
        p3.setPsex("男");
        p3.setPage(24);
        p3.setIdCard(idCard2);

        List<Person> persons = new ArrayList<>() ;
        persons.add(p1) ;
        persons.add(p2) ;
        persons.add(p3) ;
        personRepository.saveAll(persons) ;
    }

    @Override
    public List<Person> findAllPerson() {
        return personRepository.findAll();
    }

    @Override
    public List<IdCard> findAllIdCard() {
        return idCardRepository.findAll();
    }

    @Override
    public IdCard findByPerson_id(Integer id) {
        return idCardRepository.findByPerson_id(id);
    }

    @Override
    public List<IdCard> findByAddressAndCode(String address, String code) {
        return idCardRepository.findByAddressAndCode(address,code);
    }

    @Override
    public Person findByIdCard_id(Integer id) {
        return personRepository.fi

以上是关于SpringData JPA中一对一关系映射注解@OneToOne应用的主要内容,如果未能解决你的问题,请参考以下文章

SpringData JPA多表关联操作

jpa多对一映射

jpa关联映射(一)

SpringData JPA多表查询

springdata_多表关系中的一对一__小案例

SpringDataJPA