목록전체 글 (531)
개발놀이터
본 포스트는 김영한님의 인프런강의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술을 보고 정리한 포스트입니다. 자세한 내용은 강의를 참고해주세요 *기본 객체들 타임리프는 기복 객체들을 제공한다. 1. ${#request} 2. ${#response} 3. ${#sesison} 4. ${#servletContext} 5. ${#locale} 그런데 #request는 HttpServletRequest객체가 그대로 제공되기 때문에 데이터를 조회하려면 request.getParameter("data")처럼 불편하게 접근해야 한다. 이런 점을 해결하기 위해 편의 객체도 제공한다. HTTP요청 파라미터 접근 ${param.paramData} HTTP세션 접근 ${session.sessionData} 스프링 빈 접..
단순히 이렇게 넣으면 될 줄 알았는데 이상하게 PathVariable이 넘어가는 것을 확인했다. 그래서 https://www.thymeleaf.org/doc/articles/standardurlsyntax.html 타임리프 문서를 확인해본 결과 괄호를 두개로 나누는 것이 아니라 콤마로 연결한다는 것을 알았다. 오늘의 교훈 : 문서를 잘 확인하자
InvalidPathException, NoViableAltException, SemanticException 이 세개가 동시에 떠서 굉장히 당황했다. 구글링을 해봐도 별다른 수확이 없었다. 그렇게 30분동안 내 코드를 뚫어져라 쳐다본 결과 굉장히 어이없는 실수였다. 그렇다 조인이 없다... 어이없어서 다신 실수하지 말자는 의미로 이렇게 글을 남긴다.
*스프링 데이터 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..