💡 스프링부트 기본
📌 빌드도구
📌 스프링부트 프로젝트도구창 기본 설명
- src/main/java패키지 아래에는 자바 소스코드를 작성한다
- src/main/resources 디렉토리 아래에는 html,css,js,이미지 파일 등의 정적 리소스를 저장한다
- src/test/java 패키지 아래에는 테스트 코드를 작성한다
- src/main/resources/templates에서 뷰를 찾는다(thymeleaf기준)
- src/main/resources/application.properties라는 파일은 스프링부트애플리케이션 실행 시 사용하는 여러 가지 설정값들을 정의하는 파일이다
📌 Dependencies
- Lombok : 반복적인 getter/setter, toString과 같은 반복적인 자바 코드를 컴파일할 때 자동으로 생성해주는 라이브러리(프로젝트마다 setting > Build, Execution, Deployment > Compiler > AnnotationProcessors > Enable annotation processing 체크박스를 체크해줘야 사용가능하다)
- Thymeleaf : 서버에서 가공한 데이터를 뷰에 보여주기 위한 템플릿 엔진
- Spring Data JPA : JPA를 쉽게 구현할 수 있도록 도와주는 모듈. 엔티티를 만들고 나서 엔티티매니저를 직접 이용해 작성하지 않고 Data access object의 역할을 하는 repository 인터페이스를 설계한 후 사용하면 된다.
- MySQL Driver : MySQL 데이터베이스를 사용하기 위한 의존성
- H2 Database : 자바기반의 관계형 데이터베이스. 매우 가볍고 빠른 데이터베이스. 디스크기반의 데이터 저장과 메모리 내에 데이터를 저장하는 인메모리 데이터베이스기능을 지원한다. 테스트용데이터베이스로 많이 사용.
📌 어노테이션
- 클래스나 메소드, 변수 등을 선언할 때 ‘@’를 붙여서 사용한다
- 컴파일러에게 정보를 알려주거나 실행할 때 별도의 처리가 필요할 때 등 다양한 용도로 사용
@Value
: application.properties에서 설정해둔 애플리케이션의 값을 읽어와서 자바코드에서 사용할 때
@Controller
: 해당 클래스를 요청을 처리하는 컨트롤러로 사용할 때
@ResposeBody
: 자바 객체를 http응답 본문의 객체로 변환해 클라이언트에게 전송할 때
@RestController
: @Controller와 @ResposeBody를 합쳐놓은 어노테이션. html파일을 따로 만들지 않아도 문자열을 출력할 수 있다
@GetMapping
: 클라이언트의 요청을 처리할 url을 매핑할 때
- 엔티티 매핑 관련 어노테이션
@Entity
: 클래스를 엔티티로 선언. (Entity클래스는 반드시 기본키를 가져야하므로 @Id를 이용하여 id 멤버변수를 상품 테이블의 기본키로 설정한다)
@Table
: 엔티티와 매핑할 테이블을 지정
@Id
: 테이블의 기본키를 사용할 속성을 지정
@GeneratedValue
: 키값을 생성하는 전략 명시
@Column
: 필드와 컬럼 매핑
- Column 어노테이션 추가 속성 : 테이블 생성할 때 컬럼에는 다양한 조건들이 들어가는데 @Column 어노테이션의 속성을 이용하면 다양한 제약 조건(테이블에 매핑되는 컬럼의 이름, 문자열의 최대 저장 길이 등)들을 추가할 수 있다
- 추가 속성 종류 : name, unique(DDL), insertable, updatable, length, nullable(DDL), columnDefinition, precision, scale(DDL)
@Lob
: BLOG, CLOB 타입 매핑
- CLOB : 사이즈가 큰 데이터를 외부 파일로 저장하기 위한 데이터타입. 문자형 대용량 파일을 저장하는데 사용.
- BLOB : 바이너리데이터를 DB외부에 저장하기 위한 타입. 이미지, 사운드, 비디오 같은 멀티미디어데이터를 다룰 때 사용.
@Enumerated
: enum 타입 매핑
@Transient
: 해당 필드 데이터베이스 매핑 무시
@Temporal
: 날짜 타입 매핑
@CreationTimestamp
: insert 시 시간 자동 저장
@UpdateTimestamp
: update 시 시간 자동 저장
@CreateDate
: 엔티티가 생성되어 저장될 때 시간 자동 저장
@LastModifiedDate
: 조회한 엔티티의 값을 변경할 때 시간 자동 저장
@Autowired
: 각 상황의 타입에 맞는 IoC컨테이너 안에 존재하는 Bean을 자동으로 주입한다
- IoC : 스프링의 특징에는 제어의 역전(IoC)이 있다. 제어의 역전이란, 간단히 말해서 객체의 생성 및 제어권을 사용자가 아닌 스프링에게 맡기는 것이다. 지금까지는 사용자가 new연산을 통해 객체를 생성하고 메소드를 호출했다. IoC가 적용된 경우에는 이러한 객체의 생성과 사용자의 제어권을 스프링에게 넘긴다.
- Bean : 사용자는 직접 new를 이용해 생성한 객체를 사용하지 않고, 스프링에 의하여 관리당하는 자바 객체를 사용한다. 이 객체를 '빈(bean)'이라 한다.
@DisplayName()
: Junit5에 추가된 어노테이션으로 테스트 코드 실행 시 @DisplayName에 지정한 테스트명이 노출된다
📌 @Entity 어노테이션
- Entity클래스는 반드시 기본키를 가져야한다
- 기본키가 되는 멤버변수에 @Id 어노테이션을 이용하여 기본키로 설정한다
@GeneratedValue
어노테이션을 통해 기본키를 생성하는 전략은 총 4가지가 있다
GenerationType.AUTO
(default) : 데이터베이스에 의존하지않고 기본키를 할당하는 방법. JPA구현체가 IDENTITY,SEQUENCE,TABLE 생성 전략 중 하나를 자동으로 선택한다. 데이터베이스가 변경되더라도 코드를 수정할 필요가 없다
GenerationType.IDENTITY
: 기본키 생성을 데이터베이스에 위임
GenerationType.SEQUENCE
: 데이터베이스 시퀀스 오브젝트를 이용한 기본키 생성. @SequenceGenerator
를 사용하여 시퀀스 등록 필요.
GenerationType.TABLE
: 키 생성용 테이블 사용. @TableGenerator
필요
💡 JPA
📌 JPA
- ORM(Object Relational Mapping) : 자바객체와 관계형데이터베이스 사이를 매핑하는 역할을 반복하는 것을 막고, 패러다임의 불일치(객체를 데이터베이스에 넣기위해서는 SQL문을 통해 변환해야하고, 다시 꺼내오기위해서는 복잡한 SQL문을 작성해야한다는 단점)를 해결하기 위해 생긴 기술
- JPA(Java Persistence API) : 자바 ORM 기술에 대한 API 표준, 즉 인터페이스
- JAP 대표적인 구현체 : Hibernate, EclipseLink, DataNucleus, OpenJpa 등
- 자바 ↔ ORM(JPA) ↔ 관계형데이터베이스
- JPA사용 시 장점
- 특정 데이터베이스에 종속되지않는다
- 객체지향적 프로그래밍
- 생산성 향상
- JPA사용 시 단점
- 통계처리 같은 복잡한 쿼리 처리에 불리
- 성능 저하 위험
- 학습시간
📌 JPA동작방식
- 엔티티 : 데이터베이스의 테이블에 대응하는 클래스. @Entity가 붙은 클래스는 JPA에서 관리하며 엔티티라고 한다. 클래스 자체와 그 클래스로 생성한 인스턴스도 엔티티에 해당한다.
- 엔티티매니저팩토리 : 엔티티매니저를 관리, 생성(create)하는 주체. 애플리케이션 실행 시 한 개만 만들어짐.
- 엔티티 매니저 : 영속성 컨텍스트에 접근하여 엔티티에 대한 데이터베이스 작업을 제공합니다. 내부적으로 데이터베이스 커넥션을 사용해서 데이터베이스에 접근한다.
- 메소드 종류 : find()메소드 persist()메소드 remove()메소드 flush()메소드
- 영속성 컨텍스트 : 엔티티를 영구 저장하는 환경
- 예시 (상품 엔티티를 만들어서 영속성 컨텍스트에 저장 후 데이터베이스 반영하는 코드)
Item item = new Item();
item.setItemNm("테스트상품");
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persiste(item);
transaction.commit();
em.close();
emf.close();
-
엔티티 생명 주기
- 비영속, 영속, 준영속상태, 삭제상태 가 있다
- 애플리케이션과 데이터베이스 사이에 존재하는 영속성 컨텍스트라는 중간계층 덕분에 버퍼링, 캐싱 등을 할 수 있다는 장점이 있다
-
1차 캐시
-
동일성 보장
-
트랜잭션을 지원하는 쓰기 지연
-
변경 감지
💡 Repository
📌 Repository 설계
- JPA동작방식 예시에서 살펴본 것과 같이 JPA를 사용하기위해서는 엔티티매니저를 통해 엔티티를 저장해야한다. 하지만 Spring Data JPA는 엔티티매니저를 직접 이용해 코드를 작성하지 않아도 된다
- 그 대신 Data Access Object의 역할을 하는 Repository인터페이스를 설계한 후 사용하는 것이 좋다
- Repository인터페이스는 JpaRepository<A,B>를 상속받게 한다(제네릭타입 A:엔티티타입클래스, B:엔티티클래스의 기본키 타입)
- JpaRepository는 기본적인 CRUD 및 페이징 처리를 위한 메소드가 정의되어있다
- 메소드 종류 : 엔티티저장및 수정 save(), 엔티티 삭제 delete(), 엔티티 총 개수 반환 count(), 모든 엔티티 조회 findAll()
- 쿼리 메소드
- Repository 인터페이스에 메소드를 작성할 때,
find+(엔티티이름)+By+변수이름
로 작성한다 ( 엔티티이름은 생략가능 )
ex) findItemByItemNm 또는 findByItemNm
- 매개변수는 검색할 때 사용할 상품명 변수를 넘겨준다
💡 테스트환경
📌 테스트환경
- 코드 수정 이후 코드가 버그없이 제대로 동작하는지 확인하기 위해 테스트를 해야한다
- 유지보수 및 소스코드의 안정성을 높인다
- 테스트 환경의 경우 h2데이터베이스를 사용하도록 resources아래에 application-text.properties파일을 만들어 테스트환경을 위한 별도의 properties를 만든다
- h2데이터베이스
- 인메모리데이터베이스 기능을 제공
- 애플리케이션이 종료되면 데이터베이스에 저장된 데이터가 삭제된다
- 가볍고 빠르기때문에 테스트용 데이터베이스로 많이 사용한다