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.findByIdCard_id(id);
    }

    @Override
    public List<Person> findByPnameAndPsex(String pname, String psex) {
        return personRepository.findByPnameAndPsex(pname, psex);
    }

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

    @Override
    public Person getOnePerson(Integer id) {
        return personRepository.getOne(id);
    }
}

7-在src/main/java目录下创建com.controller包,在该包中创建控制器类。

import com.entity.IdCard;
import com.entity.Person;
import com.service.PersonAndIdCardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class TestOneToOneController {
    @Autowired
    private PersonAndIdCardService personAndIdCardService ;
    @RequestMapping("/save1")
    public String save(){
        personAndIdCardService.saveAll();
        return "人员和身份保存成功!" ;
    }
    @RequestMapping("/findAllPerson")
    public List<Person> findAllPerson(){
        return personAndIdCardService.findAllPerson() ;
    }
    @RequestMapping("/findAllIdCard")
    public List<IdCard> findAllIdCard(){
        return personAndIdCardService.findAllIdCard() ;
    }
    //根据人员ID查询身份信息
    @RequestMapping("/findByPerson_id")
    public IdCard findByPerson_id(Integer id){
        return personAndIdCardService.findByPerson_id(id) ;
    }
    @RequestMapping("/findByAddressAndCode")
    public List<IdCard> findByAddressAndCode(String address, String code){
        return personAndIdCardService.findByAddressAndCode(address, code) ;
    }
    //根据身份证ID查询人员信息
    @RequestMapping("/findByIdCard_id")
    public Person findByIdCard_id(Integer id){
        return personAndIdCardService.findByIdCard_id(id) ;
    }
    @RequestMapping("/findByPnameAndPsex")
    public List<Person> findByPnameAndPsex(String pname, String psex){
        return personAndIdCardService.findByPnameAndPsex(pname, psex) ;
    }
    @RequestMapping("/getOneIdCard")
    public IdCard getOneIdCard(Integer id){
        return personAndIdCardService.getOneIdCard(id) ;
    }
    @RequestMapping("/getOnePerson")
    public Person getOnePerson(Integer id){
        return personAndIdCardService.getOnePerson(id) ;
    }
}

8-在src/main/java/com目录下创建启动类,并运行。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args) ;
    }
}

9-访问http://localhost:8080/save
完成保存数据,查看数据库数据如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
10-测试相关查询
(1)查询身份证id为1的人员信息
在这里插入图片描述
(2)查询人员id为1的身份信息
在这里插入图片描述
(3)查询所有的人员信息
在这里插入图片描述
(4)查询所有的身份信息
在这里插入图片描述

剩下的查询自行测试,本次不再演示。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值