Spring Boot는 웹 프레임워크로 웹페이지를 만드는데 매우 편리한 도구이다. VScode에서 설치를 하고 구현을 한다. 처음에 프로젝트를 만들때는 빈 폴더에 Spring Boot Project를 만들어야한다. 다른 파일이 있다면 오류가 날 수 있다. Spring Boot 버전과 JAVA 버전도 맞춰서 잘 설정해야한다. 또한 기본적으로 Lombok이랑 Spring Boot web web은 추가해주는 것이 좋다. 외부 라이브러리도 추가할 수 있지만, 처음 프로젝트를 만들 때 넣어주는 것이 좋다. 추가로 넣으려고 한다면 build.gradle이나 pom.xml파일에서 dependencies 부분에 추가해주면 될 것이다.
\basic\src\main\java\com\example\basic
basic은 아마 프로젝트 만들 때 설정한 이름일 것이다. 마지막 baisc 폴더 안에 controller 폴더를 만들고 그 안에 BasicController.java라는 파일을 만들어 java 코드를 짜면 된다. java 파일을 만들었으면 어노테이션(annotation)을 추가하여 주면된다. 이 어노테이션은 import와 비슷한데 자동으로 코드도 넣어주는 것으로 보인다. 코드를 자동으로 추가해주지만 화면에는 안보이기에 더 깔끔하다. 우선 우리는 Controller를 사용할 것이기 때문에 @RestController를 public class BasicController 위에 넣어주면 기능이 추가된다.
다음으로는 http 링크에 들어가면 함수가 실행되게 만드는 코드이다. 함수를 선언하는 부분위에 @GetMapping("/something")을 설정하면 주소에 들어가면 바로 함수가 진행된다. 기본적으로 코드를 실행하면 생기는 주소는 http://localhost:8080이다. 우리는 mapping을 /something으로 해주었기 때문에 http://localhost:8080/something으로 들어가게 되면 지정해준 함수가 자동으로 실행된다.
@Slf4j
@RestController
public class BasicController {
@GetMapping("/hello")
public String getHello(){
String msg = "Hello Wrold";
System.out.println("msg: " + msg);
log.info("msg: " +msg);
return msg;
}}
코드에서는 hello로 설정했기 때문에 localhost:8080/hello로 들어가게 되면 화면에 return되는 값인 msg가 출력된다. println과 log.info를 사용했기 때문에 터미널에는 "msg: "+ msg가 출력된다. log.info와 println은 같은 역할을 하지만 log.info가 자원을 덜 먹기때문에 이것을 사용하면된다. 사용하는 방법은 @Slf4j라는 어노테이션을 추가해주면된다.
@GetMapping을 사용하여 주소를 통해 변수를 받아 올 수 있다. 아래와 같이 {param1}/{param2} 처럼 {}을 사용하여 변수를 받는다. 받은 변수는 @PathVariable이라는 어노테이션을 사용하여 함수 내부에서 변수로 사용 할 수 있다. localhost:8080/variabl2/hi/hello 라고 입력을 해준다면 터미널에서는 hi가 출력되고 web페이지에서는 hello가 출력될 것이다.
@GetMapping("variable2/{param1}/{param2}")
public String getHeollo3(@PathVariable String param1,@PathVariable String param2){
log.info("url로부터 받은"+param1);
return param2;
}
이것을 활용하여 쿼리문을 작성 할 수 있다. 쿼리는 질문하다라는 뜻으로 사용되고 주소에서 질문을 하고 값을 받을 수 있다. 예를들어 아래와 같은 코드가 있다면 key라는 질문을 받고 그것에 해당하는 value값을 반환한다. web 주소는 다음과 같다.
localhost:8080/query?key=value 로 설정할 수 있다. key=까지는 고정이고 뒤에 value값에 원하는 변수를 입력 할 수 있다. @RequestParam이라는 어노테이션을 사용하는데 key대신 다른 값을 사용할 수 있다. query?name=cheol2라고 입력한다면 key대신 name이라고 코드에 입력해줘야하고 출력값은 cheol2가 될 것이다.
localhost:8080/query?key=value
@GetMapping("/query")
public String getQuery1(@RequestParam String key){
log.info("쿼리는 질의문입니다!");
return key;
}
DTO도 설정해줄 수 있다. DTO는 data transfer object 데이터를 변환해준다. 이것은 getter와 setter를 사용하여 아래와 같이 구현할 수 있다. @ModelAttribute를 통해 BasicDto의 함수를 가져온다. BasicDto는 basic폴더에 model이라는 폴더를 만들고 그안에 BasicDto.java 파일을 만들었다. 아래와 같이 @getter를 쓰면 getter함수가 만들어지고 @setter를 치면 setter함수가 만들어진다. constructor는 생성자이고 Tostring은 string으로 바꿔주는 함수이다. 말했다싶이 어노테이션은 코드가 보이지는 않지만 내부적으로 전부 처리됐다.
//localhost:8080/dto1?name=name1&email=email1
@GetMapping("/dto1")
public String getDto1(@ModelAttribute BasicDto dto){
return dto.toString();
}
package com.example.basic.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class BasicDto {
private String name;
private String email;
}
혹시 잘 실행이 안된다면 파일 위치를 잘 설정했는지를 확인해보자

