빌드 자동화 시스템 : 자바 코드를 설정에 맞도록 자동 빌드(작성한 소스코드를 실행 가능한 jar 파일로 변경
build시, build/libs/프로젝트명.jar 생성
여러 대의 컴퓨터 또는 장비(라우터, 스위치 등등)가 서로 연결되어 정보를 주고 받을 수 있는 기술
- 정보를 주고 받기 위해서는 IP주소, 서브넷 마스크, 게이트웨이 등의 정보를 설정하고, 네트워크 프로토콜을 이용하여 통신



application programming interface : 다른 소프트웨어 시스템과 통신하기 위해 따라야 하는 규칙
일종의 약속, 컨벤션 -> 서로 약속한 방식으로 API요청을 보내면, 그에 맞는 응답을 보내주는 형식
- Representational State Trasfer(REST)는 API 동작 방식에 대한 조건을 부과하는 소프트웨어 아키텍처
- REST 아키텍처 스타일을 따르는 API를 통칭 REST API
- REST 아키텍처를 구현하는 웹 서비스를 RESTful 웹 서비스
- 즉, http를 준수하며 잘 설계된 것을 RESTful 하다고 표현
- HTTP(Hypertext Transfer Protocol)의 메소드
- GET / POST / PUT / DELETE 등등 ...
Tomcat은 동적인 처리를 할 수 있는 웹서버를 만들기 위한 웹 컨테이너
Apache Tomcat이란? Apache와 Tomcat이 합쳐진 형태로 정적인 데이터 처리와 동적인 데이터 처리를 효율적으로 진행

개발에서 발생할 수 있는 버그를 찾아내기 위한 코드
Lombok은 자바 프로젝트에 필수적인 메서드/생성자 등을 자동 생성해줌으로써 코드를 절약하도록 도와주는 라이브러리
@Getter / @Setter / @AllArgsConstructor / @NoArgsConstructor / @RequiredArgsConstructor (final이 붙은 필드)
- Spring 관련 설정을 하는 파일
- DB 연결 시 DB의 정보를 제공
- application.yml: properties보다 계층 구조 확인 용이, 가독성 UP

MVC 패턴은 소프트웨어를 구성하는 요소들을 분리함으로써, 코드의 재사용성과 유지보수성을 높이고, 개발자 간의 협업을 용이하게 한다. 따라서, MVC 패턴을 적용하여 구조를 잘 설계하는 것이 중요하다.
Spring Web MVC는 Servlet API를 기반으로 구축된 웹 프레임워크. 중앙에 있는 DispatcherServlet이 요청을 처리하기 위한 공유 알고리즘을 제공하는 Front Controller 패턴을 중심으로 설계
Servlet(서블릿)은 자바를 사용하여 웹 페이지를 동적으로 생성하는 서버 측 프로그램 혹은 그 사양을 의미
1. 사용자가 브라우저를 통해 서버에 HTTP Request(API)를 요청
2. 요청을 받은 Servlet 컨테이너는 Request와 Response 객체를 생성
3. 설정된 정보를 통해 어떤 Servlet에 대한 요청인지 확인
4. 해당 Servlet에서 service 메서드를 호출한 뒤, 브라우저의 요청 Method에 따라 doGet 혹은 doPost 등의 메서드를 호출
5. 호출한 메서드들의 결과를 그대로 반환하거나 동적 페이지를 생성한 뒤, Response 객체에 응답을 담아 브라우저에 반환
6. 응답 완료 후, Servlet 소멸
@RestController
public class HelloController {
@GetMapping("/api/hello") // Handler mapping
public String hello() {
return "Hello World!";
}
}
// API path와 Controller 메서드가 매핑된 것을 의미
// @Controller 어노테이션이 있는 클래스를 생성한 뒤, 메서드를 구현하여 요청에 해당하는 로직 처리
// return 값을 DispatcherServlet 전달
<정리>
Dispatcher(배달부)Servlet은 요청과 응답 객체를 가진 채, 매핑된 정보에 따라 Controller로 이동, 해당 로직을 수행하고, ViewResolver에 등록된 정보에 따라 로직의 return 값을 View로 전환하여 Client로 전달
@ResponseBody // View로 보내지 않고, 순수 데이터를 전송할 경우 사용

서버단에서 모든 데이터를 처리하고, html/css/js 파일을 반환하는 방식도 존재.
But! 최근에는 프론트와 백이 나뉘면서, 느슨한 결합 방식을 채택
요청에 맞는 특정 데이터만 반환 (JSON형태의 데이터 반환 多)
기본적인 html 파일 요청을 제외하고는, JSON 데이터를 요청하는 API를 통해 브라우저에서 html을 조작하여 반영하는 방식 사용
.html 파일을 반환@RestController
@RequestMapping("/response/rest")
public class ResponseRestController {
// [Response header]
// Content-Type: text/html
// [Response body]
// {"name":"Robbie","age":95}
@GetMapping("/json/string")
public String helloStringJson() {
return "{\"name\":\"Robbie\",\"age\":95}";
}
// [Response header]
// Content-Type: application/json
// [Response body]
// {"name":"Robbie","age":95}
@GetMapping("/json/class")
public Star helloClassJson() {
return new Star("Robbie", 95);
}
}
JSON 데이터 구조를 처리해주는 라이브러리.
- 자바의 객체를 Json으로, Json타입의 String 값을 Object로 전환 가능
- Spring 3.0 버전 이후로, Jackson 라이브러리 지원
- 객체를 return하면, 라이브러리에 의해 자동으로 변환되지만 직접 변환도 가능
@Test
@DisplayName("Object To JSON : get Method Need")
void test1() throws JsonProcessingException {
Star star = new Star("Robbie", 95);
ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper
String json = objectMapper.writeValueAsString(star); // 변환시 Getter 반드시 필요!
System.out.println("json = " + json);
}
@Test
@DisplayName("JSON To Object : 기본 생성자 & (get OR set) Method 필요")
void test2() throws JsonProcessingException {
String json = "{\"name\":\"Robbie\",\"age\":95}"; // JSON 타입의 String
ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper
Star star = objectMapper.readValue(json, Star.class); // 변환할 객체 명시
System.out.println("star.getName() = " + star.getName());
}
브라우저에서 서버로 HTTP 요청을 보낼 때, 데이터를 함께 보낼 수 있다.
@Controller
@RequestMapping("/hello/request")
public class RequestController {
@GetMapping("/form/html")
public String helloForm() {
return "hello-request-form";
}
// [Request sample]
// GET http://localhost:8080/hello/request/star/Robbie/age/95
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
{
return String.format("Hello, @PathVariable.<br> name = %s, age = %d", name, age);
}
// [Request sample]
// GET http://localhost:8080/hello/request/form/param?name=Robbie&age=95
// @RequestParam 생략 가능 / 단, 값을 담지 않은 채 데이터를 넘길 경우 BadRequest 400
// 안 넘어올 경우에는 required = false로 설정 -> 단, 값이 null로 초기화된다.
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam(required = false) String name, int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
// [Request sample]
// POST http://localhost:8080/hello/request/form/param
// Header
// Content type: application/x-www-form-urlencoded
// Body
// name=Robbie&age=95
@PostMapping("/form/param")
@ResponseBody
public String helloPostRequestParam(@RequestParam String name, @RequestParam int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
}
?와 &를 사용해 추가

@Controller
@RequestMapping("/hello/request")
public class RequestController {
@GetMapping("/form/html")
public String helloForm() {
return "hello-request-form";
}
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
{
return String.format("Hello, @PathVariable.<br> name = %s, age = %d", name, age);
}
// @RequestParam 생략 가능 / 단, 값을 담지 않은 채 데이터를 넘길 경우 BadRequest 400
// 안 넘어올 경우에는 required = false로 설정 -> 단, 값이 null로 초기화된다.
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam(required = false) String name, int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
@PostMapping("/form/param")
@ResponseBody
public String helloPostRequestParam(@RequestParam String name, @RequestParam int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
// HTML에 설정된 name과 일치해지 않으면 null값이 들어오므로 주의
@PostMapping("/form/model")
@ResponseBody
public String helloRequestBodyForm(@ModelAttribute Star star) {
return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.name, star.age);
}
// 데이터가 넘어오는 갯수와 양이 많다면, 하나의 객체(클래스)로 만들어서 받는 편이
// 유지보수 측면에서 유리하다.
// 또한, 객체를 매개변수로 받는 경우에는 반드시 생성자를 통해 값들을 넣어주어야 한다.
// Lombok을 통해 Setter를 설정해주면, 생성자가 기본이어도 가능
// @ModelAttribute는 생략 가능
// 생략시 Spring이 알아볼 수 있는 이유.
// simpleValueType의 경우, RequestParam이 생략됐다고 판단
// 객체를 받는 경우, ModelAttribute가 생략됐다고 판단
@GetMapping("/form/param/model")
@ResponseBody
public String helloRequestParam(@ModelAttribute Star star) {
return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.name, star.age);
}
// HTTP body 부분에 JSON 형식으로 데이터가 넘어오는 경우,
// 매개변수 앞에 @RequestBody를 반드시 붙여주어야 한다.
@PostMapping("/form/json")
@ResponseBody
public String helloPostRequestJson(@RequestBody Star star) {
return String.format("Hello, @RequestBody.<br> (name = %s, age = %d) ", star.name, star.age);
}
}

Data Transfer Object: 데이터 전송 및 이동을 위해 생성되는 객체 의미
- 클라이언트에서 보내오는 데이터를 객체로 처리할 때 사용
- 서버의 계층 간의 이동에서 사용
- DB와의 소통을 담당하는 Java 클래스를 DTO로 변환한 후에 반환할 때도 사용
@RestController
@RequestMapping("/api")
public class MemoController {
// DB 대신 일단 사용
private final Map<Long, Memo> memoList = new HashMap<>();
@PostMapping("/memos")
public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
// RequestDto -> Entity
Memo memo = new Memo(requestDto);
// Memo Max ID Check
Long maxId = memoList.size() > 0 ? Collections.max(memoList.keySet()) + 1 : 1;
memo.setId(maxId);
// DB 저장
memoList.put(memo.getId(), memo);
// Entity -> ResponseDto
MemoResponseDto memoResponseDto = new MemoResponseDto(memo);
return memoResponseDto;
}
@GetMapping("/memos")
public List<MemoResponseDto> getMemos(){
// Map to List
List<MemoResponseDto> responseList = memoList.values().stream()
.map(MemoResponseDto::new).toList();
return responseList;
}
}
@PutMapping("/memos/{id}")
public Long updateMemo(@PathVariable Long id, @RequestBody MemoRequestDto requestDto){
// 해당 메모가 DB에 존재하는지 확인
if(memoList.containsKey(id)){
// id에 해당하는 메모 가져오기
Memo memo = memoList.get(id);
memo.update(requestDto);
return memo.getId();
} else {
throw new IllegalArgumentException("선택한 메모는 존재하지 않습니다!");
}
}
@DeleteMapping("/memos/{id}")
public Long deleteMemo(@PathVariable Long id){
// 해당 메모가 Db에 존재하는지 확인
if(memoList.containsKey(id)){
memoList.remove(id);
return id;
} else{
throw new IllegalArgumentException("선택한 메모는 존재하지 않습니다!");
}
}
데이터의 집합, 정보를 저장하고 관리하는 역할
DBMS : DataBase Management System, 데이터 베이스를 관리하고 운영하는 소프트웨어
RDBMS: Relational DBMS, 관계형 데이터베이스 -> 테이블 간의 Key값을 통해 서로 관계를 맺는 DB -> 테이블 간의 결합을 통해 데이터 조작이 용이하다.
Structured Query Language, RDBMS에서 사용되는 언어
국제 표준화 기구에서 SQL에 대한 표준을 정의하여 발표. 각 회사, 제품마다 약간의 차이가 존재
- DDL: Data Definition Language, 테이블이나 관계의 구조를 생성 (Create / Alter / Drop / Truncate)
- DCL: Data Control Language, 데이터 사용 권한 관리 (Grant / Revoke)
- DML: Data Manipulation Language, 데이터 검색, 수정, 삭제, 삽입 (Insert / Select / Update / Delete)

But! DB 서버를 변경한다면, 사용 방법이 다르기 때문에 로직을 전부 수정해야한다.

이를 해결한 JDBC 표준 인터페이스
JDBC = Java Database Connectivity, Java에서 제공하는 DB 접근 API
DB 회사들은 자신들의 DB에 맞도록 JDBC 인터페이스를 구현한 후, 라이브러리로 제공 (JDBC 드라이버)
