Programming
[OpenCSV] Output Stream에 OpenCSV 쓰는 방법
Dependency 추가 com.opencsv opencsv 5.6 Example Code public void downloadCsv(HttpServletResponse response) throws IOException { // 출력 파일명 : 한글 깨짐 방지를 위해 UTF-8 인코딩 String outputFileName = URLEncoder.encode("테스트.csv", "UTF-8"); response.setContentType("text/csv;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=\""+outputFileName +"\""); OutputStream outputStream = null..
![[Spring Data JPA] 유연한 조회 API만들기(Specification)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FbdYkbN%2FbtrJAH4VqpR%2FAAAAAAAAAAAAAAAAAAAAADs_Sf34kBzJMn9AJMaiV1FCFIko39YlKGwakkWccxr8%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3DmPu%252B41FjQnCXU0knY%252BQS4sS4c2c%253D)
[Spring Data JPA] 유연한 조회 API만들기(Specification)
저번 포스터에서 Query를 사용하는 여러가지 방법에 대해서 알아 봤습니다. 데이터를 조회하는 API를 구현할 때, 다양한 검색 조건을 처리할 수 있어야 합니다. 이렇게 유연하게 처리할 수 있게 도와주는 JPA Specificcation에 대해서 알아봅시다. 1. JPA Specification 이란? JPA Spectification은 DB 쿼리의 조건을 Spec으로 작성하여 요청할 수 있게 해줍니다. 다양한 조건이 계속 추가 될 수록 Spec으로 관리하게 되면 코드가 깔끔해지고 유지보수가 좀 더 용이해집니다. 2. Specification 구현 준비 JPA Specification을 구현하기 위해서는 Repository에 JpaSecificationExecutor를 추가로 상속 받아야합니다. publ..
![[Spring Data JPA] Query를 사용하는 여러가지 방법](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FWhn6t%2FbtrJwubRF1U%2FAAAAAAAAAAAAAAAAAAAAAGhpALNQ25-EMlo9onku4JFvQzCqQOy42DSUcWBQfVpc%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3Dx%252F4hKgkeM4AQGqUsdg14AHxLEiY%253D)
[Spring Data JPA] Query를 사용하는 여러가지 방법
Spring Data JPA에서 Query를 사용하는 방법은 여러가지가 있습니다. 1. Query Method 2. @Query 어노테이션 3. Query by Example 이제 각각 쿼리 사용 방법의 예제 코드를 보면서 어떻게 사용하는지 알아보겠습니다. 1. Query Method 일반적으로 JPA에서는 쿼리 메소드를 사용하여 쿼리를 만들 수 있습니다. 우리는 앞서 DB에 쿼리 요청을 하기 위해서 Repository 인터페이스를 만들었습니다. Repository에 메소드를 작성함으로써 정의된 메소드에 따라 쿼리를 자동으로 만들어서 요청 할 수 있게 됩니다. public interface MemberRepository extends JpaRepository { // MEMBER 테이블의 name col..
[Spring Security] 두개의 로그인 페이지(Multiple Login Pages)
Spring Boot 프로젝트 진행 중 두개의 로그인 페이지(User, Admin)를 각각 구현해야 하는 이슈가 발생해서 정리하고자 합니다. 1. Maven Dependencies 추가 org.springframework.boot spring-boot-starter-security 2.7.2 org.springframework.boot spring-boot-starter-web 2.7.2 org.springframework.boot spring-boot-starter-test 2.7.2 org.springframework.security spring-security-test 5.7.2 마지막 버전 확인 spring-boot-starter-security spring-boot-starter-web spri..
![[Spring Data JPA] FetchType - 즉시 로딩(EAGER)과 지연 로딩(LAZY)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2Fb8mLg6%2FbtrIT878fck%2FAAAAAAAAAAAAAAAAAAAAAOh6i0TT5wTE32WaOePJgqZOuF1nKnvSWermF7JXb16Q%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3D26O0CwhE3v8NcgS0IdgAdMB1F0M%253D)
[Spring Data JPA] FetchType - 즉시 로딩(EAGER)과 지연 로딩(LAZY)
즉시 로딩 : @ManyToOne(fetch = FetchType.EAGER) 지연 로딩 : @ManyToOne(fetch = FetchType.LAZY) JPA JOIN에는 두 가지 로딩 방법이 존재합니다. 연관관계를 가지는 객체를 조회할 때 즉시 로딩할지, 필요할 때 로딩할지에 따라 즉시로딩(EAGER), 지연로딩(LAZY)를 선택할 수 있습니다. 이전 JPA 연관관계 매핑 포스팅에서 사용한 예제 코드로 fetch를 설명하겠습니다. 시나리오 1. 테이블은 회원(Member)와 팀(Team)이 있습니다. 2. 회원(N) : 팀(1) 관계로 다대일 다중성을 가지고 있습니다. 즉시 로딩(FetchType.EAGER) @Entity public class Team { @Id @GeneratedValue pr..
![[Spring Data JPA] 양방향 순환참조 문제 및 해결방법](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FpFr0K%2FbtrIKmUj5J3%2FAAAAAAAAAAAAAAAAAAAAALqcFeq6V2nP-gto7IY2Ax4R_Eh4i2Ox_tZN4LDjeddD%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3DO2akKgzoI8TxzxVE%252Fz8aTeFBbEo%253D)
[Spring Data JPA] 양방향 순환참조 문제 및 해결방법
양방향 순환참조 문제 양방향 연관관계를 가진 두 객체가 서로를 참조하고 있어 무한히 서로의 정보를 조회하는 문제 Spring Boot에서 Rest API를 구현할 때 @ResponseBody 어노테이션을 사용하고, 응답 값으로 양방향 연관관계를 가진 객체를 반환하는 과정(JSON 형태로 변환)에서 순환 참조가 계속 발생해 stackoverflow가 발생하는 큰 문제점이 발생하였습니다. 아래는 예제 코드입니다. @Entity public class Team { @Id @GeneratedValue private Long id; private String name; // 양방향 @OneToMany(mappedBy="team") List members; } @Entity public class Member { ..
![[Spring Data JPA] JPA 연관관계 매핑(JOIN)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FbgYrfg%2FbtrIJVCncRd%2FAAAAAAAAAAAAAAAAAAAAAIHVswAQCKRZJz724R5QVi4QGe9XcrrLbe1QVWS5LYH2%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3D73t%252FOVe9YMLOVgT%252F%252F4Sd25D6Mk4%253D)
[Spring Data JPA] JPA 연관관계 매핑(JOIN)
연관관계 매핑이 필요한 이유 팀(Team)과 회원(Member)가 일대다의 관계를 가지는 연관관계일 때 예시 코드 팀과 회원의 객체 클래스 코드 @Entity public class Team { @Id @GeneratedValue private Long id; private String name; } @Entity public class Member { @Id @GeneratedValue private Long id; private String name; @Column(name = "team_id") private Long teamId; } 팀과 회원을 조회하는 코드 // 1번 ID를 가지는 회원 찾기 Member member = em.findById(1); // 회원의 TeamId로 팀 찾기 Long ..
![[Spring Data JPA] JPA 주요 어노테이션(Annotation)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FcXsTgR%2FbtrIFH441eM%2FAAAAAAAAAAAAAAAAAAAAAH-cuE968hUIxCp6Lwwkz8lDdfMKQA0XGDxT-CwGyBvy%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3DUuBgBwrKnOEbBsYVZ7xPWRVvwQs%253D)
[Spring Data JPA] JPA 주요 어노테이션(Annotation)
JPA에는 어노테이션을 통해 여러가지 설정을 할 수 있다. 어떤 어노테이션들이 있는지 정리해보자. Entity 관련 @Entity @Table(name = "member") public class Member { @Id @GeneratedValue(startegy=GenerationType.IDENTITY) private Integer id; @Column(name="member_name") private String memberName; @Enumerated(value=EnumType.STRING) private RoleType role; @Column(name="created_time") @Temporal(value=TemporalType.TIMESTAMP) private LocalDateTime c..