Framework | Library | Tool 12

Gradle Multi-module 프로젝트에서 Build Logic 공유하기

Precompiled Script로 작성한 빌드 로직을 각 모듈에 적용하는 방법을 기록합니다.아래 예제 코드는 Kotlin dsl로 Spring Boot 프로젝트를 구성합니다.(Kotlin 2.0.0, Spring Boot 3.3.0, Gradle 8.7)buildSrc/build.gradle.kts내 빌드 스크립트에 외부 플러그인을 적용하려면 buildSrc/build.gradle.kts에서 외부 플러그인 의존성을 선언합니다.외부 의존성 내 플러그인에 적용하기// kotlin dsl plugin을 선언합니다. 따옴표가 아닌, 벡틱입니다.plugins { `kotlin-dsl` } repositories { mavenCentral() } dependencies { imp..

Homebrew 유용한 명령어

brew docs 브라우저에서 Homebrew의 온라인 설명서를 엽니다. brew install [formula] 패키지를 설치합니다. brew uninstall [formula] 패키지를 삭제합니다. brew list 설치된 패키지를 나열합니다. brew casks 설치할 수 있는 모든 cask 패키지가 나열됩니다. brew search [text] 패키지를 검색합니다. brew upgrade 설치된 패키지를 업그레이드합니다. brew cleanup [options] [formula|cask...] 오래된 잠금 파일과 이전 버전의 다운로드 파일을 삭제합니다. 옵션없이 명령을 수행하면 120일 이전의 파일을 삭제합니다. --prune=days : days 로 명시된 일자보다 오래된 캐시 파일을 삭제합니다..

Gradle 멀티 모듈 길라잡이

그래들 공식 문서에서 발췌. ├── gradle // Wrapper 파일을 위한 폴더 │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew // Gradle Wrapper 실행 파일 ├── gradlew.bat // Gradle Wrapper 실행 파일 ├── settings.gradle // 빌드 프로젝트 이름과 서브 프로젝트들이 정의되는 파일이다. ├── buildSrc // 빌드 스크립트가 정의된 디렉터리 │ ├── build.gradle // 빌드 로직의 Dependency가 정의되는 빌드 스크립트. 아래 커스텀 플러그인의 의존성을 관리할 수 있다. │ └── src │ └── main │ └── gro..

스프링의 AOP

애플리케이션은 핵심 기능과 부가 기능으로 로직을 구별할 수 있습니다. 핵심 기능 : 특정 객체가 제공하는 객체 고유의 기능 부가 기능 : 핵심 기능을 보조하는 기능. 로그, 트랜잭션 등 부가 기능은 주로 공통 로직입니다. 반복된 코드가 곳곳에서 나타납니다. 중복이 발생합니다. 변경이 일어날 때, 그만큼 수정해야 합니다. AOP 관점 지향 프로그래밍(Aspect-Oriented Programming) 반복되는 부가 기능을 모아 모듈화하는 개발방법입니다. 객체 지향 프로그래밍에서 발생하는 중복을 제한하는 보조 방법입니다. AspectJ Framework AOP를 구현한 프레임워크입니다. 오류 검사, 오류 처리, 동기화, 캐싱, 모니터링, 로깅 등을 모듈화할 수 있습니다. 스프링은 AspectJ의 문법을 차용..

JPA, JPQL(JPA Query Language) 요약

JPQL이란 JPA는 RDB 종류와 관계없이 작업을 처리해야함 JPQL(JPA Query Language) 등장 JPQL은 영속성 컨테이너에서 등록된 엔티티를 조작 JPQL은 영속성 컨테이너에서 관리 상태인 엔티티를 대상으로 검색 SQL과 구조와 사용법이 유사함 목록 질의 등을 수행하기 위해서 createQuery(String jpql) 메서드 사용 구조 SELECT 검색하려는 엔티티, 엔티티의 변수 목록 FROM 검색 대상인 엔티티, 엔티티 목록 WHERE 연산자, 함수 등으로 검색 제약 조건 표현 GROUP BY 검색 대상 엔티티를 특정 조건으로 그룹핑 HAVING 그룹핑된 엔티티에 제약조건 표현 ORDER 검색 결과에 대한 정렬 방식 JPQL 사용 주의사항 FROM 절에서는 검색 대상 엔티티의 이름..

JPA, 연관관계 매핑

