STUDY - MyBatis

준동이·2024년 2월 10일
0

MyBatis

목록 보기
1/1
post-thumbnail

시작하며

항상 프로젝트를 하며 MyBatis를 사용을 하였는데 원리에 대해서는 지식이 많이 부족한거같아 오늘은 MyBatis를 공부해보려고 한다 !

Spring Boot + MyBatis + JSP를 사용을 해보려고 한다.

원래는 Spring Boot가 아닌 그냥 Dynamic Web Project로 만들어서 직접 수동으로 라이브러리나 설정들을 다 할까 했지만 정보를 찾다 거의 Spring Boot로 많이 하는 것 같아서 나도 Spring Boot로 해보려고 한다.

MyBatis에 대한 공부이면서 Spring Boot + JSP에 대한 것도 같이 종합하여 간단하게 정리를 해볼 생각이다.

MyBatis가 중점적으로 이루어지며 Spring Boot와 JSP에 대한 설명은 다른 시리즈로 제대로 공부를 해볼 것이다 !




MyBatis란?


우선 MyBatis가 무엇인지 알아보자 !

MyBatis는 데이터베이스를 쉽게 다룰 수 있도록 도와주는 Framework이며 JDBC의 기능을 대부분 제공한다.

데이터베이스 쿼리와 프로그래밍 언어 코드를 분리하여 유지보수성과 생산성을 높일 수 있다.

SQL을 별도의 파일로 분리하여 관리할 수 있으며 JDBC같이 클래스나 JSP에서 직접 작성는 방식의 불편함도 제거해주어 SQL에 변경이 있을 때마다 자바 코드를 수정하거나 컴파일하지 않아도 된다.




MyBatis 설정하기


프로젝트 생성

나는 Maven을 사용하여서 Maven으로 만들었으며 JSP를 사용하기에 War를 선택하였다 !

Jar? War? 이게 뭐야 ?

JAR ( Java Archive )

  • Java 어플리케이션이 동작할 수 있도록 자바 프로젝트를 압축한 파일
  • JRE ( Java Runtime Environment )만 있어도 실행 가능하다.
  • 압축된 형식으로 클래스, 리소스, 라이브러리 등을 포함하므로 배포와 전달이 용이하다.
  • Java 애플리케이션의 진입점인 main 메서드를 포함하고 있어 JVM에서 직접 실행하기 때문에 별도의 웹 컨테이너나 서버가 필요하지 않다.

War ( Web Application Archive )

  • Servlet / JSP 컨테이너에 배치할 수 있는 웹 애플리케이션 압축파일.
  • Java 웹 애플리케이션을 패키징하는데 최적화, 웹 구셩요소인 JSP, Servlet, 필터, 리스너 등과 웹 애플리케이션을 실행하기 위한 서블릿 컨테이너(웹 컨테이너)에서 필요한 설정 파일, 라이브러리, 리소스 등을 포함하여 한 번에 배포 및 실행할 수 있다.
  • 사전 정의된 구조를 사용함 ( WEB-INF, META-INF )
  • 별도의 웹 서버( WEB ) or 웹 컨테이너( WAS ) 필요
  • 즉, JAR파일의 일종으로 웹 어플리케이션 전체를 패키징 하기 위한 JAR 파일이다.

출처 : https://velog.io/@mooh2jj/JAR-vs-WAR-%EB%B0%B0%ED%8F%AC%EC%9D%98-%EC%B0%A8%EC%9D%B4

추가 더 자세한 정보는 나중에 따로 다뤄보겠다 !


Dependency 설정은 이렇게 해보았다. 혹시 빼먹은게 있다면 추후 추가로 설정해주면 되니 일단 이렇게 설정 해보겠다.

Dependencies 설명

Spring Boot DevTools

  • Spring Boot Application을 개발하고 디버깅을 하는데 도움이 되는 도구 모음을 의미한다.

  • 개발 단계에서 자동으로 다시 로드되는 기능을 제공하여 개발자가 변경 사항을 신속하게 확인할 수 있도록 도움을 준다.
    또한 라이브 리로딩, 프로퍼티 변경 감지 및 자동 재시작과 같은 기능도 제공한다.

LomBok

  • LomBok은 어노테이션 기반으로 코드를 자동완성 해주는 라이브러리이다.

  • Getter, Setter 등 다양한 방면의 코드를 자동완성 시킬 수 있다.

  • 기계적인 코드 작성을 자동화해서 코드를 작성하는 것이다.