최상단에 폴더명이 1.2.Springgradle/basic로 되어있는데 원래는 basic만 나오게끔 폴더를 열어줘야한다. 프로젝트 하나만 나오게 해야한다고 들었다. 지금은 블로그 정리를 위해 모든 폴더를 띄워뒀기때문에 저렇게 나온다.
Dispatcher-Servlet처리 과정이다
우선 Filter는 Client에서 입력을 하면 모든 data가 Filter를 거쳐가기때문에 모든 입력에대해 반응을한다. Interceptor는 이것과 달리 특정한 데이터 입력에 대해서만 반응하게 만들 수 있다.
Filter보다 Interceptor를 많이 쓴다고는 하지만 두가지 모두 구현해보려한다.
위에서 했던 것 처럼 프로젝트를 새로 만든 다음 main에 있는 basic폴더에서 config라는 폴더를 새로 하나 만든다. 그리고 그안에 filter와 interceptor라는 폴더를 각각 생성한다. filter폴더 안에는 BasicFilter.java라는 파일을 만들고 interceptor에는 BasicInterceptor.java라는 파일을 만든다.
우선 BasicFilter.java 파일이다. 상단에 있는 import들은 따로 쳐줄 필요가 없다. 안쪽에 있는 class를 형성하고 어노테이션을 설정하다보면 자동으로 생성된다. 우선 @Component를 사용하여 bean을 만들어 준다. Spring bean은 객체라고 보면되는데 자세한 내용은 차차 알게 될 것으로 보인다. 상속을 받아야하니 implements Filter를 치면 알아서 Filter에 대한 코드가 형성이 된다. 우리는 이번에 Filter가 어디서 작용하는지만 확인할 것이기 때문에 filter를 지날때마다 터미널에 "filter 실행완료"라는 출력이 실행되게 한다.
package com.example.basic.config.filter;
import java.io.IOException;
import org.springframework.stereotype.Component;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class BasicFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
log.info("filter 실행완료");
chain.doFilter(request, response);
}
}
다음으로는 BasicInterceptor.java파일이다. 위에서 했으니까 간단하게 진행하겠다. 아래와 같은 코드만 쳐도 알아서 상속을 받아 Interceptor를 만들어준다. 3개의 interceptor class가 생성될 것이다. afterCompletion, postHandle, preHandle 세가지가 형성된다. 각각 의미하는 바는 해석한 의미와 같다.
@Component
public class BasicInterceptor implements HandlerInterceptor
Interceptor는 이렇게만 진행하면 안되고 config 폴더안에 WebMvcConfig.java라는 파일을 만들어야한다. MVC는 Model-View-Controller로 그냥 역할을 나누는 것이라고 생각하면 될 것같다. 여기도 똑같이 implements로 상속을 받으면 알아서 코드가 생성된다. 그리고 아래에 add와 exclude를 사용하여 interceptor를 할 부분과 안할 부분을 지정해주면 된다. admin이라는 path가 있는데 AdminController를 하나 만들어서 또 @GetMapping을 해주면된다. 그리고 AdminController class가 선언되는 부분위에 @RequestMapping("/admin")을 해주면 알아서 localhost:8080/admin이 작성된다.
public class WebMvcConfig implements WebMvcConfigurer{
@Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
// WebMvcConfigurer.super.addInterceptors(registry);
registry.addInterceptor(new BasicInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/admin/**");
}
MyBatis는 Java에서 사용가능한 객체 관계 매핑 프레임워크이다. 객체들을 서로 연결해주는 역할을 한다고 보면 된다. MySQL이랑 비슷하다. 이것을 처음에 사용하려면 Spring Boot 프로젝트를 만들때 추가 라이브러리를 넣어줘야한다. 위에서 사용한 2개의 라이브러리 외에 추가로 MySQL과 MyBatis를 추가해주면 된다. 그리고 아래는 우리 챗박사님이 알려주신 MyBatis에 대한 정보이다. 전체적인 개요를 이해하기에 아주 좋고 깔끔해 보여서 가져왔다.
MyBatis와 Spring Boot를 함께 사용할 때, 전형적인 구조는 다음과 같습니다. 이 구조는 MVC(Model-View-Controller) 아키텍처를 기반으로 하며, MyBatis를 데이터베이스와 연동하는 부분을 포함합니다.
Controller (컨트롤러):
Service (서비스):
Model (모델):
DAO (데이터 액세스 객체) 또는 Repository:
MyBatis 설정:
Spring Boot 프로젝트 구조 예시:
src
├── main
│ ├── java
│ │ ├── com.example.demo
│ │ │ ├── controller
│ │ │ │ ├── MyController.java
│ │ │ ├── service
│ │ │ │ ├── MyService.java
│ │ │ ├── model
│ │ │ │ ├── MyModel.java
│ │ │ ├── dao
│ │ │ │ ├── MyMapper.java
│ │ ├── resources
│ │ │ ├── mapper
│ │ │ │ ├── MyMapper.xml
│ │ ├── DemoApplication.java
├── resources
│ ├── application.properties
│ ├── mybatis-config.xml
위의 예시에서 MyController가 클라이언트의 요청을 받고, MyService에서 MyBatis의 MyMapper를 호출하여 데이터베이스 조작을 수행합니다. MyModel은 데이터를 표현하는 Java 객체로 MyBatis와 연동되어 데이터베이스와 매핑됩니다. MyMapper.xml은 MyBatis의 XML 매핑 파일로 SQL 쿼리를 정의합니다.
이러한 구조를 통해 Spring Boot와 MyBatis를 함께 사용하여 데이터베이스와의 효율적인 상호 작용을 달성할 수 있습니다.
from. Chat GPT
위에서 본 구조처럼 정말 다양한 것들을 설계해야 MyBatis가 동작한다. 내부 코드내용은 블로그에 올리지 않도록 하겠다. 코드를 올린다면 너무 복잡해질 것으로 예상되기 때문이다.
간단하게 작업 순서만 적어두려고 한다. 프로젝트 폴더 이름은 demo가 아닌 basic으로 설정했고 구현하려는 것은 Product라는 table을 변경하는 controller다.
- resources폴더에 application.yml 파일을 만들고 내부에 코드를 작성하여 Spring Boot 설정, DataBase(MySQL) 설정, MyBatis를 설정한다.
1-1 (선택사항) build.gradle이나 pom.xml에서 추가 할 라이브러리가 있다면 추가한다. resources폴더에 추가로 받은 파일 2개를 추가
- resources폴더에 mapper폴더를 만들고 그 안에 ProductMapper.xml를 만들고 사용할 MyBatis 코드를 설계한다.
- basic폴더에 model폴더를 만들고 그 안에 dto폴더를 만든 후 ProductDto.java 파일을 만든다. 내부에는 table의 coulumn들과 이름을 private 변수로 지정해주고 getter, setter를 구현해준다.
- model폴더에 repository폴더를 만들고 ProductMapper.java를 만들고 설계한다.
- basic폴더에 service라는 폴더를 만들고 ProductService.java를 만들고 설계한다.
- basic폴더에 controller라는 폴더를 만들고 ProductController.java를 만들고 설계한다.
결과에서 오류가 발생한다면 모두 복사해서 GPT에게 물어보면 된다.
Mapper.xml으로부터 파생되어 모든 설계가 진행되기 때문에 잘 설계하고 이해하는 것이 중요하다. 만드는 순서를 다시 한번 말하면
Mapper.xml -> Dto.java -> Mapper.java -> Service.java -> Controller.java
이다.
아래는 사용한 xml코드이다.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTO Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.basic.model.repository.ProductMapper">
<!-- 조회할때는 select -->
<select id="selectAll" resultType="ProductDto">
select
product_id
, product_name
, product_price
from product
where 1=1
;
</select>
<!-- resultType은 return하는 값이 있을때 사용한다. parameterType은 parameter가 있을때 사용한다.
보면 ProductDto에서 입력해주는 값이나 출력하는 값의 형태를 변형 시켜준다고 생각 -->
<select id="selectProduct" resultType="ProductDto" parameterType="ProductDto">
select
product_id
, product_name
, product_price
from product
where 1=1
<if test='productName != null and productName != ""'>
and product_name = #{productName}
</if>
<if test='productPrice != null and productPrice > 0'>
and product_price = #{productPrice}
</if>
;
</select>
<!-- 데이터를 저장할 때는 insert -->
<insert id="insertProduct" parameterType="ProductDto">
insert into product(product_name, product_price)
values (#{productName}, #{productPrice});
</insert>
<update id="updateProduct" parameterType="ProductDto">
update product
<set>
<if test='productName != null and productName != ""'>
product_name = #{productName}
</if>
<if test='productPrice != null and productPrice > 0'>
product_price = #{productPrice}
</if>
</set>
where 1=1
and product_id = #{productId}
</update>
<delete id="deleteProduct">
delete from product
where 1=1
and product_id = #{productId}
;
</delete>
</mapper>
JSP(Java Server Pages)는 최근에는 많이 사용하지 않아 간단하게 공부하고 넘어갔다. JSP는 HTML 웹 코드에 java 코드를 삽입하여 사용할 수 있게 만드는 것이다. <% java 코드 %> 라는 코드를 삽입하여 사용할 수 있다. java 코드를 import 하는 과정에서는 <%@ %> 을 사용하면 된다. class를 불러오는 코드는 <%! %> 을 사용한다.
<%@ page import="java.sql.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String url = "jdbc:mysql://localhost:3306/examplesdb";
String user = "urstory";
String password = "";
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
System.out.println("MySQL 연결 성공 ");
String sql = "show tables;";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
System.out.println("결과: "+rs.getString("Tables_in_examplesdb"));
}
} catch (Exception e) {
System.out.println("MySQL 연결 오류: "+e.getMessage());
} finally {
if(pstmt != null)
try{pstmt.close();}catch(SQLException sqle){}
if(conn != null)
try{conn.close();}catch(SQLException sqle){}
}
%>
</body>
</html>
위 코드는 mysql을 java에 불러와서 사용하고 그 코드를 HTML에 사용하는 JSP file의 코드이다.
Java코드에서 사용한 변수를 가져오려면 <%= 변수명 %>을 사용하면 된다. JSP를 사용하여 할일 목록을 만드는 코드를 만들 수 있다. MySQL에서 Database를 만들고 그것을 Java에 연결할 수 있다. 이렇게 연결된 데이터를 JSP에서 사용하여 바로 웹페이지에 구현하게 할 수있다. 내가 만든 것은 ToDO List(할일 목록)를 만드는 프로젝트를 진행했다. 새로운 일정을 등록하면 DB에 추가되고 삭제하면 DB에 삭제되는 것을 구현했다. JavaScript 코드와 Java 코드 모두를 사용했는데, 이후에 코드에 익숙해진다면 JS 만으로도 구현할 수 있다.