반응형
Mapping
매핑 어노테이션
객체와 테이블 : @Entity, @Table
기본키 매핑 : @Id
필드와 컬럼 매핑 : @Column
연관관계 매핑 : @ManyToOne, @OneToMany, @JoinColumn
필드와 컬럼을 매핑하기 위한 어노테이션
@Column : 컬럼 매핑
@Temporal : 날짜 타입 매핑
@Lob : BLOB, CLOB 타입 매핑
@Transient : 매핑하지 않을 특정 필드에 작성
@Enumerated : Enum 타입 매핑
@Access : JPA가 엔티티에 접근하는 방식을 지정
@Entity, @Table, @Id, @Column
/* 해당 클래스를 엔티티를 설정하기 위한 어노테이션
* 프로젝트 내 다른 패키지에 동일 엔티티가 존재한다면 식별을 위해 중복 되지 않는 name 지정
* ----주의사항----
* 1. 기본 생성자 필수 작성
* 2. final 클래스, enum(열거형), interface, inner class(클래스 안에 만들어진 내부 클래스)에서는 사용불가 // 엔티티가 될 수 없는 유형
* 3. 저장할 필드에 final 사용 불가 //테이블과 연관되서 저장할 수 있는 값으로 사용 못함*/
@Entity(name="Section01Member")
/* 매핑 될 테이블의 이름을 작성한다.
* 생략하면 자동으로 클래스 이름을 테이블의 이름으로 사용한다. */
@Table(name="TBL_MEMBER_SECTION01")
public class Member {
@Id
@Column(name="MEMBER_NO")
private int memberNo;
@Column(name="MEMER_ID")
private String memberId;
@Column(name="MEMBER_PWD")
private String memberPwd;
@Column(name="NICKNAME")
private String nickname;
@Column(name="PHONE")
private String phone;
@Column(name="EMAIL")
private String email;
@Column(name="ADDRESS")
private String address;
@Column(name="ENROLL_DATE")
private java.sql.Date enrollDate;
@Column(name="MEMBER_ROLE")
private String memeberRole;
@Column(name="STATUS")
private String status;
@Column 속성과 @Temporal
@Column 속성
@Column(name="PHONE", nullable=false, columnDefinition="varchar2(200) default '010-0000-0000'")
@Column(name="EMAIL", length=500)
@Temporal
- @Temporal(TemporalType.TIMESTAMP) : DATE + TIME으로 현재 날짜 및 시간이 나옴(기본 값)
- @Temporal(TemporalType.DATE) : Oracle에서는 TIMESTAMP 설정과 차이가 없음
- @Temporal(TemporalType.TIME) : 1970/01/01에 시간만 맞게 나옴
@Enumerated
@Entity 클래스 내에 필드 레벨에 @Enumerated 어노테이션 사용 가능
Enum 클래스를 활용하면 Enum에 속한 값만 DB에 저장할 수 있음
1. EnumType.ORDINAL
장점 : 데이터베이스에 저장 되는 데이터의 크기가 작다
단점 : 이미 저장 된 Enum의 순서를 변경할 수 없다
2. EnumType.STRING
장점 : 저장 된 Enum의 순서가 바뀌거나 Enum이 추가 되어도 안전하다
단점 : 데이터베이스에 저장 되는 데이터의 크기가 ORDINAL에 비해 크다
- Enum 클래스 생성
public enum RoleType {
ADMIN, MEMBER
//정의 된 순서대로 각각 0과 1이라는 상수 값이 부여되고, 이 값을 사용할 수 있다.
}
- Entity에 @Enumerated 사용
@Entity(name="Section04Member")
@Table(name="TBL_MEMBER_SECTION04")
public class Member {
/* memberRole을 String에서 enumType으로 변경한다. */
@Column(name="MEMBER_ROLE")
@Enumerated(EnumType.STRING) //enum의 문자 그대로를 사용한다는 의미(ADMIN, MEMBER)
@Enumerated(EnumType.ORDINAL) //enum의 상수 값을 사용한다는 의미(0, 1)
private RoleType memeberRole; //열거형 타입으로 선언
}
반응형
@Access
- @Access 어노테이션을 이용하여 접근 방식을 설정할 때 클래스 레벨과 필드 레벨에 설정 가능.
1. 클래스 레벨 클래스 레벨에 @Access를 적용하면 모든 필드에 대해 일괄적으로 적용 된다.
2. 필드 레벨 해당 필드의 접근 방식을 필드 접근으로 바꿀 수 있다.
@Id 어노테이션이 필드 레벨에 존재하는 경우 해당 필드는 @Access(AccessType.FIELD)이다.
3. 프로퍼티 레벨 Getter 메소드로 접근하는 프로퍼티 접근으로 바꿀 수 있다.
@Id 어노테이션이 프로퍼티 레벨에 존재하는 경우@Access(AccessType.PROPERTY)이다.
- @Access를 설정하지 않으면 @Id의 위치를 기준으로 접근 방식이 설정 됨.
- 클래스 레벨
@Entity(name="FieldAccessMember")
@Table(name="TBL_MEMBER_SECTION05_SUBSECTION01")
@Access(AccessType.FIELD) //클래스 레벨에 사용(getter 출력 안됨)
public class Member { }
- 필드 레벨
@Entity(name="FieldAccessMember")
@Table(name="TBL_MEMBER_SECTION05_SUBSECTION01")
public class Member {
@Access(AccessType.FIELD) //필드 위에 작성 가능(getter 출력 안됨)
@Id
@Column(name="MEMBER_NO")
private int memberNo;
@Access(AccessType.FIELD)
@Column(name="MEMER_ID")
private String memberId;
@Access(AccessType.FIELD)
@Column(name="MEMBER_PWD")
private String memberPwd;
@Access(AccessType.FIELD)
@Column(name="NICKNAME")
private String nickname;
public Member() {}
public Member(int memberNo, String memberId, String memberPwd, String nickname) {
super();
this.memberNo = memberNo;
this.memberId = memberId;
this.memberPwd = memberPwd;
this.nickname = nickname;
}
public int getMemberNo() {
System.out.println("getMemberNo()를 이용한 access 확인...");
return memberNo;
}
public void setMemberNo(int memberNo) {
this.memberNo = memberNo;
}
public String getMemberId() {
System.out.println("getMemberId()를 이용한 access 확인...");
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberPwd() {
System.out.println("getMemberPwd()를 이용한 access 확인...");
return memberPwd;
}
public void setMemberPwd(String memberPwd) {
this.memberPwd = memberPwd;
}
public String getNickname() {
System.out.println("getNickname()를 이용한 access 확인...");
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Override
public String toString() {
return "Member [memberNo=" + memberNo + ", memberId=" + memberId + ", memberPwd=" + memberPwd + ", nickname="
+ nickname + "]";
}
}
- Getter 메소드로 접근
@Access(AccessType.PROPERTY) //프로퍼티 레벨에 설정
public int getMemberNo() {
System.out.println("getMemberNo()를 이용한 access 확인...");
return memberNo;
}
public void setMemberNo(int memberNo) {
this.memberNo = memberNo;
}
public String getMemberId() {
System.out.println("getMemberId()를 이용한 access 확인...");
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberPwd() {
System.out.println("getMemberPwd()를 이용한 access 확인...");
return memberPwd;
}
public void setMemberPwd(String memberPwd) {
this.memberPwd = memberPwd;
}
public String getNickname() {
System.out.println("getNickname()를 이용한 access 확인...");
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Override
public String toString() {
return "Member [memberNo=" + memberNo + ", memberId=" + memberId + ", memberPwd=" + memberPwd + ", nickname="
+ nickname + "]";
}
}
- 다른 로직을 처리하거나 값을 검증하는 등의 추가 로직을 수행할 수 있기에 혼용 방식을 사용하기도 함.
@Entity(name="PropertyAccessMember")
@Table(name="TBL_MEMBER_SECTION05_SUBSECTION02")
public class Member{
@Id
@Column(name="MEMBER_NO")
private int memberNo;
@Column(name="MEMER_ID")
private String memberId;
@Column(name="MEMBER_PWD")
private String memberPwd;
@Column(name="NICKNAME")
private String nickname;
public Member() {}
public Member(int memberNo, String memberId, String memberPwd, String nickname) {
super();
this.memberNo = memberNo;
this.memberId = memberId;
this.memberPwd = memberPwd;
this.nickname = nickname;
}
public int getMemberNo() {
System.out.println("getMemberNo()를 이용한 access 확인...");
return memberNo;
}
public void setMemberNo(int memberNo) {
this.memberNo = memberNo;
}
public String getMemberId() {
System.out.println("getMemberId()를 이용한 access 확인...");
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberPwd() {
System.out.println("getMemberPwd()를 이용한 access 확인...");
return memberPwd;
}
public void setMemberPwd(String memberPwd) {
this.memberPwd = memberPwd;
}
/* 다른 값들은 모두 필드로 접근하지만 nickname 값만 getter로 접근하도록 설정*/
@Access(AccessType.PROPERTY)
public String getNickname() {
System.out.println("getNickname()를 이용한 access 확인...");
return nickname + "님";
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Override
public String toString() {
return "Member [memberNo=" + memberNo + ", memberId=" + memberId + ", memberPwd=" + memberPwd + ", nickname="
+ nickname + "]";
}
}
@Id 어노테이션의 위치(필드. getter 메소드)에 따라 @Access 방식이 결정 되며 이는 전역 설정이다.
클래스 레벨에 @Access 설정하는 것과 같다. 다만 두 가지 설정이 상충되는 경우 엔티티 매니저가 생성 되지 않을 수 있으니 유의한다. @Access(AccessType.PROPERTY) 설정을 getter 위에 지정하면 특정 필드만 getter 메소드로 접근 가능하며 값에 대한 검증 등 추가 로직이 필요한 경우 이렇게 혼용해서 사용할 수 있다.
반응형
'프로그래밍 > Spring & Spring boot' 카테고리의 다른 글
[Spring/JPA] Mapping (3) 연관 관계 매핑 (단반향, 양방향) (0) | 2022.09.26 |
---|---|
[Spring/JPA] Mapping (2) @SequenceGenerator , @TableGenerator, @Embeddable, @IdClass (0) | 2022.09.23 |
[Spring/스프링] JPA(Java Persistence API) (0) | 2022.09.23 |
[Spring/스프링] JUnit이란? (0) | 2022.09.20 |
[Spring/스프링] jQuery ajax , Fetch ajax(Simple string, JSON) (0) | 2022.09.20 |