MyBatis Framework

  • MyBatis를 사용하기 위한 설정으로 설명은 위에서 참고.

MariaDB Driver

  • MariaDB 데이터베이스와의 연결을 가능하게 하는 라이브러리이다.

Spring Web

  • 내장된 Tomcat서버를 제공하여 별도의 웹 서버를 설치하거나 구성할 필요가 없다.
    그래서 애플리케이션을 더 쉽게 패키지하고 배포할 수 있다는 장점도 가지고 있다.

  • Spring MVC를 위한 기본 설정들을 자동으로 제공한다.
    @Controller 어노테이션을 사용하여 컨트롤러를 정의하거나 @RequestMapping 어노테이션을 사용하여 URL매핑을 수행 등 편리한 설정들을 제공해준다.

  • 따라서 내장된 Tomcat서버와 Spring MVC를 쉽게 설정하고 사용할 수 있어서 프로젝트의 초기 설정과 구성에 대한 부담을 줄일 수 있다.



application.properties 설정

프로젝트를 완성 후 src/main/resources에 mapper폴더를 생성후 쿼리문을 적을 xml파일을 MyBatis.xml로 생성해주었다.
그리고 application.properties에서 DB연결 정보와 MyBatis의 경로를 잡아주기 위해 정보를 입력해야한다 !

간단한 프로젝트 구조 설명

src/main/java 디렉토리

  • 자바 파일을 저장하는 곳이다.

  • 스프링 부트의 컨트롤러, DTO, 엔티티, 서비스 등의 자바 파일이 패키지와 클래스파일의 구조로 위치한다.

src/main/resources 디렉토리

  • 자바 파일을 제외한 HTML, CSS, 자바스크립트, 환경 파일 등을 저장하는 공간이다.
    ( 환경파일 : 프로젝트의 설정 정보를 저장하는 파일이다. )

static 디렉토리

  • 프로젝트의 스타일시트 ( css파일 ), 자바스크립트 ( js파일 ) 그리고 이미지 파일 ( jpg파일, png파일 등 ) 등을 저장한다.

application.properties 디렉토리

  • 프로젝트의 환경을 설정한다.

  • 프로젝트의 환경 변수, 데이터베이스 등의 설정을 이 파일에 저장한다.

src/test/java 디렉토리

  • 프로젝트에서 작성한 파일을 테스트하는 코드를 저장하는 공간이다. JUnit과 스프링 부트의 테스트 도구를 사용하여 서버를 실행하지 않은 상태에서 src/main/java 디렉토리에 작성한 코드를 테스트할 수 있다.
    ( JUnit은 테스트 코드를 작성하고, 작성한 테스트 코드를 실행할 때 사용하는 자바의 테스트 프레임워크이다. )

내가 사용해본 부분은 어느정도 알지만 사용해보지 않은 디렉토리는 그냥 이런 구조구나 라고는 이해만 해서 정확히 어떻게 사용하며 활용을 해야하는지 잘 숙지하지 못했다.

이 부분은 Spring Framework, Spring Boot공부를 하며 차근차근 알아가보자.

출처 : https://wikidocs.net/160947



application.properties에서 정보를 넣어보자 !

경로 및 설정 설명

spring.datasource.driver-class-name=org.mariadb.jdbc.Driver

  • 이 속성은 데이터베이스 연결을 관리하는 데 사용되는 JDBC 드라이버의 클래스 이름을 지정한다.

  • 속성을 설정하여 어떤 JDBC 드라이버를 사용할지 지정할 수 있다.

  • org.mariadb.jdbc.Driver는 MariaDB JDBC 드라이버의 클래스 이름이다.
    => 클래스 이름은 원래 org/mariadb/jdbc/Driver.class 이런식으로 경로가 되어있다.
    => 설정 해줄때는 "/"가 아닌 " . " 으로 설정해준다.
    => 클래스 이름은 해당 라이브러리의 공식 문서나 구조에서 확인이 가능하다.
    => 나는 Dependency에서 MariaDB Driver를 추가해줘서 알아서 해당 라이브러리를 가져왔기      때문에 저 클래스 이름을 사용할 수 있다.

