JPA로 DB 연결
- bootbasic 프로젝트를 생성한다.
![](https://velog.velcdn.com/images/yongseok0419/post/fd742894-557f-4aee-8e63-bfbf4a152d3f/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/bcc27d3c-1d2e-4480-adff-d62af1538d44/image.png)
-
Spring Boot 의 기본 버전 설정과 DB와 연결하기 위한 Spring Data JPA, MySQL Driver, Developer Tools > Lombok에 체크한다.
-
Spring Boot Version은 2.6.10이고 Spring Boot에서 Web을 사용하기 위해 Spring Boot DevTools와 Spring Web에 체크를 해주어야한다.
![](https://velog.velcdn.com/images/yongseok0419/post/223bbbd5-b753-441c-947d-0bab3f40057b/image.png)
- JPA로 DB에 연결하기 위해 체크해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/da73cc36-117b-4281-b29a-76269d950dae/image.png)
** JPA 모듈을 사용하게되면 Connection Pool과 DB 연결을 자동으로 해주는데, 다만 프로젝트 실행 시 DB 연결이 반드시 선행작업이 되어야한다.
- DB는 MySQL을 사용하기때문에 자바와 MySQL을 연결해주는 Driver에 체크한다.
![](https://velog.velcdn.com/images/yongseok0419/post/6716e364-3801-4606-aefe-42f51f62a557/image.png)
- Vo를 만들 때 @(어노테이션)으로 쉽게 Getter, Setter, ToString 등을 만들기 위해 체크해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/2b50e142-3633-4721-8f75-357dff3a15e0/image.png)
- Selected된 것을 확인하고 Finish 버튼을 클릭한다.
![](https://velog.velcdn.com/images/yongseok0419/post/5b1c6108-d61e-44e7-898d-25269c20550e/image.png)
- application.properties 에 DB에 연결하기위한 driver, url, username, password를 입력해주어야한다.
![](https://velog.velcdn.com/images/yongseok0419/post/780cf45a-009a-4d61-a503-25227482c0f5/image.png)
- MySQL의 Workbench를 이용하여 DB생성과 계정을 생성하고 모든 권한을 부여해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/4b8cc720-7eee-4842-a4d8-ac7a64459bee/image.png)
- 만든 계정으로 Workbench에 Connection Card를 추가한다.
![](https://velog.velcdn.com/images/yongseok0419/post/4fb71e17-5253-40b6-a620-34db904a4443/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/c6cd9e77-2410-469e-927b-80daaed80978/image.png)
- application.properties 에 username과 password를 수정해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/6b79c340-b4a4-47f9-a891-3dcd04aa3be4/image.png)
** 여기까지해주면 JPA 모듈이 데이터베이스와 자동으로 연결해준다.
- DB에 연결이 되었는지 확인해보자.
![](https://velog.velcdn.com/images/yongseok0419/post/a9d0e203-758b-4a19-a65a-639d1ef47bdd/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/6fda9d2e-fea1-4e79-9800-c3d1a76fc26c/image.png)
JSP vs Thymeleaf (JSP)
![](https://velog.velcdn.com/images/yongseok0419/post/3a490ae9-1ecf-4b11-a009-dae827b40f84/image.png)
-
spring-boot-starter-web 에 포함된 tomcat 은 JSP 엔진을 포함하고 있지 않다. jsp 파일은 Springboot 의 templates 폴더안에서 작동하지 않는다. 그래서 jsp를 적용하기 위해서는 아래와 같은 의존성을 추가해야한다.
-
https://mvnrepository.com/ 로 이동해서 검색창에 embed를 입력한다.(Tomcat Embed Jasper를 클릭한다.)
![](https://velog.velcdn.com/images/yongseok0419/post/dfa6c3ba-54e8-426a-9fdd-866ea313503f/image.png)
- Spring Boot의 내부 Tomcat과 버전을 맞추기위해 버전을 확인한다.
![](https://velog.velcdn.com/images/yongseok0419/post/66cad2e7-66e7-477f-9aa1-d2541b647fdd/image.png)
- 해당 버전의 Gradle 을 복사해서 build.gradle의 dependencies에 추가해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/62487244-735b-4171-abec-e6a3640b22c8/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/d9b392f8-a229-46e1-a474-ebceeb491d48/image.png)
- 마찬가지로 jstl을 사용하기위해 build.gradle의 dependencies에 추가해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/f10a38bd-2de5-45d3-be95-df7a834bf846/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/64229f37-ed76-4174-b42f-cbbfec79d2a2/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/a8e7fb1e-1412-4a91-8258-ca00fc1bcfde/image.png)
** 라이브러리를 추가할 때 version을 적어주지않으면 Spring Boot가 알아서 버전을 맞춰서 다운로드해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/e8e24495-db34-4d05-bf9f-b57b20e74e8f/image.png)
- 필요한 라이브러리를 추가하게되면 Gradle을 Refresh 해주어야한다.
![](https://velog.velcdn.com/images/yongseok0419/post/589d0632-8b46-4ab5-8c87-156970696fa9/image.png)
** jar 파일이 잘 받아졌는지는 확인하려면 Explorer 퍼스펙티브에 Project and External Dependencies에서 꿀단지 모양의 아이콘이 하얗게 들어왔다면 잘 받아진것이다.
![](https://velog.velcdn.com/images/yongseok0419/post/ac88d5ce-f046-42a8-960c-fad4cb312922/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/fbf840e8-73d1-4976-a791-a8d24d4aa4ad/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/8ed41fe7-aaf2-4c23-a8ad-3ef9db9a6a8c/image.png)
- Spring에서 servlet-context.xml에 InternalResourceViewResolver 는 컨트롤러가 지정한 뷰 이름으로 부터 실제로 사용될 뷰를 선택.
- 컨트롤러가 지정한 뷰 이름 앞뒤로 prefix 프로퍼티와 suffix 프로퍼티를 붙인 값이 실제로 사용될 자원의 경로가 됨.
![](https://velog.velcdn.com/images/yongseok0419/post/2a2b256a-5fc3-48d5-baea-1d706a95a2d7/image.png)
- 위의 그림과 같이 Spring에서 ViewResolver가 하는 역할을 SpringBoot 에서도 해주어야한다.(application.properties 파일)
![](https://velog.velcdn.com/images/yongseok0419/post/d689c0d5-646d-4113-8bcb-52e3fcec7651/image.png)
- SpringBoot에서 View를 강제적으로 만들어보자.
- SpringBoot의 초기 프로젝트는 src 폴더아래에 main 폴더밖에 없기때문에 main 폴더아래에 webapp/WEB-INF/views/home.jsp 파일까지 만들어준다.
![](https://velog.velcdn.com/images/yongseok0419/post/6511356f-ad9e-4fde-88d3-9bc9a97934bf/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/02b0d148-24e2-4f3c-ae49-3a2d17865ab0/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/56a82ac0-e77a-4001-a85c-4d29cfee5b66/image.png)
- ViewResolver 에게 "home"을 리턴해줄 HomeController를 만든다.
![](https://velog.velcdn.com/images/yongseok0419/post/40207e75-1a66-42e9-81f3-c08422ff70ff/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/c7267740-94e5-4d91-86ad-c5a75461c99d/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/1b2deeec-ca80-4773-9d70-957eff85bd43/image.png)
- jsp page가 잘 뜨는지 확인해보자.
![](https://velog.velcdn.com/images/yongseok0419/post/5b5fe95b-e7a6-4756-9ef4-9b1671279655/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/b5c35813-f643-4534-b047-05dbf96dcfa6/image.png)
여기까지가 Spring Boot에서 jsp 를 view 사용하는 방법이었다.
JSP vs Thymeleaf (Thymeleaf)
- JSP에서 사용했던 ViewResolver 주석처리한다.
![](https://velog.velcdn.com/images/yongseok0419/post/b9480455-0eeb-4b63-97bf-cfefb6906c37/image.png)
- src/main 폴더 아래에 만들어두었던 webapp/WEB-INF/views/home.jsp 모두를 삭제한다.
![](https://velog.velcdn.com/images/yongseok0419/post/188a1b43-892b-415c-a2c0-6b5f94af40ef/image.png)
- build.gradle 에 추가했던 jar 파일들을 주석처리한다.
![](https://velog.velcdn.com/images/yongseok0419/post/2c5860a7-1e8a-4487-9ec4-9cf99c10ba37/image.png)
- 이제 다시 중앙레파지토리에 가서 입력창에 thymeleaf를 입력한다.
- Spring Boot Starter Thymeleaf를 클릭한다.
![](https://velog.velcdn.com/images/yongseok0419/post/ceb8cecf-1166-4090-8ca9-56585fee96d2/image.png)
- 버전은 지울꺼니까 버전은 아무거나 클릭한다.
- gradle(short) 로 복사해온다.
![](https://velog.velcdn.com/images/yongseok0419/post/733ad68c-22d5-41b0-a8ac-c94c921f4327/image.png)
- 타임리프 모듈을 build.gradle의 dependencies 안에 붙여넣기한다.
![](https://velog.velcdn.com/images/yongseok0419/post/6cf16725-6585-4faf-b6bf-9bc911c8e55c/image.png)
- gradle을 refresh 해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/b98a2e7d-cac6-4356-8f17-b13580ce21cb/image.png)
- JSP에서와 같이 jar 파일이 제대로 받아졌나 확인한다.
![](https://velog.velcdn.com/images/yongseok0419/post/f2c3ab1e-fcba-452e-b71e-88e94bc9547d/image.png)
- thymeleaf는 html 기반이기때문에 html 파일을 생성한다.
- html 파일 이름은 home.html 이다.
![](https://velog.velcdn.com/images/yongseok0419/post/42e9db53-fc20-43c3-9539-a39dc7698ca3/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/90811302-f29b-4806-97fd-981a3fc1a3e4/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/b1db349d-0c5e-4df4-817f-3b0ff9643b37/image.png)
- Controller는 JSP 를 view로 했을 때 만들어두었던 HomeController를 그대로 사용한다.
![](https://velog.velcdn.com/images/yongseok0419/post/8e6e15b6-e850-4445-8236-b53f52458742/image.png)
** 혹시나 페이지를 찾을 수 없다는 404 에러가 난다면 내부 Tomcat Server를 Stop and Start를 하거나 Restart를 해주고 브라우저에서 home.html로 이동해보자.
![](https://velog.velcdn.com/images/yongseok0419/post/487b4325-24f2-43df-8448-bf2253e18e04/image.png)
** Spring Boot Project 에서 타임리프 문법은 다음 게시글에서 올리겠다.
IOC Container
- 스프링에서 가장 중요한 컨테이너이다.
- 스프링 프로젝트에서 필요한 자바의 객체를 모두 IOC 컨테이너에 만들어놓는데, 여기서 객체를 우리는 bean이라 부른다.
(즉, 스프링의 동작방식은 IOC 컨테이너에 bean을 미리 생성하고 필요할 때 꺼내서 사용하는 방식이다.)
- IOC : Inversion of Control의 줄임말로 필요한 시점에 특정객체를 이용해서 자바단에 꺼내서 사용할 수 있고, bean 끼리는 DI(의존성 주입) 관계이다. 그래서 @Controller, @Service, @Repository가 모두 DI 관계이다.
- @Controller에서 Autowired로 @Service를 연결하고 @Service는 Autowired로 @Repository(Dao)와 연결하고 Dao는 DB와 연결한다.(의존성관계)
- 스프링에서는 servlet-context.xml 에서 bean 을 만들었었는데, 이를 자바의 객체라 부른다.
- 스프링부트에서는 xml 파일이 .java 파일로 바뀌고, 객체를 자바파일로 꺼내서 사용할 수 있도록 바뀌게 된다.(즉, 가독성이 훨씬 더 좋아진다.)
- 자바 파일을 생성하고 @(어노테이션)만 붙여주면 자동으로 빌드를 생성해준다.
- WebMvcConfigurer는 스프링부트에 내장되어있는 인터페이스이다.
- 클래스가 WebMvcConfigurer를 상속받아서 클래스가 역할을 할 수 있도록 만들어주면 된다.
- WebMvcConfigurer를 상속받은 클래스 안에서 @Bean(빈으로 등록)으로 사용하겠다고 선언을 해준다. 그러면 이 해당 파일을 읽어서 @Bean에 해당하는 것을 객체로 생성해준다.
![](https://velog.velcdn.com/images/yongseok0419/post/100cfebb-4a8a-42ba-84f6-6e630ccbf1ed/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/9deeb1e4-69de-41ab-a945-cbc1f744aba2/image.png)
bean을 생성해보자.
- com.simple.basic.config 패키지를 생성한다.
- WebConfig.java 파일을 생성한다.
![](https://velog.velcdn.com/images/yongseok0419/post/2057a94a-a8ce-4ced-af00-52044318404f/image.png)
- 클래스를 설정파일로 선언하기위해 클래스코드 위에 @Configuration 어노테이션을 붙인다.
- WebConfig 클래스는 WebMvcConfigurer 인터페이스를 상속받는다.
![](https://velog.velcdn.com/images/yongseok0419/post/c579a47a-9d9e-444a-aae3-3ad20e2aea1c/image.png)
** WebMvcConfigurer 인터페이스는 하나 예를들자면 스프링에서 servlet-context.xml 파일에서 bean 객체로 InternalResourceViewResolver 클래스가 브라우저의 url을 조각나져있는 경로들을 prefix(접두사)는 WEB-INF/viwes/ 두고, suffix(접미사)는 .jsp로 지정하여 Controller에서 리턴한 값을 실제 jsp의 파일이름과 동일하게 받아서 해당하는 jsp파일로 이동하게끔 해준다. WebMvcConfigurer 인터페이스의 기능은 엄청 많지만 하나의 예를들은 것이다.(필자는 스프링에서의 기본으로 설정한 기능들을 스프링부트에서도 사용할 수 있도록 일반클래스에 WebMvcConfigurer 인터페이스를 상속받음으로써 WebConfig 클래스에서 오버라이딩해서 WebMvcConfigurer의 기능들을 살짝씩 바꿔서 객체를 사용할 수 있다는것까지 이해하고 넘어간다.)
![](https://velog.velcdn.com/images/yongseok0419/post/a40aa992-eaf7-42af-8ae9-85f4a29313a0/image.png)
- 잘 동작되는지 내장되어있는 tomcat 서버를 재시작해서 bean 생성 문구가 출력되는지 확인한다.
![](https://velog.velcdn.com/images/yongseok0419/post/7f64f264-0f4b-42a6-813c-48a103d3c7ce/image.png)
Application Context의 참조
![](https://velog.velcdn.com/images/yongseok0419/post/d6b05c42-8396-4665-958e-316bf7783520/image.png)
-
ApplicationContext 객체는 자바로 정의된 것을 뽑을 수 있는 스프링부트에 IOC Container 안에 들어있는 값들을 참조할 수 있는 핵심적인 객체이다.(즉, IOC Comtainer 안에 들어있는 Bean 정보를 실제로 확인할 수 있다.)
-
WebConfig 클래스에서 ApllicationContext 객체를 사용해보자.
-
@Autowired는 필요한 의존 객체의 "타입"에 해당하는 Bean을 찾아 주입한다.(생성자, Setter, 필드)
그렇기때문에 ApplicationContext ctx = new ApplicationContext() 라고 생성하지 않아도 된다.
![](https://velog.velcdn.com/images/yongseok0419/post/5ecbc73b-ea74-4e12-96b1-4e14bcb0a3a1/image.png)
-
test 메서드 안에서 IOC Container 안에 들어있는 Bean 들의 숫자를 찍어보자.
![](https://velog.velcdn.com/images/yongseok0419/post/139334c3-7f8b-4b91-b614-6d4617d3cbf9/image.png)
- 어떠한 Bean이 들어있는지는 모르나 230개의 Bean이 들어있다는 것을 확인할 수 있다.
![](https://velog.velcdn.com/images/yongseok0419/post/16f362d1-ba22-43e7-9159-f61791a88ac6/image.png)
- HomeController 도 들어있는데, 진짜로 들어있는지 확인해보자.
- Bean의 홈컨트롤러 클래스는 HomeController 타입으로 반환이 된다.
![](https://velog.velcdn.com/images/yongseok0419/post/0d15c126-b4d2-4a5f-b85b-da33ca70c166/image.png)
- 이렇게 생성이 되어있는 것을 확인할 수 있다.
- 여기서 중요한것은 new라는 키워드가 없어졌다는 것이다.(스프링에서는 new 대신에 .getBean(xx.class)로 해당 클래스의 Bean을 뽑아올 수 있다.)
![](https://velog.velcdn.com/images/yongseok0419/post/d6a8a1b1-d1ef-4768-9ef0-44d325171d94/image.png)
- 홈컨트롤러 안에 들어있는 메서드도 확인이 가능하다.
![](https://velog.velcdn.com/images/yongseok0419/post/2b569603-3439-4b0c-8366-b98f640e21ff/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/f0f07aed-4b53-48be-9635-3bd50e0491c5/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/3ba1fdaf-13f9-41e8-b23a-466cf3185a38/image.png)
** 앞으로 사용할 메서드들은 IOC컨테이너에 Bean으로 다 만들어질 것이라는 것을 기억하자.
UtilComponent
- com.simple.basic.util이라는 패키지를 생성한다.
![](https://velog.velcdn.com/images/yongseok0419/post/9f43f929-56af-4d8c-bbac-85d0ef901088/image.png)
- 여기다가 UtilComponent라는 클래스를 생성한다.
![](https://velog.velcdn.com/images/yongseok0419/post/65237691-eb0e-4e5c-9cd6-2f2f0177fdf6/image.png)
- 유틸컴포넌트에 Bean으로 생성해주라는 어노테이션이 있는데 스프링에서 servlet-context.xml 파일에 component-scan이 읽게되는 어노테이션은 1.@Controller, 2.@Service, 3.@Repository, 4.@Component가 있다.
![](https://velog.velcdn.com/images/yongseok0419/post/3126aed5-a4f3-4ecd-88e0-bebbac246570/image.png)
- 그래서 직접적으로 @Controller,@Service,@Repository가 아닌 클래스를 Bean으로 만들어주기위해서는 @Component라고 클래스 위에 적어준다.
![](https://velog.velcdn.com/images/yongseok0419/post/7ee1d598-7a34-4ce2-b69d-c35ffbcc8c69/image.png)
- 여기다가 개별적인 또 다른 기능을 만들수도 있다. 예를들어서 util() 메서드를 만든다.
![](https://velog.velcdn.com/images/yongseok0419/post/02366688-1c00-4557-9479-29e06e0a06a2/image.png)
- 빈이 230개에서 231개로 1개 더 늘어난 것을 확인할 수 있다.
![](https://velog.velcdn.com/images/yongseok0419/post/485493be-3671-4fb5-a620-c04e94acdf1e/image.png)
- Util 메서드를 WebConfig 클래스에서 실행해보자.
![](https://velog.velcdn.com/images/yongseok0419/post/614438e7-7b52-43fa-8441-b68e7e2fc965/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/f0b8cf1e-ff24-4797-b696-237c037dd46a/image.png)
- 어노테이션으로 Bean을 만들어내는 방법이 아닌 고전적인 방법으로 직접생성해내는 방법도 있다.
- UtilComponent 클래스의 @Component를 주석처리해보자. 당연히 UtilComponent 클래스가 없다고 에러가 날것이다.(그렇게되면 Bean으로 만들어지지않았기때문에 IOC Container 안에 존재하지않기때문이다.)
![](https://velog.velcdn.com/images/yongseok0419/post/87da0692-23a1-49be-a00c-75374ec2679b/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/d807d659-8623-4556-90cc-5d15d589dea8/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/c6ba62c9-0836-4d60-81f1-3df4987338d1/image.png)
- WebConfig 클래스에 test()안에 만들었던 UtilComponent 안에 메서드를 확인했던 코드도 주석처리하자.
![](https://velog.velcdn.com/images/yongseok0419/post/4c7c5326-2e48-4a71-b3af-ee7eda6671c8/image.png)
- 두번째 방법은 WebConfig 클래스 안에서 직접 생성한다.
- 반환유형을 UtilComponent로 하고 utilComponent()라는 메서드를 만들자.
- 리턴에 new UtilComponent()를 써서 객체를 직접생성하고 반환해주는것이다.
![](https://velog.velcdn.com/images/yongseok0419/post/7b6100c9-da52-4eef-987b-52ffdaa49f22/image.png)
- 스프링에서 보았었던 14번 그림을 스프링부트에서는 13번의 그림처럼 바뀌어 들어가는것이다.
![](https://velog.velcdn.com/images/yongseok0419/post/b19258cc-e9d9-4a6d-aef9-31db1b4028b9/image.png)
- 그렇기때문에 아래그림과 같이 스프링부트에서는 빈으로 생성하고 바로 util 메서드를 호출해서 사용할 수 있게되는 것이다.
![](https://velog.velcdn.com/images/yongseok0419/post/42a342c7-bb46-4b3d-b657-5dcbfab33251/image.png)
![](https://velog.velcdn.com/images/yongseok0419/post/b655afb3-3170-4707-987f-cb6cd028224a/image.png)
@Value 어노테이션으로 application.properties에 값을 참조하는 방법
- WebConfig 클래스에 url 변수를 만든다.
![](https://velog.velcdn.com/images/yongseok0419/post/03168467-ad42-4bc0-bcd1-5ef6f108f47a/image.png)
- application.properties에서 아무경로나 적어보자.
![](https://velog.velcdn.com/images/yongseok0419/post/6fd93c50-157a-421f-a3d2-dabcbe99f39a/image.png)
- Value라는 어노테이션으로 application.properties에 있는 값을 참조할 수 있다.
![](https://velog.velcdn.com/images/yongseok0419/post/f2a4b574-33d4-4323-8d01-19db051dca0d/image.png)
- 밑에 있는 test()메서드 Bean에서 값을 찍어보자.
![](https://velog.velcdn.com/images/yongseok0419/post/3bcf5c32-5791-4a93-92ea-51bb2e861744/image.png)