В этом подробном руководстве мы рассмотрим тонкости взаимных однозначных ассоциаций, операций CRUD и роль MappedBy, @JsonManagedReference и @JsonBackReference в эффективном моделировании данных.
На кратком примере мы продемонстрируем, как легко интегрировать эти концепции, начиная с определения объекта.
Давайте начнем с моделирования наших сущностей.Далее мы рассмотрим, как Hibernate генерирует таблицы.
В этом примере мы обозначили «Адрес» в качестве владеющей стороны связи «один-к-одному», а «Организацию» — в качестве ссылающейся стороны. Этот подход гарантирует, что отношения внешнего ключа устанавливаются как в адресной, так и в организационной таблице. Теперь давайте углубимся в код. Мы будем использовать атрибут MappedBy в сочетании с аннотацией @OneToOne, чтобы определить эту связь. Атрибут 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