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表中的數據以一個對象的形式關聯過來了。

接下來測試自己定義的接口方法 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章