前言
所谓一对一,就是在两个表中有唯一的两条数据相互对应。举个栗子,一个人只有一个身份证号,这就是一对一。下面讲解怎么在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表中的数据以一个对象的形式关联过来了。
接下来测试自己定义的接口方法