본문 바로가기
728x90

[JAVA]88

JAVA + Spring Data JPA 프로젝트에 다중 DB를 연결해보자. 💡 회사에서 새롭게 서버를 리팩터링 하는 도중에 하나의 프로젝트에 2개 이상의 데이터베이스를 연결해야 했다. 구글링을 통해 검색해 본 결과 생각보다 간단하게 할 수 있었다. 집에 와서 프로젝트를 간단하게 요약하여 재구성한 후 테스트를 진행해보려고 한다. Spring Initializr Spring Initializr 설정이다. 원래 H2로도 테스트를 해보고 싶었는데 못해서 의미가 없게 됐다. 프로젝트 패키지 구조 이 테스트의 핵심은 데이터베이스 2개를 하나의 프로젝트에 연결하고, 패키지 별로 사용 db를 나눈 후에 이를 기준으로 정상적으로 데이터베이스와 해당 패키지의 클래스가 연결되는지 보는 것이다. 따라서 db1(main), db2(second) 서버와 연결할 각각의 Entity와 Repository .. 2023. 5. 23.
slf4j, log4j, log4j2, logback & logging level 요약 정리 log(로그) 소프트웨어의 이벤트를 기록하는 것으로 일반적으로 동작 상태를 파악하여 문제가 발생했을 때 원인을 찾아내고 해결하기 위해 사용한다. 로그를 찍는 것은 디버그와 system.out에 비해 여러 장점을 가지고 있다. 상황별로 Level을 지정하여 Level에 맞는 메시지를 선택할 수 있다. 응용프로그램의 실행에 대한 흐름과 에러를 확인할 수 있다. 프레임워크를 이용하여 간단하고 쉬운 사용환경을 조성한다. 모듈 별로 유연한 메시지 출력이 가능하다. 자유로운 출력 위치 및 형식을 지원한다. SLF4J(Simple Logging Facade for Java) 다양한 로깅 프레임워크에 대한 추상화를 제공하므로 개발자가 로깅 프레임워크를 플러그인하고 변경할 필요 없이 상호 교환하며 사용할 수 있다. Lo.. 2023. 5. 22.
JPARepository의 findAll() 호출 시 하나의 Row가 중복해서 여러 개 들어가는 경우와 특정 컬럼만 null이 들어가 있는 경우 (엔티티명과 컬럼명의 올바른 매핑 방법) 💡 JPARepository의 findAll() 메서드를 호출해서 List에 저장을 했는데 하나의 Row 값만 잔뜩 들어가 있었다. DB를 확인해 보니 맨 위 첫 번째 row 데이터였는데 테이블의 row 수만큼 데이터가 들어가 있었기 때문에 매핑에 문제가 있음을 단번에 알아챘다. 테스트를 진행해 보자. 우선 로컬 DB에 테이블을 생성한다. 칼럼명을 짓고 더미 데이터도 적당하게 넣는다. test 데이터베이스의 test 테이블에 10개의 row가 들어가 있다. 엔티티를 생성한다. 나는 두 가지를 테스트할 예정이므로 일부러 id와 name 필드명 테이블의 칼럼명과 다르게 했다. seq는 test 테이블의 ID에 해당한다. name은 test 테이블의 USER_NAME에 해당한다. 나머지 칼럼명은 필드명과 일.. 2023. 5. 19.
WEB-INF에 대해 알아보기 WEB-INF(Web Information) Java 웹 애플리케이션에서 흔히 볼 수 있는 디렉터리이다. 말 그대로 "웹 정보"를 의미하며 응용 프로그램의 구성, 보안 및 리소스에 대한 정보를 제공하는 파일 및 디렉터리를 포함한다. classes 및 lib 디렉터리와 같은 다른 디렉터리와 함께 응용 프로그램 디렉터리를 포함한다. 일반적으로 WEB-INF 디렉터리는 클라이언트의 웹 브라우저에서 직접 액세스 할 수 없지만 대신 웹 컨테이너(Apache Tomcat)에서 애플리케이션을 관리하는 데 사용된다. WEB_INF 내 주요 파일 및 디렉터리 web.xml 웹 응용 프로그램의 구성을 지정하는 배포 설명자 파일이다. 여기에는 응용 프로그램에서 사용하는 서블릿, 필터 및 보안 제약 조건과 같은 정보가 포함된.. 2023. 5. 15.
JPQL - 벌크 연산 재고가 10개 미만인 모든 상품의 가격을 10% 올리려면 어떻게 해야 할까? JPA 변경 감지 기능으로 실행하려면 너무 많은 SQL이 실행될 것이다. 1. 재고가 10개 미만인 상품을 리스트로 조회한다. 2. 상품 엔티티의 가격을 10% 증가한다. 3. 트랜잭션 커밋 시점에 변경 감지가 동작한다. 변경된 데이터가 100건이라면 100번의 UPDATE SQL문이 실행될 것이다. 벌크 연산 쿼리 한 번으로 여러 테이블의 로우(엔티티)를 변경한다. executeUpdate()를 사용하여 연산할 수 있다. // 모든 Member의 나이를 20살로 변경한다. int resultCount = em.createQuery("update Member m set m.age = 20") .executeUpdate(); ex.. 2023. 5. 14.
JPQL - @NamedQuery 애너테이션 @NamedQuery @Entity @NamedQuery( name = "Member.findByUsername", query = "select m from Member m where m.username = :username") public class Member{ ... } List resultList = em.createNamedQuery("Member.findByUsername", Member.class) .setParameter("username", "회원1") .getResultList(); 미리 정의해서 이름을 부여해 두고 사용하는 JPQL이다. 정적 쿼리만 가능하다. 애너테이션, XML에 정의할 수 있다. 애플리케이션 로딩 시점에 초기화 후 재사용한다. 애플리케이션 로딩 시점에 JPA나 하이.. 2023. 5. 13.
JPQL - 엔티티 직접 사용 엔티티 직접 사용 JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용한다. 엔티티 직접 사용 - 기본 키 값 -- JPQL select count(m.id) from Member m -- 엔티티의 아이디를 사용 select count(m) from Member m -- 엔티티를 직접 사용 -> Member 엔티티의 기본 값인 id 값을 사용 -- SQL(위의 쿼리 둘 다 아래의 SQL이 실행된다.) SELECT COUNT(m.id) AS cnt FROM Member m 엔티티를 파라미터로 전달 String jqpl = "select m from Member m where m = :member"; List resultList = em.createQuery(jpql) .setPa.. 2023. 5. 13.
JPQL - 다형성 쿼리 TYPE 조회 대상을 특정 자식으로 한정할 수 있다. -- EX) Item 중에 Book, Movie를 조회해라. -- JQPL select i from Item i where type(i) IN (Book, Movie) -- SQL select i from i where i.DTYPE in ('B', 'M') TREAT(JPA2.1) 자바의 타입 캐스팅과 유사하다. 상속 구조에서 부모 타입을 특정 자식타입으로 다룰 때 사용한다. FROM, WHERE, SELECT(하이버네이트 지원)에서 사용할 수 있다. -- EX) 부모인 Item과 자식 Book이 있다. -- JPQL select i from Item i where treat(i as Book).auther = 'kim' -- SQL select i.. 2023. 5. 13.
728x90