Spring Data JPA -- 多表操作(一对一)

前言

所谓一对一,就是在两个表中有唯一的两条数据相互对应。举个栗子,一个人只有一个身份证号,这就是一对一。下面讲解怎么在Spring Data JPA 中实现一对一操作。

首先我们这里有两张表,一张Person表,一张Address表,也就是一个人只有一个家庭住址。

person表:      Address表:

1.新建两个实体类

Person类:

package com.chen.domain.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Getter
@Setter
@Entity
@Table(name = "test_person")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "name")
    private String name;

    @Column(name = "age")
    private int age;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="address_id",referencedColumnName="id")
    private Address address;
}

说明:

@OneToOne(cascade=CascadeType.ALL)代表一对一关联

@JoinColumn(name="address_id",referencedColumnName="id")表示address_id是外键字段,并设置与表Address中的id字段关联

Address类:

package com.chen.domain.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Getter
@Setter
@Entity
@Table(name = "test_address")
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "address")
    private String address;
}

2.新建Dao接口,因为在Person类设置了外键关联,所以只需要一个dao接口即可

package com.chen.dao;

import com.chen.domain.entity.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer>, JpaSpecificationExecutor<Person> {

    @Query(value = "SELECT p.name,p.age,a.address FROM test_person p LEFT JOIN test_address a ON p.address_id=a.id", nativeQuery = true)
    List<Map<String, Object>> findPersonAndAddress();
}

说明:我这里新加了一个接口方法,出于强迫症,我不喜欢给前端返回一堆多余的东西,需要什么数据,我就拿出什么数据 。另外,个人喜欢将数据直接返回成List<Map<String,Object>>的形式。在网上借鉴了很多网友的思路和代码,基本都是新建一个实体类去封装返回的数据,但在实际开发中,不可能每次都去新建一个实体类进行装配,当然是怎么方便怎么来。

3.新建service,实现dao中的接口方法

package com.chen.service;

import com.chen.dao.PersonRepository;
import com.chen.domain.entity.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class PersonService {

    @Autowired
    private PersonRepository personRepository;

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

    public List<Map<String, Object>> findPersonAndAddress(){
        return personRepository.findPersonAndAddress();
    }
}

4.在controller层进行调用

package com.chen.controller;

import com.chen.domain.entity.Person;
import com.chen.restful.RestResponse;
import com.chen.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class PersonController {

    @Autowired
    private PersonService personService;

    @PostMapping("findAllPerson")
    public RestResponse findAllPerson(){
        List<Person> allPerson = personService.findAllPerson();
        return RestResponse.ok().data(allPerson);
    }

    @PostMapping("findPersonAndAddress")
    public RestResponse findPersonAndAddress(){
        List<Map<String, Object>> personAndAddress = personService.findPersonAndAddress();
        return RestResponse.ok().data(personAndAddress);
    }
}

5.测试

首先测试第一种,用JPA自带的接口方法,返回结果如下,可以看到address表中的数据以一个对象的形式关联过来了。

接下来测试自己定义的接口方法 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

西瓜不甜柠檬不酸

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值