목록전체 글 (518)
개발놀이터
*스프링 데이터 JPA에서의 QueryDSL 사용 사용자 정의 리포지토리를 사용하면 된다. (Spring Data JPA 참고) *QueryDSL 페이징 연동 + 스프링 데이터 JPA 1. 사용자 정의 리포지토리를 사용해서 구현체를 만든다. 2. 인자값으로 Pageable을 넘긴다. 3. queryFactory에서 offset메서드, limit메서드를 사용한다. // offset(pageable.getOffset()), limit(pageable.getPageSize()) 4. fetchResults()메서드로 최종연산을 마무리 짓는다. // 이유 : 페이징 처리를 하려면 전체 데이터 개수를 알고 있어야 하므로 5. total사이즈를 뽑는다. fetchResults()의 결괏값으로 QueryResults..
*프로젝션과 결과 반환 프로젝션 : select 대상 지정 -프로젝션 대상이 하나일 때 (단일 타입) List result = queryFactory.select(member.username).from(member).fetch(); 1. 프로젝션 대상이 하나면 타입을 명확하게 지정할 수 있음 2. 프로젝션 대상이 둘 이상이면 튜플이나 DTO로 조회 -프로젝션 대상이 둘 이상일 때 (튜플 사용) List result = queryFactory.select(member.username, member.age).from(member).fetch(); -사용방법 for (Tuple tuple : result) { String username = tuple.get(member.username); Integer ag..
*QueryDSL *QueryDSL 시작하기 build.gradle plugins에 id "com.ewerk.gradle.plugins.querydsl"version "1.0.10" 추가 build.gradle dependencies 에 implementation 'com.querydsl:querydsl-jpa' 추가 build.gradle에 맨아래에 def querydslDir = "$buildDir/generated/querydsl" querydsl { jpa = true querydslSourcesDir = querydslDir } sourceSets { main.java.srcDir querydslDir } configurations { querydsl.extendsFrom compileClass..
*람다식의 대한 고찰 람다식은 내 입장에서 다른 자바8 내용인 Optional과 LocalDateTime과 다르게 이해하기 상당히 까다로운 내용이었다. 내가 나름대로 이해한 내용을 기록으로 적어 남긴다 *stream API에서의 람다식 -사고의 시작 Map paramMap = new HashMap(); request.getParameterNames().asIterator().forEachRemaining(paramName -> paramMap.put(paramName, request.getParameter(paramName))); 람다식 안에 있는 paramName은 어떻게 구분하지? 자바 코드는 뭘 가지고 판단해서 paramName을 지정하는 것이지? request.getParameter(paramNa..
@Bean public AuditingAware auditorProvider() { return () -> { ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); String loginId = (String) attr.getRequest().getSessio().getAttribute("loginId"); if (loginId != null) { return Optional.of(loginId); } else { return Optional.of("Anonymous"); } } } *JPA Auditing AuditorAware Auditing에서 createdDa..
*Optional클래스 Optional 클래스는 Integer나 Double 클래스처럼 'T'타입의 객체를 포장해주는 래퍼 클래스(Wrapper class)이다. 따라서 Optional클래스는 모든 타입의 참조 변수를 저장할 수 있다. 이러한 Optional 객체를 사용하면 예상치 못한 NullPointerException 예외를 제공되는 메소드로 간단히 회피할 수 있다. 즉, 복잡한 조건문 없이도 널값으로 인해 발생하는 예외를 처리할 수 있게 된다. Optional 객체를 생성하기 위해서는 메서드를 사용해야 한다. Optional도 stream API 처럼 생성, 중개연산, 최종연산이 있다. *Optional 객체 생성 -Optional.of value가 null인 경우 예외가 터진다. 반드시 값이 있..
*스프링 데이터 JPA *공통 인터페이스 1. 인터페이스로 repository를 만든다 2. JpaRepository를 상속받는다. 상속 받을 때 public interface MemberRepository extends JpaRepository 이렇게 상속하는데 제네릭 첫번 째 부분은 매핑할 엔티티이고 두번 째는 해당 엔티티의 PK타입이다. *메소드 이름으로 쿼리 생성 메소드 이름을 분석해서 JPQL 쿼리를 실행해주는 기능으로 파라미터가 많지않을 경우 (한두개) 해당 기능을 사용하면 좋다. public List findByName(String name); 이렇게 선언만 해주면 스프링 데이터 JPA가 메소드 이름을 분석해 JPQL을 작성해준다. 위의 예제는 select m from Member m whe..
*Restful API 설계 앞으로 보여주는 예제들은 XToOne (ManyTonOne, OneToOne) 인 상황에서의 성능 최적화를 다루고 있다. *version1 = 응답 값으로 엔티티를 직접 외부에 노출함 @GetMapping("/api/v1/simple-orders") public List orderV1() { List all = orderRepository.findAll(new OrderSearch()); return all; } 문제점 1. 엔티티에 프레젠테이션 계층을 위한 로직이 추가된다. 2. 기본적으로 엔티티의 모든 값이 노출된다. 3. 응답 스펙을 맞추기 위한 로직이 추가된다. (@JsonIgnore, 별도에 뷰 로직 등등) 4. 실무에서는 같은 엔티티에 대해 API가 용도에 따라 다..
해당 에러의 원인은 종속성 관계에 있다. 두개의 객체가 서로 관계를 가지고 있다면 (1대1, 1대다) A인스턴스에 a1, a2 B인스턴스에 b 이렇게 두개의 인스턴스의 값을 디비에 집어 넣으려는데 a1을 넣으면 b가 자동으로 디비에 입력되고 a2를 넣으면 b가 또 디비에 입력되어서 b에 해당하는 엔티티를 디비에서 이미 가지고 있기 때문에 생기는 에러다. 보통 cascade를 ALL로 설정했을 때 생기는 일이며 cascade를 없애주면 해결되는 일이다. 나의 경우에는 for문을 돌면서 중복된것을 확인하고 확인함과 동시에 insert를 했기 때문에 생긴 해프닝이었다.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'announcementService' defined in file [D:\stock\stock\out\production\classes\project\stock\service\AnnouncementService.class]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Encountered invalid @Scheduled method 'compare': Only no-arg methods may be annotated with @Schedule..