post-image

@OneToOne trong Spring Boot là gì ?

Tổng quan

Cách biểu thị quan hệ 1-1 trong cơ sở dữ liệu là rất phổ biến, ví dụ một người sẽ có một địa chỉ duy nhất (giả sử). Bình thường, khi các bạn tạo table trong csdl để biểu thị mối quan hệ này, thì sẽ có một bảng chứa khóa ngoại của bảng còn lại. Thể hiện mỗi quan hệ này trong code bằng Hibernate thì chúng ta sẽ dùng @OneToOne. Cùng tìm hiểu cách sử dụng annotation @OneToOne trong Spring Boot ở bài viết này

@OneToOne trong Spring Boot

Tạo project

Chúng ta sẽ sử dụng Gradle để tạo một project có khai báo Spring Boot và Jpa để hỗ trợ cho việc demo @OneToOne.

Các bạn có thể tự tạo 1 project Spring-boot với gradle đơn giản tại: https://start.spring.io

plugins {
    id 'org.springframework.boot' version '2.1.4.RELEASE'
    id 'java'
}
apply plugin: 'io.spring.dependency-management'

group 'me.loda.java'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}Code language: JavaScript (javascript)

Trong ứng dụng trên bạn sẽ thấy có com.h2database:h2. Đây là một database, tuy nhiên nó chỉ tồn tại trong bộ nhớ. Tức làm mỗi khi chạy chương trình này, nó sẽ tạo database trong RAM, và tắt chương trình đi nó sẽ mất.

Chúng ta sẽ sử dụng H2 thay cho MySql để cho.. tiện!

Khi tạo xong project, sẽ có thư mục như sau:

@OneToOne trong Spring Boot

Tạo Table

Để tạo table, chúng ta tạo ra các Class tương ứng.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

import lombok.Builder;
import lombok.Data;

@Entity // Hibernate entity
@Data // Lombok 
@Builder // Lombok
public class Person { //Table person

    @Id // Đánh dấu trường này là primary key
    @GeneratedValue // Tự động tăng giá trị id
    private Long id;
    private String name;
}Code language: JavaScript (javascript)
@Entity
@Data
@Builder
public class Address { // Table address
    @Id
    @GeneratedValue
    private Long id;

    private String city;
    private String province;

    @OneToOne // Đánh dấu có mỗi quan hệ 1-1 với Person ở phía dưới
    @JoinColumn(name = "person_id") // Liên kết với nhau qua khóa ngoại person_id
    private Person person; 
}Code language: PHP (php)

Nếu chúng ta chưa tạo ra các table trong cơ sở dữ liệu, thì mặc định Hibernate sẽ bind dữ liệu từ class xuống và tạo table cho chúng ta.

Bạn phải tạo file config src\main\resources\application.properties như sau để kết nối tới H2 database nhé:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
// Không có password, vào thẳng luôn
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# Cho phép vào xem db thông qua web
spring.h2.console.enabled=trueCode language: PHP (php)

Chạy thử

Bạn tạo file OneToOneExampleApplication và cấu hình Spring Boot và khởi chạy chương trình.

@SpringBootApplication
@RequiredArgsConstructor
public class OneToOneExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(OneToOneExampleApplication.class, args);
    }
}Code language: PHP (php)

Sau khi chạy xong, hãy truy cập vào http://localhost:8080/h2-console/ để vào xem database có gì nhé.

Bạn sẽ thấy nó tạo table giống với mô tả ở đầu bài. Với khóa ngoại person_id ở bảng address.

Thêm dữ liệu

Để thêm dữ liệu vào database, chúng ta sẽ dùng tới Jpa.

import org.springframework.data.jpa.repository.JpaRepository;

public interface AddressRepository extends JpaRepository<Address,Long> {
}
public interface PersonRepository extends JpaRepository<Person, Long> {
}Code language: PHP (php)

Chúng ta sẽ tạo một chương trình Spring Boot đơn giản bằng cách sử dụng CommandLineRunner để chạy code ngay khi khởi động.

import javax.transaction.Transactional;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.google.common.collect.Lists;

import lombok.RequiredArgsConstructor;

@SpringBootApplication
@RequiredArgsConstructor
public class OneToOneExampleApplication implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication.run(OneToOneExampleApplication.class, args);
    }

    // Sử dụng @RequiredArgsConstructor và final để thay cho @Autowired
    private final PersonRepository personRepository;
    private final AddressRepository addressRepository;

    @Override
    public void run(String... args) throws Exception {
        // Tạo ra đối tượng person
        Person person = Person.builder()
                              .name("loda")
                              .build();
        // Lưu vào db
        personRepository.save(person);

        // Tạo ra đối tượng Address có tham chiếu tới person
        Address address = Address.builder()
                .city("Hanoi")
                .person(person)
                .build();

        // Lưu vào db
        addressRepository.save(address);

        // Vào: http://localhost:8080/h2-console/ để xem dữ liệu đã insert
    }
}Code language: JavaScript (javascript)

Kết quả trong database lúc này:

@OneToOne trong Spring Boot

Vậy là thằng Address đã liên kết tới Person có id=1. Đúng như ta mong đợi.

Nguồn: https://loda.me/jpa-huong-dan-su-dung-one-to-one-loda1554476367261

Leave a Reply

Your email address will not be published. Required fields are marked *