보라코딩
JPA를 이용한 데이터베이스 생성 및 접근 본문
JPA 이용 + 엔티티 클래스로 데이터베이스 정의하는 방법
pom.xml
JPA와 H2 데이터베이스를 이용하려면 pom.xml 파일에 의존성을 추가한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
엔티티 클래스 만들기
Car
package com.packet.cardatabase.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String brand, model, color, registerNumber;
@Column(name="`year`")
private int year;
private int price;
public Car() {};
public Car(String brand, String model, String color, String registerNumber, int year, int price) {
super();
this.brand = brand;
this.model = model;
this.color = color;
this.registerNumber = registerNumber;
this.year = year;
this.price = price;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getRegisterNumber() {
return registerNumber;
}
public void setRegisterNumber(String registerNumber) {
this.registerNumber = registerNumber;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
application.properties
spring.datasource.url=jdbc:h2:meme:testdb
spring.jpa.show-sql=true
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
http://localhost:8080/h2-console/
CRUD 리포지터리 만들기
CarRepository
CrudRepository 인터페이스를 확장하며
<Car, Long>은 Car 엔티티 클래스의 리포지터리이고 ID 필드 형식이 Long임을 정의
package com.packet.cardatabase.domain;
import org.springframework.data.repository.CrudRepository;
public interface CarRepository extends CrudRepository<Car, Long>{
}
CardatabaseApplication
CommandLineRunner 인터페이스를 이용하면
애플리케이션이 완전히 시작되기 전에 추가코드 실행 가능 (예제 데이터 준비 적합)
package com.packet.cardatabase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.packet.cardatabase.domain.Car;
import com.packet.cardatabase.domain.CarRepository;
@SpringBootApplication
public class CardatabaseApplication implements CommandLineRunner {
private static final Logger logger =
LoggerFactory.getLogger(CardatabaseApplication.class);
@Autowired
private CarRepository repository;
public static void main(String[] args) {
SpringApplication.run(CardatabaseApplication.class, args);
logger.info("Application started");
}
@Override
public void run(String... args) throws Exception {
repository.save(new Car("Ford", "Mustang", "Red", "ADF-1121", 2021, 59000));
repository.save(new Car("Nissan", "Leaf", "White", "SSJ-3002", 2019, 29000));
repository.save(new Car("Toyota", "Prius", "Silver", "KKO-0212", 2020, 39000));
for (Car car : repository.findAll()) {
logger.info(car.getBrand() + " " + car.getModel());
}
}
}
CarRepository
쿼리는 접두사 (findBy) 로 시작해야 한다!
다음에는 클래스 필드 나와야 한다!
package com.packet.cardatabase.domain;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface CarRepository extends CrudRepository<Car, Long>{
// 브랜드로 자동차 검색
List<Car> findByBrand(String string);
// 색상으로 자동차 검색
List<Car> findByColor(String color);
// 연도로 자동차 검색
List<Car> findByYear(int year);
}
그밖에
// 브랜드와 모델로 검색
List<Car> findByBrandAndModel(String Brand, String model);
// 브랜드 또는 색상으로 검색
List<Car> findByBradnOrColor(String brand, String color);
// 쿼리 정렬
List<Car> findByBrandOrderByYearAsc(String brand);
Query 어노테이션 이용하면 SQL문으로 쿼리 생성 가능
@Query("select c from Car c where c.brand = %?1")
List<Car> findByBrand(String brand);
스프링 데이터 JPA에서 페이징 매김과 정렬 적용하고 엔티티 검색하는 메서드 제공!
public interface CarRepository extends PagingAndSortingRepository<Car, Long>
테이블 간의 관계 추가
일대다 관계 추가하려면
@ManyToOne 또는 @OneToMany 어노테이션 이용
ManyToOne
toMany의 경우, FetchType.LAZY가 기본값
toOne의 경우, FetchType.LAZY 정의 필요
Eager은 즉시검색, LAZY는 지연검색
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="owner")
private Owner owner;
// getter와 setter도 추가
public Owner getOwner() {
return owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
OneToMany
cascade 특성은 삭제 또는 업데이트 시 연속효과 적용되는 방법 지정
ALL은 모든 작업이 연속 적용
(소유자 삭제 시, 자동차도 모두 함께 삭제)
mappedBy="owner"
ㄴ owner 필드가 이 관계의 기본키임을 의미
@OneToMany(cascade = CascadeType.ALL, mappedBy="owner")
private List<Car> cars;
// getter와 setter 추가
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
CardatabaseApplication
@Override
public void run(String... args) throws Exception {
// 소유자 객체 추가하고 데이터베이스에 저장
Owner owner1 = new Owner("John", "Johnson");
Owner owner2 = new Owner("Mary", "bora");
orepository.saveAll(Arrays.asList(owner1, owner2));
repository.save(new Car("Ford", "Mustang", "Red", "ADF-1121", 2021, 59000, owner1));
repository.save(new Car("Nissan", "Leaf", "White", "SSJ-3002", 2019, 29000, owner2));
repository.save(new Car("Toyota", "Prius", "Silver", "KKO-0212", 2020, 39000, owner2));
for (Car car : repository.findAll()) {
logger.info(car.getBrand() + " " + car.getModel());
}
}
다대다 관계로 변경
@ManyToMany(mappedBy = "cars")
private Set<Owner> owners = new HashSet<Owner>();
public Set<Owner> getOwners() {
return owners;
}
public void setOwners(Set<Owner> owners) {
this.owners = owners;
}
@ManyToMany(cascade=CascadeType.PERSIST)
@JoinTable(name="car_owner",
joinColumns = {@JoinColumn(name="`id`")})
private Set<Car> cars = new HashSet<Car>();
public Set<Car> getCars() {
return cars;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
car 테이블과 owner 테이블 사이에 car_owner 이라는 새 조인 테에블이 생성된다.
다대다 관계 관리하기 위해 조인테이블 사용 (@JoinTable 어노테이션)
ㄴ 조인테이블과 조인 열의 이름 설정 가능
'코딩 > Spring' 카테고리의 다른 글
JWT로 백엔드 인증 구현하기 (0) | 2023.07.25 |
---|---|
스프링부트로 RESTful 웹 서비스 만들기 (0) | 2023.07.24 |
스프링 시큐리티 설정하기 (0) | 2023.07.18 |
타임리프 페이지 레이아웃 설정하기 (0) | 2023.07.17 |
Spring Boot Devtools 적용하기 (0) | 2023.07.17 |