spring.datasource.url=jdbc:mariadb://localhost:3306/user

  • 데이터베이스에 접속하기 위한 경로 설정이다.

  • jdbc : JDBC URL의 프로토콜을 나타낸다.

  • mariadb : MariaDB JDBC 드라이버를 사용한다는 것을 나타낸다.

  • localhost : MariaDB 서버의 호스트명이나 IP주소이다.
    나는 로컬 서버(현재 사용 중인 컴퓨터)로 설정이 되어있어서 localhost이다.
    실제 운영 환경에서 사용한다면 호스트명이나 IP주소를 실제 정보로 입력해줘야한다.

  • 3306 : 3306포트번호를 사용한다는 것이다.
    기본 포트 번호이며 다른 포트에서 실행중일 경우 해당 포트 번호로 바꿔줘야한다.

  • user : 이 부분은 연결할 데이터베이스의 이름이다.
    나는 user라는 데이터베이스를 생성하여 설정하였다.


    => 즉 localhost 서버의 3306포트에서 동작하는 MariaDB 서버에 user라는 데이터베이스를 연결한다는 것.

spring.datasource.username=root

  • 데이터베이스에 연결할 때 사용할 데이터베이스 사용자 이름을 설정하는 속성이다.

spring.datasource.password=비밀번호

  • 사용자의 비밀번호를 입력해주는 속성이다.

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

  • Spring MVC 애플리케이션에서 뷰 파일이 위치하는 디렉토리의 접두사(prefix)를 설정하는 속성

  • spring.mvc.view.suffix=.jsp는 뷰 이름에 접미사(suffix)를 추가하여 확장자를 지정한다.

  • 만약 home.jsp 파일이 있다면, 원래는 /WEB-INF/views/home.jsp인데, 설정을 해줌으로써 home이라고 해도 /WEB-INF/views/home.jsp 이렇게 해석이 된다. ( 이건 직접 코드를 보면 알 수 있을 것 이다. )

