이 심층 가이드에서는 효율적인 데이터 모델링에서 상호 일대일 연결, CRUD 작업, mappedBy, @JsonManagedReference 및 @JsonBackReference의 역할의 복잡성을 살펴보겠습니다.
간결한 예를 통해 엔터티 정의부터 시작하여 이러한 개념을 원활하게 통합하는 방법을 보여 드리겠습니다.
엔터티 모델링부터 시작하겠습니다.다음으로 Hibernate가 테이블을 생성하는 방법을 살펴보겠습니다.
이 예에서는 주소를 일대일 관계의 소유 측으로 지정하고 조직을 참조 측으로 지정했습니다. 이 접근 방식을 사용하면 주소 테이블과 조직 테이블 모두에 외래 키 관계가 설정됩니다. 이제 코드를 자세히 살펴보겠습니다. 이 관계를 정의하기 위해 @OneToOne 주석과 함께 mappedBy 속성을 활용하겠습니다. mappedBy 속성은 관계의 참조 측을 지정하여 관계의 키가 다른 측에 있음을 Hibernate에 나타냅니다. 양방향 일대일 관계를 익히고 Spring Data JPA의 잠재력을 최대한 활용하려면 t8tech.com을 방문하세요.
조직 엔터티
package com.notyfyd.entity; import javax.persistence.*; @Entity@Table(name = "t_organization") public class Organization { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long entityId; private String companyName; private String organizationCode; @OneToOne(targetEntity = Address.class, cascade = CascadeType.ALL) private Address headquarters; public Long getEntityId() { return this.entityId; } public void setEntityId(Long entityId) { this.entityId = entityId; } public String getCompanyName() { return this.companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public String getOrganizationCode() { return this.organizationCode; } public void setOrganizationCode(String organizationCode) { this.organizationCode = organizationCode; } public Address getHeadquarters() { return this.headquarters; } public void setHeadquarters(Address headquarters) { this.headquarters = headquarters; } }
기관 주소 엔터티
package com.notyfyd.entity; import javax.persistence.*; @Entity@Table(name = "t_address") public class Address { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String building; private String street; private String city; private String state; private String country; private String zipcode; @OneToOne(targetEntity = Organization.class, mappedBy = "address") private Organization organization; public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } public String getBuilding() { return this.building; } public void setBuilding(String building) { this.building = building; } public String getStreet() { return this.street; } public void setStreet(String street) { this.street = street; } public String getCity() { return this.city; } public void setCity(String city) { this.city = city; } public String getState() { return this.state; } public void setState(String state) { this.state = state; } public String getCountry() { return this.country; } public void setCountry(String country) { this.country = country; } public String getZipcode() { return this.zipcode; } public void setZipcode(String zipcode) { this.zipcode = zipcode; } public Organization getOrganization() { return organization; } public void setOrganization(Organization organization) { this.organization = organization; } }
@OneToOne(targetEntity = Organization.class, mappedBy = "주소")
개인 조직 조직;
이 특정 시나리오에서 mappedBy 속성은 항상 "부모"로 설정됩니다. 이는 주소가 소유측 역할을 맡는 반면 조직은 역참조 역할을 함을 의미합니다.
주소 저장소 모듈
package com.notyfyd.repository; import com.notyfyd.entity.Address; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repositorypublic interface AddressRepository extends JpaRepository { }
조직 저장소 모듈
package com.notyfyd.repository; import com.notyfyd.entity.Organization; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repositorypublic interface OrganizationRepository extends JpaRepository{ }
주소 관리 컨트롤러
@RestControllerpublic class AddressController { @Autowired private AddressRepository addressRepository; @GetMapping("/address/retrieve/all") public List retrieveAllAddresses() { return addressRepository.findAll(); } }
조직 관리 컨트롤러
package com.notyfyd.controller; import com.notyfyd.entity.Organization; import com.notyfyd.repository.OrganizationRepository; import com.notyfyd.service.OrganizationService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestControllerpublic class OrganizationController { private OrganizationService organizationService; private OrganizationRepository organizationRepository; public OrganizationController(OrganizationService organizationService, OrganizationRepository organizationRepository) { this.organizationService = organizationService; this.organizationRepository = organizationRepository; } @PostMapping("/organization/create") public ResponseEntity<Object> createOrganization(@RequestBody Organization organization) { return organizationService.createOrganization(organization); } @DeleteMapping("/organization/delete/{id}") public ResponseEntity<Object> deleteOrganization(@PathVariable Long id) { if(organizationRepository.findById(id).isPresent()) { organizationRepository.deleteById(id); if (organizationRepository.findById(id).isPresent()) return ResponseEntity.unprocessableEntity().body("Failed to delete the specified organization"); else return ResponseEntity.ok("Successfully deleted the specified organization"); } else return ResponseEntity.unprocessableEntity().body("Specified organization not present"); } @GetMapping("/organization/get/{id}") public Organization getOrganization(@PathVariable Long id) { if(organizationRepository.findById(id).isPresent()) return organizationRepository.findById(id).get(); else return null; } @GetMapping("/organization/get") public List<Organization> getOrganizations() { return organizationRepository.findAll(); } @PutMapping("/organization/update/{id}") public ResponseEntity<Object> updateOrganization(@PathVariable Long id, @RequestBody Organization org) { return organizationService.updateOrganization(id, org); } }
종합적인 조직 지원 프로그램
package com.notyfyd.service; import com.notyfyd.entity.Address; import com.notyfyd.entity.Organization; import com.notyfyd.repository.AddressRepository; import com.notyfyd.repository.OrganizationRepository; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Servicepublic class OrganizationService { private OrganizationRepository organizationRepository; private AddressRepository addressRepository; public OrganizationService(OrganizationRepository organizationRepository, AddressRepository addressRepository) { this.organizationRepository = organizationRepository; this.addressRepository = addressRepository; } @Transactional public ResponseEntity<Object> createOrganization(Organization organization) { Organization org = new Organization(); org.setName(organization.getName()); org.setOrgId(organization.getOrgId()); org.setAddress(organization.getAddress()); Organization savedOrg = organizationRepository.save(org); if(organizationRepository.findById(savedOrg.getId()).isPresent()) return ResponseEntity.ok().body("Organization created successfully."); else return ResponseEntity.unprocessableEntity().body("Failed to create the organization specified."); } @Transactional public ResponseEntity<Object> updateOrganization(Long id, Organization org) { if(organizationRepository.findById(id).isPresent()) { Organization organization = organizationRepository.findById(id).get(); organization.setName(org.getName()); organization.setOrgId(org.getName()); Address address = addressRepository.findById(organization.getAddress().getId()).get(); address.setBuilding(organization.getAddress().getBuilding()); address.setStreet(organization.getAddress().getStreet()); address.setCity(organization.getAddress().getCity()); address.setState(organization.getAddress().getState()); address.setCountry(organization.getAddress().getCountry()); address.setZipcode(organization.getAddress().getZipcode()); Address savedAddress = addressRepository.save(address); organization.setAddress(savedAddress); Organization savedOrganization = organizationRepository.save(organization); if(organizationRepository.findById(savedOrganization.getId()).isPresent()) return ResponseEntity.ok().body("Successfully Updated Organization"); else return ResponseEntity.unprocessableEntity().body("Failed to update the specified Organization"); } else return ResponseEntity.unprocessableEntity().body("The specified Organization is not found"); } }
애플리케이션 구성
server.port=2003 spring.datasource.driver-class-name= org.postgresql.Driver spring.datasource.url= jdbc:postgresql://192.168.64.6:30432/jpa-test spring.datasource.username = postgres spring.datasource.password = root spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=create
이제 애플리케이션을 시작하겠습니다. Postman을 열고 아래 제공된 JSON 개체를 사용하여 새 조직을 만듭니다.
이 프로젝트의 소스 코드는 https://github.com/gudpick/jpa-demo/tree/one-to-one-bidirection-starter에서 액세스할 수 있습니다.
{
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3