RDB의 데이터들은 정규화 과정을 통해서 테이블 간 관계가 형성됨 JPA는 이러한 RDB의 관계를 객체를 통해서 표현해야함 연관관계 매핑은 RDB 테이블 간 관계를 Java 객체로 표현하는 것 연관관계 매핑을 통해서 불필요한 Join을 줄일 수 있고, 데이터 적재 시점을 결정할 수도 있음 테이블의 관계는 항상 양방향, 객체의 관계는 방향성이 있기 때문에 이러한 특성을 고려해야함 연관관계 매핑 기준 방향성 객체는 방향성이 존재(단방향, 양방향) 테이블은 항상 양방향 다중성 N:1, 1:N, 1:1, N:M @ManyToOne 엔티티 간 N:1 관계를 표현 N인 엔티티에서 반대편 엔티티 객체를 표현할 때 사용 주요 속성 optional 연관 엔티티의 필수 여부 false --> 연관 엔티티가 필수 false..

JPA, 영속성 컨텍스트와 상태 관리

영속성 컨텍스트란 엔티티를 관리해주는 컨테이너 엔티티는 다양한 상태로 존재함 엔티티의 상태를 기준으로 DB와 애플리케이션 사이에서 캐시의 역할을 수행 컨테이너에서 필요한 정보를 persistence.xml로부터 가져옴 entityManager를 생성할 때 자동으로 생성되며, entityManager의 메서드를 통해서만 접근할 수 있음 엔티티의 상태 생성(new) 비영속 상태 엔티티가 컨테이너에 등록되지 않은 상태 엔티티 객체는 컨테이너와 DB와 아무런 관련이 없음 관리(managed) 영속 상태 엔티티가 컨테이너에 등록된 상태 persist()에 의한 managed 실제 persist 메서드가 트랜잭션 안에서 이뤄져야 함 managed 상태의 엔티티를 수정하면 트랜잭션 종료시점에 update 처리가 이뤄..

JPA의 엔티티 매핑

JPA에서는 데이터베이스의 테이블과 객체를 annotation으로 연결합니다. 주요 에너테이션 @Entity 에너테이션이 명시된 클래스의 인스턴스를 엔티티로 식별합니다. 일반 자바 객체와 구별하는 에너테이션입니다. 해당 클래스는 @Id가 선언된 식별자 필드가 있어야 합니다. 에너테이션의 name 속성을 지정하지 않으면 JPA는 클래스 이름을 엔티티 이름으로 등록합니다. @Id 엔티티 객체의 식별자 필드를 지정합니다. JPA에서 엔티티 객체를 등록하기 위해서 반드시 식별자 필드가 있어야 합니다. @Table 엔티티 이름과 테이블 이름이 다를 경우, 해당 에너테이션으로 매핑할 테이블을 지정합니다. 속성 name : 매핑할 테이블을 지정합니다. catalog : DB 카탈로그를 지정합니다.(MySQL) sch..

Spring Triangle : 스프링을 지탱하는 원리

Dependency Injection Inversion of Control Portable Service Abstraction Dependency Injection 소개 의존성은 쉽게 이야기하면 new입니다. DI는 new를 사용하여 어떤 컴포넌트에 의존성을 주입하는 것입니다. DI 방법 의존성은 크게 2가지 방법으로 주입할 수 있습니다. Constructor Injection 컴포넌트를 생성할 때 컨테이너에 있는 의존성을 주입합니다. DI 시점을 파악할 수 있습니다. 권장되는 DI 방법입니다. Setter Injection 생성된 컴포넌트에 임의의 시점에 의존성을 주입합니다. DI 시점을 파악하기 어렵습니다. @Autowired와 @Resource Autowired 스프링 프레임워크 에너테이션 Type..

Thymeleaf에서 레이아웃 만들기

레이아웃 만들기 발번역입니당ㅠㅠ 개선하겠습니다! 템플릿 조각 정의 템플릿을 작성할 때, 레이아웃을 이루는 fragment는 th:fragment="조각이름"으로 선언합니다. © 2011 The Good Thymes Virtual Grocery 레이아웃에 th:insert="~{templatename :: fragmentname}"으로 삽입할 수 있습니다. fragment의 추가는 th:fragment, th:replace 둘 다 가능합니다. "~{templatename :: fragmentname}" == "templatename :: fragmentname" ... 아래와 같이 Th:fragment 속성 없이 id 값만으로도 호출할 수 있습니다. ... © 2011 The Good Thymes Virt..