Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- WSLHostPatcher
- flyio
- react
- AWS
- Nextjs
- Delphi
- wsl2
- spring
- svelte
- beautifullsoup
- tessrect
- Markdown
- FastAPI
- reactnative
- TypeScript
- stepzen
- docker
- superbase
- dokerfile
- vmmem
- Expo
- Book
- springboot
- vercel
- 일의격
- oraclecloude
- kidznote
- shadcn-ui
- edgestore
- java
Archives
- Today
- Total
Blog
[Spring] 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 본문
스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Spring Boot / JPA(Java Peristence API) / Gradle / HIBERNATE / Thymeleaf
스프링 입문
스프링 핵심 원리
스프링 웹 MVC
스프링 DB 데이터 접근기술
실전! 스프링 부트
설정
- intelliJ 설치(SDKs | IntelliJ IDEA Documentation (jetbrains.com))
- java 11 설치(GitHub - ojdkbuild/ojdkbuild: Community builds using source code from OpenJDK project)
- Spring Initializr 에서 프로젝트 설정 및 샘플 다운로드
자바 11 사용하려면 spring boot 버전을 2..x.x 로 설정하자
3.x.x 버전부터는 자바 17 이상을 써야한다고 한다.
- 인텔리 제이로 build.gradle 열어서 프로젝트 오픈
- 프로젝트 구성 확인
- 프로젝트 폴더 main/test
- 실행하면 localhost:8080 으로 톰캣 서버가 올라간다
- 테스트할 때에는 settings>Build, Execution, Deployment>Gradle Build and run using&Ren tests using 을 IntelliJ IDEA 로 설정해준다
(속도 개선)
라이브러리
- 스프링부트 라이브러리
- 로그 활용 시 요즘에는 logback 과 jul-to-slf4j 를 주로 사용한다
- 테스트는 junit을 주로 쓴다 요즘에는 5버전을 쓴다,
sping-test 스프링과 통합해서 사용할 수 있는 라이브러리 - spring-boot-starter-web
- spring-boot-starter-tomcat: 톰캣(웹서버)
- spring-webmvc 스프링 웹 mvc
- spring-boot-starter-thymeleaf 타임리프 템플릿 엔진(View)
- spring-boot-starter(공통) 스프링부트 + 스프링 코어 + 로깅
- spring-boot
- spring-core
- spring-boot-starter-logging
- logback, slf4j
- spring-boot
- spring-boot-starter-test : 테스트 라이브러리
- junit: 테스트 프레임워크
- mockito: 목 라이브러리
- assertj: 테스크코드를 편하게 작성해주는 라이브러리
- spring-test: 스프링 통합 테스트 지원
View 설정
- welcome page 만들기
- static/index.html 을 올리면 welcome page 기능을 제공한다.
- spring.io spring boot 문서에서 welcome page 설정을 찾아서 설명을 확인한다
- hellospring 폴더에서 controller 폴더 만들고 HelloController.java 에 데이터 매핑 코드를 작성 후
resources/templates/hello.html 에서 매핑된 데이터를 불러올 수 있다.
package hello.hellospring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("hello")
public String hello(Model model){
model.addAttribute("data", "hello!!!!!!!");
return "hello"; // hello.html 을 실행해라
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요 ' + ${data}"> 안녕하세요 손님</p>
</body>
</html>
빌드
- 콘솔로 프로젝트 폴더 이동
- ./gradlew.bat build 실행(unix ./gradlew build)
이상 시 clean build 실행, 지우고 빌드함 - cd build/libs
- java -jar hello-spring-0.0.1-SNAPSHOT.jar
스프링이 실행된다.
스프링 웹 개발 기초
정적 컨텐츠
- static, public, resources 폴더에 넣어 그냥 사용
MVC 와 템플릿 엔진: 모델 뷰(템플릿) 컨트롤러 를 나눠 서버가 일정부분 화면을 그려줌
Controller
View
Model
컨트롤러를 선언하고 다시 템플릿 코드를 작성해본다
컨트롤러 선언 시 @RequestsParam(”name”) 을 지정하면 기본값이 필수 이기 때문에 url 에서 name 파라미터를 받아야한다.
ex) localhost:8080/hello-mvc?name=spring<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <p th:text="'안녕하세요 ' + ${name}">Hello empty</p> </body> </html>@GetMapping("hello-mvc") public String helloMcx(@RequestParam("name") String name, Model model){ model.addAttribute("name", name); return "hello-template"; }
API: 요청하면 JSON 으로 데이터를 클라이언트에 전달, 화면은 알아서 클라이언트가 그림
vue, react- Controller 에 @Response회
- @ResponseBody 사용시
Http 의 body 에 문자 내용을 직접 반환
viewResolver 대신에 HttpMessageConverter 가 동작
기본 문자처리 StringHttpMessageConverter
기본 객체처리 MappingJackson2HttpMessageConverter
byte 처리 등등 기타 여러 httpMessageConverter가 기본으로 등록되어 있
호
회원관리에제 - 백엔드
- 비지니스 요구사항 정리
- 컨트롤러: 웹 mvc 의 컨트롤러 역활
- 서비스: 핵심 비즈니스 로직 구현
- 리포지토리: 데이터베이스에 접근, 도메인 객체를 DB 에 저장하고 관리
- 도메인: 비즈니스 도메인 객
- 회원 도메인과 리포지토리 만들기
도메인 패키지에 단순히 id, name 으로 객체 설정
(windwos alt + insert = 제너레이)
문법보면 익숙해서 대강은 알겠는데, 정리된거라도 빠르게 한번 훑어야겠다 - 회원 리포지토리 테스트 케이스 작성
JUnit 도 자주 쓰지만 AssertJ 테스트 라이브러리르 주로 쓴다고 한다.
(DUnit 과 비슷하네, 테스트 라이브러리는 어디나 비슷비슷한듯 하다)
클래스를 정적 임포트 시키면 함수만 바로 쓸 수 있다.
(요떄 alt + enter 활용) - 회원 서비스 개발
MemberService 클래스 만든다
(ctrl + alt + v 리턴 코드 생성)
repository 는 데이터 중심적으로 service 는 비즈니스 중심적으로 코드를 나눈다 - 회원 서비스 테스트
생성자를 선언해 메모리디비(?)를 넣어 사용하는 방법으로 변경한다
(DI 디펜던시 인젝션)
스프링 빈과 의존관계
- 스프링 빈을 등록하고 의존관계 설정하기
- 회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 준비하자
MemberController 만들고 생성자를 추가해주자 - 생성자 위에 @Autowired 어노테이션을 선언하자
- @Controller, @Service, @Repository 각 클래스별로 선언, 정형화된 패턴이라함
- 컨트롤러 통해서 외부 요청 받고, 서비스에서 비즈니스 로직을 만들고, 리포지토리에서 데이터 저장하고
- 회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 준비하자
- 스프링빈을 등록하는 2가지 방법
- 컴포넌트 스캔과 자동 의존관계 설정
- @Autowired 같이 어노테이션 걸어주는 것
- 자바 코드로 직접 스프링 빈 등록하기
- 컴포넌트 스캔과 자동 의존관계 설정
- @Component 어노테이션이 있으면 스프링 빈으로 자동등록된다.
- @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컨포넌트 스캔때문이다.
- @Component 를 포함하는 다음 어노테이션도 스프링 빈으로 자동 등록된다.
- @Controller
- @Service
- @Repository
- 자바코드로 직접 스프링 빈 등록하기
- SpringConfig 파일 만들고, @Configuration 어노테이션을 걸어준다
- 그리고 내부 생성자 메소드 위에 @Bean 을 선언해준다
- @Autowried 와 자바코드로 직접 주입 하는 것 중 아무래도 Autowired 가 편한다
필드 주입 방식도 있지만 권장하진 않는다. - 회원 컨트롤러에 의존관계 추가
- 회원 웹 기능 - 홈 화면 추가
- HomeController 만들고 resource/template 에 home.html 을 만들어 연결해준다
- 회원 웹 기능 - 조회
- H2 데이터 베이스 설치
- H2 데이터베이스 설치
- 개발이나 테스트용도로 가볍고 편리한 DB, 웹 화면 제공
- https://www.h2database.com/
- h2 데이터베이스 버전은 스프링부트 버전에 맞춘다
- 권한 chmod 755 h2.sh
- 실행 ./h2.sh
- 데이터베이스 파일 생성 방법
- jdbc:h2:~/test (최초한번)
- ~/test.mv,db 파일 생성 확인
- 이후부터는 jdbc:h2:tcp://localhsot/~/test 이렇게 접속
- 순수 JDBC
- 스프링 통합 테스트
- @SpringBootTest
- 스프링 컨테이너와 테스트를 함께 실행한다.
- @Transcational
- 스프링 컨테이너에 이 어노테이션이 있으면, 테스트 시작 전에 트랜잭션을 시작하고 테스트 완료 후에 항상 롤백한다.
- @SpringBootTest
- 스프링 통합 테스트
- 스프링 JDBC Template
- 순수 jdbc 와 동일한 환경설정을 하면된다
- 스프링 jdbcTemplate과 Mybatis 같은 라이브러리는 JDBC API에서 본 반복코드를 대부분 제거해준다. 하지만 SQL은 직접 작성해야한다.
- 추가로 생성자가 하나면 @Autowired 를 생략해서 사용할 수 있다.
- JPA
- JPA는 기존의 반복코드는 물론이고, 기본적인 SQL도 JPA가 직접 만들어서 실행해준다
- JPA를 사용하면 SQL과 데이터 중심의 설꼐에서 객체 중심으로 설계로 패러다임을 전환을 할 수 있다.
- JPA를 사용하면 개발 생산성을 크게 높일 수 있다.
- build.gradle 에 jpa impliments 추가
- application.properties 에 spring.jpa.show-sql=true 를 추가
- application.properties 에 spring.jpa.hiberate.ddl-auto=none 추가
- none 으로한 이유는 이미 테이블이 만들어져 있기 때문에
- 도메인 클래스에 어노테이션을 걸어준다
- @Id, @GeneratedValue(strategy = GenerationType.IDENTITY)
- 스프링 데이터 JPA
- 스프링부트와 JPA만 사용해도 개발 생산성이 정말 많이 증가하고, 개발해야할 코드도 확연히 줄어듭니다. 여기에 스프링 데이터 JPA를 사용하면, 기존의 한계를 넘어 마치 마법처럼, 리포지토리에 구현 클래스없이 인터페이스 만으로 개발을 완료할 수 있습니다.
- 그리고 반복 개발해온 기본 CRUD 기능도 스프링 데이터 JPA가 모두 제공합니다.
- 스프링부트와 JPA라는 기반 위에 스프링 데이터 JPA라는 환상적인 프레임워크를 더하면 개발이 정말 즐거워집니다.
- 지금까지 조금이라도 단순하고 반복이라 생각했던 개발 코드들이 확연하게 줄어듭니다.
- 따라서 개발자는 핵심 비즈니스 로직을 개발하는데 집중할 수 있습니다.
- 실무에서 관계형 데이터베이스를 사용한다면 스프링 데이터 JPA는 이제 선택이 아니라 필수 입니다.
- 스프링 데이터 JPA 제공 기능
- 인터페이스를 통한 기본적인 CRUD 제공
- findByName(), findByEmail() 처럼 메서드 이름 만으로 조회 기능 제공
- 페이징 기능 자동 제공
- 참고: 실무에서는 JPA와 스프링데이터 JPA를 기본으로 사용하고 복잡한 동적쿼리는 Querydsl 이라는 라이브러리를 사용하면 된다. Querydsl을 사용하면 쿼리도 자바 코드로 안전하게 작성할 수 있고, 동적 쿼리도 편리하게 작성할 수 있다. 이 조합으로 해결하기 어려운 쿼리는 JPA가 제공하는 네이티브 쿼리를 사용하거나 앞서 학습한 스프링 JdbcTemplate를 사용하면 된다.
- H2 데이터베이스 설치
AOP
- AOP 가 필요한 상황
- 모든 메소드의 호출 시간을 측정하고 싶다면?
- 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern)
- 회원 가입 시간, 회원 조회 시간을 측정하고 싶다면?
- 코드를 일일이 넣자니…노동이다
- 문제
- 회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아니다.
- 시간을 측정하는 로직은 공통 관심 사항이다.
- 시간을 측정하는 로직과 핵심 비즈니스의 로직이 섞여서 유지보수가 어렵다
- 시간을 측정하는 로직을 별도의 공통 로직으로 만들기 매우 어렵다
- 시간을 측정하는 로직을 변경할 때 모든 로직을 찾아가면서 변경해야한다.
- AOP 적용
- AOP: Aspect Oriented Programming
- 공통관심사항 vs 핵심관심사항
- SpringConfig 에 Bean 으로 등록해도 되고, Aop 활용 클래스에서 @Component 로 설정해줘도 된다.
사람들이 스프링을 쓰는 이유가 있을 테니…열심히 찾아봐야겠다.