
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
}
spring:
datasource:
driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3306/menudb
username: swcamp
password: swcamp
jpa:
show-sql: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
자주 쓰는 속성만 요약
@Entity(name = "entityMember")
@Table(name = "tbl_member")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_no")
private int memberNo;
@Column(name = "member_id", unique = true, nullable = false, columnDefinition = "varchar(10)")
private String memberId;
@Column(name = "member_pwd", nullable = false)
private String memberPwd;
@Column(name = "member_name")
private String memberName;
@Transient
private String phone;
@Column(name = "address", length = 900)
private String address;
@Column(name = "enroll_date")
private LocalDateTime enrollDate;
@Enumerated(EnumType.STRING)
@Column(name = "member_role")
private MemberRole memberRole;
@Column(name = "status", columnDefinition = "char(1) default 'Y'")
private String status;
protected Member() {}
// 생성자 생략
}
Repository/Service 테스트로 테이블 생성 및 insert 확인
테이블을 이용해 키를 발급하는 방식.
@TableGenerator(
name = "member_seq_tbl_generator",
table = "tbl_my_sequences",
pkColumnValue = "my_seq_member_no"
)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "member_seq_tbl_generator")
@Column(name = "member_no")
private int memberNo;
// ...
}
로그 흐름
@Entity(name = "entityMember")
@Table(name = "tbl_member")
@Access(AccessType.FIELD)
public class Member {
// ...
@Access(AccessType.PROPERTY)
public String getMemberName() {
System.out.println("getMemberName()으로 접근");
return memberName + "님"; // 조회 시 가공
}
}
Repository JPQL 예시(실전에서는 파라미터 바인딩 권장)
String jpql = "SELECT m.memberName FROM entityMember m WHERE m.memberId = :memberId";
return em.createQuery(jpql, String.class)
.setParameter("memberId", memberId)
.getSingleResult();
테스트에서 “님”이 붙은 값 반환 확인
공통 속성을 값 타입으로 분리해 재사용.
@Embeddable
public class Price {
@Column(name = "regular_price") private int regularPrice;
@Column(name = "discount_rate") private double discountRate;
@Column(name = "sell_price") private int sellPrice;
protected Price() {}
public Price(int regularPrice, double discountRate) {
if (regularPrice < 0) throw new IllegalArgumentException("가격 음수 불가");
if (discountRate < 0) throw new IllegalArgumentException("할인율 음수 불가");
this.regularPrice = regularPrice;
this.discountRate = discountRate;
this.sellPrice = (int)(regularPrice - (regularPrice * discountRate));
}
}
@Entity
@Table(name = "tbl_book")
public class Book {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "book_no")
private int bookNo;
// ...
@Embedded
private Price price;
}
DDL에서 임베디드 필드는 소유 엔티티 테이블 컬럼으로 평탄화됨(regular_price, discount_rate, sell_price 등)
두 방식 모두 복합키 클래스는 Serializable 구현 필요, @GeneratedValue 사용 불가.
equals/hashCode 구현을 강력 권장(동등성/캐시 일관성 보장).
@Embeddable
public class LikeCompositeKey implements Serializable {
@Column(name = "liked_member_no") private int likedMemberNo;
@Column(name = "liked_book_no") private int likedBookNo;
protected LikeCompositeKey() {}
public LikeCompositeKey(int likedMemberNo, int likedBookNo) { ... }
// equals/hashCode 권장
}
@Entity
@Table(name = "tbl_like")
public class Like {
@EmbeddedId
private LikeCompositeKey likeInfo;
protected Like() {}
public Like(LikeCompositeKey likeInfo) { this.likeInfo = likeInfo; }
}
DDL 예시
create table tbl_like (
liked_book_no integer not null,
liked_member_no integer not null,
primary key (liked_book_no, liked_member_no)
)
public class CartCompositeKey implements Serializable {
private int cartOwner;
private int addedBook;
protected CartCompositeKey() {}
public CartCompositeKey(int cartOwner, int addedBook) { ... }
// equals/hashCode 권장
}
@Entity
@Table(name = "tbl_cart")
@IdClass(CartCompositeKey.class)
public class Cart {
@Id @Column(name = "cart_owner") private int cartOwner;
@Id @Column(name = "added_book") private int addedBook;
@Column(name = "quantity") private int quantity;
protected Cart() {}
public Cart(int cartOwner, int addedBook, int quantity) { ... }
}
DDL 예시
create table tbl_cart (
added_book integer not null,
cart_owner integer not null,
quantity integer,
primary key (added_book, cart_owner)
)
Serializable + equals/hashCode 구현