mybatis.mapper-locations=classpath:/mapper/*.xml

  • 이 속성은 MyBatis 프레임워크에서 SQL매핑 정보를 담고 있는 XML파일의 위치를 설정하는 속성이다.

  • SQL쿼리와 자바 객체 간의 매핑을 정의하는 XML파일을 사용하여 데이터베이스와 상호작용을 하는데 이 속성을 사용하여 이러한 매핑 파일이 어디에 위치하는지 지정할 수 있다.

  • mapper라는 디렉토리 아래에 있는 모든 XML파일을 SQL매핑 파일로 인식하게 설정해놓았다.
    (classpath:/mapper/*.xml로 설정 : XML파일은 이 파일만 사용할 것 같아서 전체로 설정함)
    classpath:/ 를 쓴 이유는 안넣어 줬더니 경로를 찾지 못하였음 .. 이유를 찾아보니 기본적으로 만들어지는 resources 폴더 하위를 설정할때 사용하는 것 같다 !



JSP 설정

JSP를 사용하기 위해 JSP 폴더를 생성해주었다.

디렉토리 구조를 보면 webapp/WEB-INF 구조로 되어있는 것을 볼 수 있다.
이 것은 WAS가 읽을 수 있는 구조여서 이 구조를 맞춰서 디렉토리를 생성하여 jsp파일을 만든 것이다.

WEB-INF 외부에서의 접근을 할 수 없는 디렉토리이다.
만약 직접 URL에 전체 경로를 다 적어준다고 해도 접속을 할 수 없을 것 이다.
그래서 컨트롤러를 통하여 jsp파일에 접근할 수 있도록 구현하였다 !
( 구현 코드에서 확인해보자 ! )

=> 즉, 구조를 맞춰서 디렉토리를 생성하고 개발하면 된다 !
아파치 톰캣을 다운 받았다면 해당 폴더 경로를 찾아보면 알 수 있다.



Jasper / JSTL Dependency 추가

스프링에서는 더이상 JSP를 권장하지 않으며 내장된 톰캣도 JSP를 지원하지 않는다고 한다.
대신 Thymeleaf엔진을 권장하는 것 같다. 하지만 나는 JSP만 사용해봐서.. JSP로 해보려고 한다.

권장하지 않는다고 해서 사용하지 못하는 것은 아니다 !
JSP를 사용하고 싶다면 Jasper와 JSTL을 추가하여 JSP를 지원하도록 설정할 수 있다.

Jasper란?
JSP 파일을 컴파일하고 실행 가능한 서블릿 코드로 변환하는데 사용된다고 한다.
JSP 컨테이너의 핵심 엔진으로, JSP 파일을 자바 코드로 변환하여 실행한다.
=> Jasper를 사용하면 JSP파일을 서블릿으로 컴파일할 수 있으며, Spring Boot 애플리케이션에서 JSP를 실행하는 데 필요하다.

JSTL이란?
JSP 페이지에서 자주 사용되는 일반적인 작업을 단순화하는 데 사용된다.
반복문, 조건문, 데이터 포맷팅 등을 위한 태그 라이브러리가 포함되어 있다.
JSP 페이지에서 코드의 가독성을 높이고, 유지보수를 쉽게 할 수 있다는 장점이 있다.

=> 따라서 Spring Boot에서 JSP를 사용할 때는 Jasper와 JSTL을 추가하여 JSP파일을 실행 가능한 서블릿으로 컴파일하고, JSP페이지에서 간편하게 작업할 수 있도록 지원하는 것이다.

https://mvnrepository.com/ 에서 검색하여 각 Dependency 추가할 수 있다 !


Spring Boot에서 Mybatis와 JSP를 사용하기 위한 설정은 여기까지이다. 이제 코드 작성을 해보자 !




Mybatis 코드 구현


패키지 구조

MVC 패턴을 통해 Mybatis를 구현한 패키지 구조이다.
각 패키지가 어떠한 역할을 하고있는지 간단하게 살펴보자 !

  • config
    데이터베이스 접속을 위한 설정을 담은 패키지이다.
  • controller
    컨트롤러 클래스 파일이 들어가있는 패키지로, View(화면)와 로직(Model)을 연결시켜주는 역할을 하는 Controller 클래스 파일이 들어가있다.
  • dto ( Data Transfer Object )
    데이터를 전송하기 위한 객체 클래스 파일이 있는 패키지이다.
    DTO는 프로세스 간에 데이터를 전달하는 용도의 객체로, 비즈니스 로직을 포함하지 않는 데이터를 전달하기 위한 단순 객체이다.
  • mapper
    Mapper Interface가 있는 패키지이다.
    Mybatis는 Mapper인터페이스를 제공한다.
    Mybatis 매핑 xml에 SQL을 호출하기 위한 Interface가 있다.
    DAO를 사용하는 것 보다 구조가 더 편리하여 Mapper를 사용하였다.
  • service
    Service Interface 와 Service 구현체인 ServiceImpl 클래스가 있는 패키지이다.
    Service는 비즈니스 로직을 수행하는 부분으로 여기서 Mapper를 의존해 Controller로 값을 반환해 주었다.



Application.java - 실행 클래스

프로젝트를 실행하기 위한 클래스로 Spring Boot Application을 실행하는 곳이다.
스프링 빈을 설정하기 위한 어노테이션 설정과 Mapper를 위한 어노테이션 설정을 하였다.

package com.example.mybatis;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = { "com.example.controller", "com.example.config", "com.example.service", "com.example.dto", "com.example.dao", "com.example.mapper" } ) 
@MapperScan("com.example.mapper")
public class MyBatisApplication {

	public static void main(String[] args) {
		SpringApplication.run(MyBatisApplication.class, args);
	}
}

코드 설명

@SpringBootApplication

  • 일반적으로 프로그램의 진입점인 메인 애플리케이션 클래스에 적용되는 어노테이션이다.

  • 스프링 부트의 자동 설정과 스프링 Bean읽기와 생성이 모두 자동으로 설정된다.

  • 즉, 스프링 부트 애플리케이션의 주요 구성 요소를 정의하고 애플리케이션을 설정, 실행하며 구성하는 데 사용된다.

@ComponentScan(basePackages={..., ...})
스프링에서는 여러 빈들을 관리하면서 의존성을 주입해 주는데 이때 전체 코드에서 컴포넌트를 찾아 빈을 생성하는 것이 아닌 범위를 지정하여 그 범위 안에서 어노테이션이 된 클래스들을 찾아 빈을 생성 및 관리한다.
빈으로 등록하기 위해 스캔하는 어노테이션은 @Component, @Repository, @Service, @Controller, @Configuration이 있다.

  • 스프링 빈으로 만들기 위한 컴포넌트를 스캔할 곳을 설정하는 역할이다.

  • basePackages는 괄호 안에 직접 패키지 경로를 적어주어 스캔할 위치를 지정할 수 있다.

@MapperScan("com.example.mapper")

  • 지정된 패키지 또는 패키지들에서 Mapper인터페이스를 검색하여 Mybatis가 사용할 수 있도록 등록한다.

  • Mapper Interface가 있는 com.example.mapper 패키지를 경로로 지정해주었다.



UserDTO.java - 데이터 전송을 위해 사용하는 객체

데이터의 전송을 위해 사용하는 객체로 비즈니스 로직은 없으며, 순수하게 전달하고 싶은 데이터만 담겨있다. 주로 클라이언트와 서버가 데이터를 주고받을 때 사용하는 객체이다.

package com.example.dto;

import lombok.Data;

@Data
public class UserDTO {

	int seq;
	String name;
	String age;
	String sex;
	String address;
		
}

코드 설명

@Data

  • @Data 어노테이션은 Lombok 라이브러리에서 제공하는 어노테이션이다.

  • @Data 어노테이션은 @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 모두를 자동으로 적용한다.

Lombok을 사용하지 않았다면 getSeq(), setSeq(int seq) 이런식으로 직접 만들어줘야하지만 @Data 어노테이션을 통해 한번에 처리하며 코드의 복잡성도 줄여주었다.



DatabaseConfiguration.java - DB를 연결하기 위한 클래스

이 클래스에서는 DB와의 연결에 설정에 관한 설정클래스이다.
application.properties에서 설정한 값들을 가져와 설정 하였으며, 연결될 xml파일의 경로도 넣어주었다.

package com.example.config;

import javax.sql.DataSource;


import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DatabaseConfiguration {
	
	@Autowired
	private ApplicationContext applicationContext;
	
	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
	
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);
		sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath:/mapper/*.xml"));
		
		return sqlSessionFactoryBean.getObject();
	}
	
	@Bean
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {

		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

코드 설명

@Configuration

  • 수동으로 스프링 컨테이너에 빈을 등록하는 방법으로 해당 클래스에 @Configuration 어노테이션을 붙여주면 된다. 그리고 @Bean 어노테이션을 사용하여 수동으로 빈을 등록해줄 때에는 메소드 이름으로 빈 이름이 결정이 나서 중복된 빈 이름이 존재하지 않도록 조심해야한다.

  • 과정은 스프링 컨테이너가 @Cnofiguration이 붙어있는 클래스를 자동으로 빈으로 등록해주고, 해당 클래스를 파싱하여 @Bean이 있는 메소드를 찾아서 빈을 생성해준다. 그래서 @Bean을 사용하는 클래스에는 반드시 @Configuration 어노테이션을 활용하여 Bean을 등록하고자 함을 명시해줘야 한다.

@Autowired
private ApplicationContext applicationContext;

  • @Autowried란 의존관계 주입(DI)을 할 때 사용하는 어노테이션이며, 의존 객체의 타입에 해당하는 빈(Bean)을 찾아 주입하는 역할을 한다.

  • ApplicationContext는 스프링 컨테이너로 해당 애플리케이션에 대한 구성 정보를 제공하는 인터페이스이다.
    등록, Bean의 정보를 가져올 수 있으며 BeanFactory를 상속받은 인터페이스이다.
    그래서 이것을 통해서 스프링 컨테이너에 등록된 빈을 가져와 사용하기 위해 사용하였다.

@Bean

  • 빈(Bean)은 인스턴스화된 객체를 의미하며, 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.

  • 해당 메소드의 반환값을 빈으로 등록한다.

public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {} 메소드 설명
반환타입인 SqlSessionFactory 객체는 데이터베이스와의 연결과 SQL의 실행에 대한 모든 것을 가진 가장 중요한 객체이다. 이 객체가 DataSource를 참조하여 Mybatis와 DB서버를 연동시켜준다.

나는 DataSource가 어떻게 사용되는지 궁금하여 찾아봤는데, 스프링이 자동적으로 의존성을 주입시킨 것이고 그 의존성은 application.properties의 설정이라고 볼 수 있다고 한다.

그래서 주입된 DataSource는 메서드 내에서 SqlSessionFactoryBean에 설정되어 데이터베이스 연결을 구성하는 데 사용된다.

이제 코드에 대한 설명을 보겠다.

SqlSessionFactoryBean객체는 SqlSessionFactory를 생성하기 위한 객체로 해당 코드에서 SqlSessionFactoryBean에 설정을 한 후 SqlSessionFactory로 반환을 해주어 데이터베이스와의 연결 설정이 완료된다.

SqlSessionFactoryBean은 MyBatis의 SqlSessionFactory를 생성하기 위한 팩토리 빈이다.
MyBatis의 SqlSessionFactory를 생성하고 구성하기 위한 여러 설정을 제공한다.
데이터베이스 연결 정보를 설정하고 MyBatis 매퍼 파일의 위치 등을 설정할 수 있다.

그래서 setDataSource(dataSource)로 데이터베이스 연결 설정을 넣어준 것과,
setMapperLocations(applicationContext.getResources("classpath:/mapper/*.xml"));로 mybatis.xml 경로를 연결해 주었다.
( application.properties에서 설정해도 되는데 나는 에러가 나서 여기에도 경로 설정을 해주었음 )

SqlSessionFactory는 MyBatis에서 데이터베이스와의 연결을 관리하는 인터페이스이다.
SQL 세션을 생성하여 MyBatis 매퍼와의 상호 작용을 수행한다.
데이터베이스와의 연결 설정, SQL매핑, 쿼리 실행 등을 수행하는 중요한 역할을 한다.

이렇게 생성된 SqlSessionFactory객체를 getObject() 메서드로 반환한다.

SqlSessionTemplate는 SqlSession 인터페이스의 구현체이다.
데이터베이스와의 상호작용을 담당하며, 실제 SQL 쿼리를 실행하고 결과를 반환해준다.

SqlSessionTemplate를 사용하지 않으면SqlSession sqlSession = sqlSessionFactory.openSession(true); 이렇게 생성하여 직접 구현을 해줘야 하는 번거로움을 해결할 수 있다.

그래서 SqlSessionFactory를 주입받아 반환하였다.



UserController.java - 컨트롤러 클래스

컨트롤러 클래스로 Service와 View와 연결되는 클래스이다.
Service와 연결하여 Service에서 데이터를 가져와 다시 Controller로 반환하고 Controller에서 View로 반환하는 역할을 하고있다.

package com.example.controller;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.example.dto.UserDTO;
import com.example.service.UserService;

@RestController
public class UserController {
	
	@Autowired
	private UserService userService;

	@RequestMapping("/user")
	public ModelAndView userList() throws Exception {
		
		ModelAndView mv = new ModelAndView();
		ArrayList<UserDTO> userList = userService.selectUserList();
		
		mv.addObject("userList", userList);
		mv.setViewName("userList");
		return mv;
	}
}

코드 설명

@RestController

  • @RestController는 @Controller에 @ResponseBody가 추가된 것이다.
  • @RestController의 용도는 Json 형태로 객체 데이터를 반환하는 것이다.
  • REST API를 개발할 때 주로 사용하며 객체를 ResponseEntity로 감싸서 반환한다.
  • 즉, @Controller에 @ResponseBody를 붙인 것과 같다.
  • 그래서 나는 REST API를 사용하지 않는다 해도 @RestController로 사용한다.

@Autowired
private UserService userService

  • @Autowried란 의존관계 주입(DI)을 할 때 사용하는 어노테이션이다.
  • 의존 객체의 타입에 해당하는 빈(Bean)을 찾아 주입하는 역할을 한다.
  • 그래서 Service를 사용하기 위해 UserService에 의존성 주입을 해주었다.

@RequestMapping

  • 클라이언트의 요청(URL)에 맞는 클래스나 메서드를 연결시켜주는 어노테이션이다.
  • 나는 /user로 설정하여 localhost:8080/user로 url을 입력하면 접속이 된다.



UserService.java - 서비스 인터페이스

Service Interface로 DB에서 유저 리스트를 가져올 UserList라는 추상 메소드를 정의해 놓았으며 이 인터페이스를 구현하는 ServiceImpl 클래스가 메소드를 오버라이딩하여 DB 정보를 가져올 것이다.

package com.example.service;

import java.util.ArrayList;

import com.example.dto.UserDTO;

public interface UserService {

	ArrayList<UserDTO> selectUserList() throws Exception;
}



UserServiceImpl.java - Service 부분

UserService Interface를 구현한 클래스로 메소드를 오버라이딩 하여 Mapper Interface인 UserListMapper에 접근하여 데이터를 가져온 후 Service를 호출했던 Controller로 값을 return해준다.

코드를 package com.example.service;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.dto.UserDTO;
import com.example.mapper.UserListMapper;

@Service
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserListMapper userListMapper;
	
	@Override
	public ArrayList<UserDTO> selectUserList() throws Exception {		
		return userListMapper.selectUserList();
	}

}

코드 설명

@Service

  • @Service 어노테이션은 비즈니스 로직을 처리하는 서비스 클래스에 적용이 된다.

  • @Service 어노테이션은 해당 클래스를 스프링 빈(Bean)으로 등록하는 역할을 한다.



UserListMapper - Mapper Interface

Mapper 설정 파일(xml)에 있는 SQL 쿼리문을 호출하기 위한 인터페이스로 xml 파일과 연결되어 xml에 있는 쿼리문의 데이터를 호출한다.

UserServiceImpl에서 이 인터페이스를 의존하였던 것이다.

package com.example.mapper;

import java.util.ArrayList;

import org.apache.ibatis.annotations.Mapper;

import com.example.dto.UserDTO;

@Mapper
public interface UserListMapper {

	ArrayList<UserDTO> selectUserList() throws Exception;
}

코드 설명

@Mapper

  • @Mapper 어노테이션은 Interface를 매퍼로 등록하기 위해 사용한다.
    그러면 MyBatis에게 해당 인터페이스가 SQL 매핑 파일과 연결되어 있음을 알려준다.
    그래서 MyBatis는 해당 인터페이스의 구현체를 생성하고 SQL 매핑 파일의 SQL 쿼리를 실행할 수 있다.

  • @Mapper 어노테이션을 사용하면 빈으로 등록되며 메서드명과 xml 파일의 id와 동일하게 맞춰줘야 한다.



UserListMapper.xml - MyBatis xml파일

여기에서 매퍼 인터페이스와 이름을 맞춰서 코드를 구현해야한다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        
<mapper namespace="com.example.mapper.UserListMapper">
	<select id="selectUserList" resultType="com.example.dto.UserDTO">
		select * from user_list
	</select>
</mapper>

코드 설명

여기에서 매퍼 인터페이스와 정보를 맞춰야 하는데 namespace를 해당 매퍼 인터페이스의 경로를 적어주며, id값에는 해당 인터페이스의 메소드 명과 일치 시켜주고, resultType은 DTO로 순수 객체들에 대한 값으로 받기때문에 resultType을 DTO 경로로 설정해주었다.

처음 xml 파일을 만들고

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

이 부분이 왜 필요한지 의문점이 생겼었다.

찾아보니 MyBatis xml 매퍼 파일에 대한 DTD를 지정한다고 한다.

DTD란 XML 문서의 구조와 유효성을 정의하는 규칙 세트라고 한다.
XML 문서가 올바른 형식으로 작성되었는지를 검사하는데 사용된다고 한다.



마치며

나는 원래 밑의 코드처럼

@Select("select * from user_list")
ArrayList<UserDTO> selectUserList() throws Exception;

이런식으로 Mybatis를 다뤘다.
이건 3버전 이상부터 사용할 수 있다는 글을 봤던 기억이 있다.
하지만 이렇게 말고 XML파일을 만들어 사용하는 방법도 알아야 할 것 같아서 배웠었지만 다시금 해봤던 것이다.

기회가 되면 원래 하던 방식에 대한 공부도 다시 할겸 2탄을 올릴 수 있으면 올려보겠다 !

이번 MyBatis를 공부하면서 Spring Boot의 어노테이션과 JSP와 각 설정들에 대한 내가 할 수 있는 설명을 최대한 해보려고 했더니 너무 가독성도 떨어지는 느낌이고 다른 사람들이 본다면 보기 힘들 구조인 것 같기도 하다 .. 사실 내가 공부하려고 하는거라 상관은 없지만 그래도 점점 포스팅을 하며 가독성도 더 좋고 퀄리티도 더 좋게 만들어 봐야겠다.


혹시 누군가 제 포스팅을 보고 잘못된 점이나 부족하거나 바로잡아야할 부분이 있다면 언제든 댓글로 피드백 부탁드립니다 !

그럼 안녕 ~ 🖐🖐

profile
개발자 꿈나무

0개의 댓글