예제에 사용할 Notice테이블의 정보와 테이블안의 데이터다.
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "NOTICE")
@Table(name = "NOTICE")
public class Content {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long noticeId;
@Column(length = 100, nullable = false, updatable = true)
private String title;
@Column(length = 3000)
private String content;
@Column(length = 1000)
private String attachFile;
@ManyToOne
@JoinColumn(name = "CATEGORY_ID")
private Category category;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
@CreatedDate
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt = LocalDateTime.now();
@LastModifiedDate
@Column(name = "modified_at")
private LocalDateTime modifiedAt = LocalDateTime.now();
}
엔티티클래스명은 Content이지만 실제 DB의 테이블명은 notice이므로
@Entity와 @Table 의 name을 NOTICE로 지정했다.
@ManyToOne
@JoinColumn(name = "CATEGORY_ID")
private Category category;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
이것은 Content 엔티티클래스가 Category 엔티티클래스 및 Member 엔티티클래스와 다대일 관계를 형성한다는 것을 의미한다.
그리고 각각 엔티티의 ID(CATEGORY_ID, MEMBER_ID) 로 조인하는 것을 의미한다.
public interface ContentRepository extends JpaRepository<Content, Long> {
}
Content 엔티티로 사용할 JpaRepository 인터페이스다.
JpaRepository<Content, Long> 의 첫번째 제네렉파라미터는 해당 JpaRepository의 엔티티클래스를 의미하고 두번째 제네릭파라미터는 이 엔티티클래스의 식별자멤버(@Id)의 타입을 의미한다.
테이블에서 특정컬럼을 where 조건으로 두고 데이터를 조회한다.
위의 그림처럼 title이라는 컬럼을 조건으로 데이터를 조회하려할 때는 JpaRepository에 아래와 같이 입력한다.
이와같이 입력하면 title 이라는 컬럼을 조건으로 데이터를 가져온다.
이렇게 위 워크밴치와 같은 조건으로 요청을 하면 워크밴치의 요청결과와 같은 데이터를 조회하게 된다.
[
{
"noticeId": 1,
"title": "제목1",
"content": "내용내용1",
"attachFile": "첨부1",
"memberId": 1,
"categoryId": 1,
"createdAt": "2023-07-03T15:58:30",
"modifiedAt": null
},
{
"noticeId": 5,
"title": "제목1",
"content": "내용내용5",
"attachFile": "5첨부2",
"memberId": 3,
"categoryId": 1,
"createdAt": "2023-07-03T16:00:02",
"modifiedAt": null
}
]
where에서 2개의 컬럼조건으로 데이터 조회한다.
위와 같이 where 절에서 2개의 컬럼 조건을 쓸 경우 JpaRepository에 아래와 같이 입력한다.
By+첫번째조건멤버+And+두번째조건멤버
이런식으로 메서드명을 적는다.
이렇게 같은 조건으로 데이터요청시 아래와 같이 결과를 얻는다.
[
{
"noticeId": 5,
"title": "제목1",
"content": "내용내용5",
"attachFile": "5첨부2",
"memberId": 3,
"categoryId": 1,
"createdAt": "2023-07-03T16:00:02",
"modifiedAt": null
}
]
특정컬럼값 하나를 조회한다.
위와 같이 attach_file 컬럼값 하나를 조회하고자 할 때
아래와 같이 작성한다.
find+조회할멤버+By+조건멤버
이런식으로 작성한다.
[ ※ 예제에서는 이미 row개수가 1개만 나올 것을 알아서 Content find... 로 작성했는데,
원래는 2개 이상 row 개수가 나올 수 있으므로 List< Content > find... 식으로 작성해주는게 맞다. ]
이렇게 메서드명을 작성하고 요청을 하면 이 findAttachFileByNoticeId메서드를 요청을 한 Content 타입 변수에는 AttachFile멤버에 select결과데이터가 들어간다. AttachFile내용을 요청했으므로 AttachFile 외 멤버는 Null 상태일 것이다.
그래서 서비스단계에서 아래와 같이 작성하여 해당멤버만 get하여 반환하거나...
public String findContentsBySpeci(long noticeId){
Content findAttachFile = contentRepository.findAttachFileByNoticeId(noticeId);
String result = findAttachFile.getAttachFile();
return result;
}
별도처리를 하여 반환해주면 된다.
이런 방법으로 요청을 하면 "첨부2" 라는 결과를 얻는다.
JpaRepository에서 메서드시그니처 말고도 JPQL방법으로 조회할 수도 있다.
메서드 위에 @Query 입력 후 value 값에는 쿼리내용을 적는다.
먼저 from 절에 사용할 테이블(NOTICE)를 적고 alias(n)을 적는다. 그리고
select 문에 alias(n)을 적고 where 절에는 alias(n)의 멤버noticeId을 조건으로 사용하기 위해 n.noticeId 라고 적는다.
메서드시그니처의 파라미터 (@Param("noticeId") long noticeId) 는,
long noticeId 파라미터 값을 JPQL에서 @Param()의 명칭의 값으로 사용하겠다는 것을 의미한다. 다시 말해서 long noticeId 값이 @Param("noticeId") 의 noticeId 로 전달되고 이 noticeId는 다시 JPQL의 :noticeId 로 전달된다.
nativeQuery = false 의 경우는 false 가 default이므로 이 문장을 생략할 수 있다.
이는 SQL문으로
select n.* from notice n where n.notice = :noticeId 와 동일한다.
JPQL을 사용하여 Like 조건으로 데이터를 조회한다.
위와 같이 데이터를 조회하고자 할 경우 아래와 같이 작성한다.
where like가 '%첨부2%' 인 것처럼
JPQL에도 like %:attachFile% 이런식으로 적어준다.
조건을 '첨부2'로 시작하는 값을 조회할 경우
:attachFile%
조건을 '첨부2'로 끝나는 값을 조회할 경우
%:attachFile
이렇게 사용할 수도 있다.
요청을 하면 아래와 같은 결과를 얻는다.
[
{
"noticeId": 2,
"title": "제목2",
"content": "내용내용2",
"attachFile": "첨부2",
"memberId": 2,
"categoryId": 1,
"createdAt": "2023-07-03T15:59:01",
"modifiedAt": null
},
{
"noticeId": 4,
"title": "제목4",
"content": "내용내용4",
"attachFile": "6첨부2텐",
"memberId": 2,
"categoryId": 2,
"createdAt": "2023-07-03T15:59:46",
"modifiedAt": null
},
{
"noticeId": 5,
"title": "제목1",
"content": "내용내용5",
"attachFile": "5첨부2",
"memberId": 3,
"categoryId": 1,
"createdAt": "2023-07-03T16:00:02",
"modifiedAt": null
},
{
"noticeId": 7,
"title": "제목222",
"content": "내용내용222",
"attachFile": "첨부222",
"memberId": 2,
"categoryId": 2,
"createdAt": "2023-07-04T23:16:44",
"modifiedAt": "2023-07-04T23:16:44"
}
]
조회데이터에 대해서 컬럼별로 출력순서를 정한다.
위 결과를 보면 category_id 오름차순으로 우선정렬하고, category_id가 동등할 경우 2차적으로 member_id 내림차순으로 정렬했다.
위 정렬방법을 구현할 경우 아래와 같이 작성한다.
find...+OrderBy+첫번째정렬대상멤버+Asc(오름차순) 혹은 Desc(내림차순)+(이후 정렬이 필요한 경우 멤버+Asc 혹은 Desc 로 작성해나감)
이렇게 입력하면 1차적으로 CategoryId 로 오름차순정렬하고 2차적으로 MemberId로 내림차순정렬을 한다.
멤버를 적을 때 CategoryId, MemberId로 적지 않고 Category, Member 로 적었는데, 이는 Content 엔티티 클래스에서 category, member 로 멤버를 선언했고 category_id, member_id를 joincolumn으로 두었기 때문에 categoryId, memberId 대신 멤버인 category, member 로 적은 것이다.
이렇게 요청한 결과를 보면 아래와 같다.
[
{
"noticeId": 5,
"title": "제목1",
"content": "내용내용5",
"attachFile": "5첨부2",
"memberId": 3,
"categoryId": 1,
"createdAt": "2023-07-03T16:00:02",
"modifiedAt": null
},
{
"noticeId": 2,
"title": "제목2",
"content": "내용내용2",
"attachFile": "첨부2",
"memberId": 2,
"categoryId": 1,
"createdAt": "2023-07-03T15:59:01",
"modifiedAt": null
},
{
"noticeId": 1,
"title": "제목1",
"content": "내용내용1",
"attachFile": "첨부1",
"memberId": 1,
"categoryId": 1,
"createdAt": "2023-07-03T15:58:30",
"modifiedAt": null
},
{
"noticeId": 4,
"title": "제목4",
"content": "내용내용4",
"attachFile": "6첨부2텐",
"memberId": 2,
"categoryId": 2,
"createdAt": "2023-07-03T15:59:46",
"modifiedAt": null
},
{
"noticeId": 7,
"title": "제목222",
"content": "내용내용222",
"attachFile": "첨부222",
"memberId": 2,
"categoryId": 2,
"createdAt": "2023-07-04T23:16:44",
"modifiedAt": "2023-07-04T23:16:44"
},
{
"noticeId": 3,
"title": "제목3",
"content": "내용내용3",
"attachFile": "첨부3",
"memberId": 1,
"categoryId": 2,
"createdAt": "2023-07-03T15:59:28",
"modifiedAt": null
}
]