Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- tableperclass
- 프라이머리키
- 데이터베이스네이밍규칙
- db설계방법
- spring필수문법
- 내일배움캠프
- django
- 데이터베이스설계요약
- 릴레이션십데이터베이스
- 스파르타코딩
- 준태튜터님
- 장고기초지식
- 스파르타코딩클럽
- jpa플러시
- 패스트캠퍼스
- 팀스파르타
- JPA
- 코딩
- 장고
- db설계과정
- 리콰이어먼츠 설정
- Python
- 포링키
- db네이밍규칙
- 스파코
- 자기계발회고
- jakartapersistenceapi
- dbnamingrule
- db설계핵심요약
- 파이썬
Archives
- Today
- Total
당우 일기장
JPA 상속 기법: 다중테이블 전략으로 회원 도메인 설계하기 본문
JPA의 상속 매핑 전략 중
다중테이블 전략(TABLE_PER_CLASS)
를 활용해 회원 도메인을 설계한 과제 내용을 요약해 소개합니다.
학생(Student), 강사(Instructor), 관리자(Admin)로 구분되는 회원 데이터를 각각 독립적인 테이블로 관리하며
코드와 함께 살펴보겠습니다.
과제 개요
회원 도메인 설계
- 부모 클래스: User
- 공통 속성: userId, username, email, passwordHash, createdAt
- 공통 메서드: login(), updateProfile()
- 자식 클래스:
- Student: 특화 속성 studentId (학번)
- Instructor: 특화 속성 majorSubject (전공 과목)
- Admin: 특화 속성 position (직책), department (부서)
- 상속 전략: TABLE_PER_CLASS
- 각 역할별 독립 테이블(students, instructors, admins) 생성
- MySQL 환경 가정, ID는 GenerationType.TABLE로 관리 (수정 시 IDENTITY 권장)
코드 설명
1. 부모 클래스: User
- 역할: 모든 회원의 공통 속성과 메서드를 정의.
- 상속 전략: @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)로 다중테이블 전략 지정.
- ID 생성: @GeneratedValue(strategy = GenerationType.TABLE)로 자동 생성 (MySQL에서는 IDENTITY로 변경 가능).
2. 자식 클래스: Student, Instructor, Admin
- 공통점: User를 상속받아 공통 속성을 물려받음.
- 특화 속성: 각 클래스마다 독자적인 속성을 추가.
- 테이블 분리: @Table로 각기 다른 테이블 이름 지정.
3. 실행 클래스: Application
- 기능: 엔티티 생성, 저장, 조회를 테스트.
- 수정 포인트: 초기 코드에서 ID를 수동 설정해 detached entity 에러 발생 → ID 수동 설정 제거 후 자동 생성으로 변경.
4. 다중테이블 전략의 특징
- 장점: 조인 없이 빠른 조회, 독립적인 테이블 관리.
- 단점: 공통 속성 중복 저장, 다형성 쿼리 시 UNION 비용 발생.
1. 부모 클래스: User
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.TABLE) // MySQL에서는 IDENTITY 추천
private int id;
private String userId;
private String username;
private String email;
private String passwordHash;
private LocalDateTime createdAt;
public User() {}
public User(String username, String userId, String email, String passwordHash, LocalDateTime createdAt) {
this.username = username;
this.userId = userId;
this.email = email;
this.passwordHash = passwordHash;
this.createdAt = createdAt;
}
public void login() {
System.out.println(username + " 로그인 시도");
}
public void updateProfile() {
System.out.println(username + "의 프로필 업데이트");
}
// Getter, Setter, toString 생략
}
2. 자식 클래스: Student
@Entity
@Table(name = "students")
public class Student extends User {
private int studentId;
public Student() {}
public Student(String username, String userId, String email, String passwordHash, LocalDateTime createdAt, int studentId) {
super(username, userId, email, passwordHash, createdAt);
this.studentId = studentId;
}
// Getter, Setter, toString 생략
}
3. 자식 클래스: Instructor
@Entity
@Table(name = "instructors")
public class Instructor extends User {
private String majorSubject;
public Instructor() {}
public Instructor(String username, String userId, String email, String passwordHash, LocalDateTime createdAt, String majorSubject) {
super(username, userId, email, passwordHash, createdAt);
this.majorSubject = majorSubject;
}
// Getter, Setter, toString 생략
}
4. 자식 클래스: Admin
@Entity
@Table(name = "admins")
public class Admin extends User {
private String position;
private String department;
public Admin() {}
public Admin(String username, String userId, String email, String passwordHash, LocalDateTime createdAt, String position, String department) {
super(username, userId, email, passwordHash, createdAt);
this.position = position;
this.department = department;
}
// Getter, Setter, toString 생략
}
5. 실행 클래스: Application
public class Application {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa-lecture");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
LocalDateTime now = LocalDateTime.now();
// 엔티티 생성 및 저장
Student student = new Student("김학생", "student01", "student@example.com", "pass123", now, 20240001);
em.persist(student);
Instructor instructor = new Instructor("이강사", "instructor01", "instructor@example.com", "pass456", now, "컴퓨터 과학");
em.persist(instructor);
Admin admin = new Admin("박관리", "admin01", "admin@example.com", "pass789", now, "시스템 관리자", "IT 부서");
em.persist(admin);
em.flush();
em.clear();
// 조회 및 메서드 호출
System.out.println("==== 사용자 정보 조회 ====");
Student foundStudent = em.find(Student.class, student.getId());
System.out.println("조회된 학생: " + foundStudent);
foundStudent.login();
// 나머지 조회 코드 생략
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
em.close();
emf.close();
}
}
}
JPA의 TABLE_PER_CLASS 전략을 적용하며 상속 구조를 설계해보았습니다.
