본문 바로가기
Spring

[Spring] MyBatis(1) 세팅

by moca7 2024. 10. 21.

 

 


ㅁ 마이바티스 ~ 스프링의 AOP 특징도 알아본다.

 

 

ㅁ 새로운 스프링 레거시 프로젝트 생성

- project name은 "04_Spring_MyBatis_AOP"

- "Spring MVC Project" 템플릿 선택

- 베이스 패키지는 "com.br.sbatis"

- src/main/java에 있는 베이스 패키지의 HomeController.java, src/main/webapp/WEB-INF/views의 home.jsp 삭제

 

 

 

 

 

ㅁ DB 연동할거라 DB 생성

 

- 관리자 계정에서 "create user sbatis identified by sbatis;", "grant connect, resource to sbatis;"으로 계정을 생성한다.

- sbatis 계정으로 접속한다. 

 

 

 

- 내가 직접 ~했다면 commit;으로 트랜잭션 처리를 해야 함.

그래야 다른 데서 보인다.

 

 

 

 

ㅁ pom.xml 

 

 
<?xml version="1.0" encoding="UTF-8"?>
   
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.br</groupId>
    <artifactId>sbatis</artifactId>
    <name>04_Spring_MyBatis_AOP</name>
    <packaging>war</packaging>
    <version>1.0.0-BUILD-SNAPSHOT</version>
   
    <properties>
        <java-version>11</java-version>
        <org.springframework-version>5.3.27</org.springframework-version>
        <org.aspectj-version>1.9.19</org.aspectj-version>
        <org.slf4j-version>2.0.7</org.slf4j-version>
    </properties>
   
    <dependencies>
   
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                 </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
               
        <!-- AspectJ -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency>  
       
        <!-- Logging (logback) -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.14</version>
            <!-- <scope>test</scope> 이건 지워야 함 -->
        </dependency>

        <dependency> <!-- 기존 dependency 중 이것만 남기고 다 지운다.-->
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j-version}</version>
        </dependency>
       
       

        <!-- @Inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
               
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
   
        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>        
       
       
        <!-- Lombok 라이브러리 추가 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

        <!-- Jackson 라이브러리 추가 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.14.2</version>
        </dependency>


        <!-- db관련 라이브러리 -->
        <!-- (1) ojdbc8 -->
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>23.2.0.0</version>
        </dependency>

        <!-- (2) spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <!-- (3) mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.14</version>
        </dependency>

        <!-- (4) mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>

        <!-- (5) commons-dbcp -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.9.0</version>
        </dependency>

       

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java-version}</source>
                    <target>${java-version}</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

- 맨 위 6줄 프로젝트 정보는 건들지 말고, properties와 dependencies 수정한다.

- 3번째 프로젝트의 pom.xml에서 properties부터 완전 끝까지(/project) 복사.

 

- 추가로 db연동하고 마이바티스 프레임워크를 사용한다.

기존에 다이너믹 웹 프로젝트할 때도 마이바티스 라이브러리를 추가했었다.

그것만 있으면 되는게 아니고 스프링에서 마이바티스를 쓸 수 있게 라이브러리를 더 추가해야 한다.

db관련 라이브러리도 추가한다. ojdbc 라이브러리 등.

 

- ojdbc6버전을 썼었는데 ojdbc6은 외부저장소를 연결해야 한다해서 ojdbc8을 쓴다.

 

 

 

 

 

 

- 첫번째꺼. com.oracle.database.jdbc

- 스프링이 나온 23년과 비슷한 23.2.0.0버전 사용.

- ojdbc 먼저 추가했다.

 

 

 

 

 

 

- 여기서 보이는 버전은 스프링 버전이다. 스프링의 모듈 중 하나다.

- 5.3.27버전을 쓰고 있으니 거기서 가져온다.

- <version>5.3.27</version>을 <version>${org.springframework-version}</version>으로 수정한다.

이러면 properties 태그만 바꿔도 된다.

 

 

 

 

 

 

- 첫번째에서 3.5.14버전.

 

- 두번째가 스프링과 마이바티스 다리역할이다. 2.0.6버전 사용.

 

 

 

 

 

- DBCP가 database connection pool이다. 2.9.0 사용.

 

 

 

- 기본적으로 이렇게 5개가 필요하다. 오라클 관련한거, 마이바티스 관련한거, 커넥션풀 관련한거.

 

 

 

ㅁ 자바 버전은 그대로다

- 프로젝트 우클릭 - maven - update project 

 

 

 

ㅁ 패키지와 클래스 생성

com.br.sbatis.controller.NoticeController

com.br.sbatis.dto.NoticeDto

com.br.sbatis.dao.NoticeDao

com.br.sbatis.service.Service 인터페이스

com.br.sbatis.service.ServiceImpl 클래스

 

 

 

 

ㅁ NoticeDto

 

 
package com.br.sbatis.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@NoArgsConstructor
// @AllArgsConstructor 매개변수 생성자는 dto엔 사용할 일이 없다.
@Getter
@Setter
@ToString
public class NoticeDto {

    private int no;
    private String title;
    private String content;
   
}

 

 

 

ㅁ NoticeService

 

 
package com.br.sbatis.service;

import java.util.List;

import com.br.sbatis.dto.NoticeDto;

public interface NoticeService {

   
    // 전체목록조회
    List<NoticeDto> selectNoticeList();
   
    // 번호로 공지사항 한 개 조회
    NoticeDto selectNoticeByNo(int noticeNo);
   
    // 공지사항 등록
    int insertNotice(NoticeDto n);
   
    // 공지사항 수정
    int updateNotice(NoticeDto n);
   
    // 다수의 번호들 가지고 공지사항 일괄삭제
    int deleteNotice(String[] deleteNo);
   
}

 

 

 

ㅁ NoticeServiceImpl

 

 
package com.br.sbatis.service;

import java.util.List;

import org.springframework.stereotype.Service;

import com.br.sbatis.dao.NoticeDao;
import com.br.sbatis.dto.NoticeDto;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class NoticeServiceImpl implements NoticeService {
   
   
    private final NoticeDao noticeDao;
   

    @Override
    public List<NoticeDto> selectNoticeList() {
        return null;
    }

    @Override
    public NoticeDto selectNoticeByNo(int noticeNo) {
        return null;
    }

    @Override
    public int insertNotice(NoticeDto n) {
        return 0;
    }

    @Override
    public int updateNotice(NoticeDto n) {
        return 0;
    }

    @Override
    public int deleteNotice(String[] deleteNo) {
        return 0;
    }
   
   

}

 

 

ㅁ NoticeDao

 

 
package com.br.sbatis.dao;

import org.springframework.stereotype.Repository;

@Repository
public class NoticeDao {

}

 

 

 

 

ㅁ 컨트롤러에서는 서비스 객체가, 서비스에서는 dao 객체가 필요하다.

여기까지가 mvc의 기본세팅이다.

 

 

 

 

ㅁ 추가로 마이바티스 쓴다.

- src/main/resources에 config, mappers 폴더 생성.

 

 

ㅁ mapper 파일에 xml 파일 만들기

- 기존에는 dtd 3줄을 홈페이지에서 복붙했다.

- 처음 만들때부터 붙여서 만들 수 있다.

 

 

 

- preferences - xml - xml catalog - ~

 

 

 

 

 

- new xml file에서 finish말고 next한다.

- finish하면 기본 템플릿대로 만들어진다.

 

 

- 2->1

 

 

 

 

 

- 1 -> 2

- user specified entries 보면 내가 만든 2개~. 직므은 mapper파일이니까 mapper 누른다.

 

 

 

 

- finish한다.

 

 

 

 

 

- <cache-ref> 태그는 자동완성시 만들어지는데 반드시 지워줘야 한다.

- 이런식으로 mapper 파일을 많이 만들 예정이다.

- 이때 각각의 mapper 파일을 각각의 어쩌구~

mapper 파일의 ~ namespace

- 초반에 mapper 파일 만들 때 반드시 namespace까지도 써놔라.

namespace를 안쓰고 등록하면 서버 구동이 안된다.

 

 

 

 

 

ㅁ config 폴더에 mybatis-config.xml 생성

- 얘도 finish로 바로 만들지 않고 위처럼 똑같이 한다. 

- user specified entries만 config를 선택한다.

 

 

 

 

- 근데 조금 이상하다. 마이바티스때 홈페이지에서 가져왔던 코드는 세번째가 url 주소였다.

- 이 상태로는 유효성 검사가 제대로 반영이 안 될 수 있다.

 

 

 

 

- 미리 설정하고 가져다 쓰고 있는데 

 

 

 

 

 

- config, mapper 둘 다 https를 http로 바꾼다. 

- https면 url로 인식이 잘 안됬던 이슈가 있었다. ~

 

- config, mapper 둘 다 삭제하고 다시 만들었다. 세번째가 url 주소로 잘 되어있다.

 

 

 

 

ㅁ mybatis-config.xml

 

 

 

- 주로 dto에 별칭을 붙인다. 

그런데 실제 클래스가 존재하고 별칭을 붙여야 한다.

서버 시작할 때 이제 웬만한 xml 파일을 다 읽어들인다. 없으면 서버 시작할 때부터 오류난다.

- mapper 파일도 존재하지 않는 mapper 파일을 쓰면 오류난다.

뿐만 아니라 mapper파일은 namespace까지도 다 지정되어 있어야 한다.

 

 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
<configuration>

    <settings>
        <setting name="jdbcTypeForNull" value="NULL" />
    </settings>

    <typeAliases>
        <typeAlias type="com.br.sbatis.dto.NoticeDto" alias="NoticeDto" />
    </typeAliases>
   
    <!-- 연결 db 정보는 mybatis 관련한 SqlSession[Template] 빈으로 등록하는 곳에서 작성한다.  -->
       
    <mappers>
        <mapper resource="mappers/notice-mapper.xml" />
    </mappers>
   
   
   
</configuration>

 

 

- 그런데 이전 마이바티스의 mybatis-config.xml에서 environments ~

- 연결 db 정보는 mybatis 관련한 SqlSession[Template] 빈으로 등록하는 곳에서 작성한다. 

 

 

- settings, typeAliases, mappers 태그만 작성했다.

- ~ 거기에 연결 db정보를 작성한다. 

 

 

 

 

 

 

ㅁ SqlSession 객체 빈 등록

- 빈 등록 방법은 3가지. xml 방식, 자바 방식, 어노테이션 방식. 내가 만든 클래스면 상단에 어노테이션.

- 이번에 등록해야 하는 빈은 내가 만든 클래스가 아니고 마이바티스가 제공하는 클래스다.

 

- src/main/webapp/WEB-INF/spring의 root-context.xml

서버가 실행될 때 root-context.xml을 읽어들인다. 

 

 

 

ㅁ root-context.xml

- 서버 스타트와 동시에 web.xml 파일에 기술된 ContextLoaderListener에 의해 pre-loading(제일 먼저 읽혀짐)되는 문서.

- Spring Bean Configuration File이다. 빈을 등록하는 파일이다. 아이콘도 콩과 S 모양이 있다.

- 서버 구동과 동시에 등록하고자 하는 빈들이 있다면 해당 파일에 작성하면 된다.

- 주로 db 관련 빈 객체, 트랜잭션 처리, 내외부 모듈 연동 등 스프링에서 제공하는 서비스들에 대한 설정 정보들에 대해 작성한다.

 

 

 

 

 

- SqlSession은 마이바티스가 제공하는 객체다.

~ 우리가 필요한 건 SqlSession 객체가 아니라 ~서 제공하는 SqlSessionTemplate 객체가 필요하다.

 

- 그런데 SqlSessionTemplate 객체를 만드려면 SqlSessionFactoryBean이라는 객체가 필요하다.

SqlSessionFactoryBean 객체도 빈으로 등록되어야 한다.

- 작성 순서 중요하다. SqlSessionFactoryBean이 먼저 생성되어야 한다.

 

- 그런데 SqlSessionFactoryBean 객체를 만드려면 BasicDataSource 객체가 필요하다.

BasicDataSource 객체에 setter 메소드로 value값을 각 필드에 담았다.

 

 

 

 

(1) BasicDataSource

- destroy-method="close"는 해당 빈이 소멸될 때 close() 메서드가 호출된다는 의미다. 

SqlSessionFactoryBean의 경우, 세션을 닫고 연결을 정리하는 자원 해제 작업을 close() 메서드를 통해 수행

 

 

 

(2) SqlSessionFactoryBean 

- SqlSessionFactoryBean 객체를 생성하면서 mybatis-config.xml을 읽어들인다.

- classpath:: 리소스 파일이 클래스패스에 위치하고 있음을 나타냅니다. 클래스패스는 주로 src/main/resources에 해당하며, 이 경로에 있는 파일을 참조할 수 있습니다.

- config/mybatis-config.xml: 클래스패스 내에서 config 폴더 안에 있는 mybatis-config.xml 파일을 참조하겠다는 의미입니다.

- dataSource 필드에 위에서 빈으로 등록한 dataSource 객체를 참조한다.

이 객체를 만들기 위해서는 위의 객체가 필요해서 먼저 빈으로 등록했다.

 

 

(3) SqlSessionTemplate

- 이 빈의 아이디로 "sqlSession"을 준다.

- 빈이름이 바로 위에서 만든 "sqlSessionFactory"인 객체를 주입한다.

 

 

- 위의 3개 다 내가 만든 클래스가 아니어서 어노테이션 방식이 불가능하다.

- 자바에서 객체 생성하고 setter 메소드로 담는 구문이 내부적으로 실행된다.

value 속성이 아니고 ref 속성이면 문자열로 담기는게 아니고 참조 변수가 그대로 담긴다.

- constructor-arg는 setter메소드가 아니라 생성할 때 생성자의 매개변수로 전달한다는 뜻이다.

- 최종적으로 필요한 객체는 SqlSessionTemplate 타입의 sqlSession 객체다.

 

- 스프링을 쓰지 않던 마이바티스 프로젝트에서는 별도로 Template 클래스를 만들어서 SqlSession 객체를 생성해서 반환하는 static 메소드를 만들었었다.

여기서도 sqlSession 객체를 만들 때 mybatis-config.xml을 읽어들이는 InputStream과 sqlSeesionFactoryBuilder ~

 

 

 

 

ㅁ 서버에 add and remove로 4번째 프로젝트만 올리고 서버 스타트한다.

 

ㅁ 로그백

- log4.xml은 지운다.

3번재 프로젝트에서 logback.xml을 복사해서 src/main/resources에 붙여넣는다.

 

 
<?xml version="1.0" encoding="UTF-8"?>
<configuration>


    <appender class="ch.qos.logback.core.ConsoleAppender" name="consoleLog">
        <encoder>
            <pattern>%-5level: [%date{yyyy-MM-dd HH:mm:ss}] [%logger:%line] - %msg%n</pattern>
        </encoder>
    </appender>

   
    <logger name="org.springframework" level="INFO" />
    <logger name="com.br.sbatis" level="DEBUG" />

   
    <root level="WARN">
        <appender-ref ref="consoleLog" />
    </root>  
         
     

</configuration>


 

- <logger name="com.br.ajax" level="DEBUG" />에서 ajax를 sbatis로 바꿨다.

 

 

 

 

 

 

ㅁ 서버 구동해보고 오류나는지 확인한다. 

 

 

 

 

===============================================================

 

 

ㅁ NoticeDao 수정

 

package com.br.sbatis.dao;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Repository
public class NoticeDao {
   
    private final SqlSessionTemplate sqlSession;

}
 

 

 

ㅁ src/main/webapp/WEB-INF/views에 main.jsp 생성

 

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

    <h2>메인페이지</h2>

    <a href="">공지사항 목록페이지로 이동</a>
   
</body>
</html>
 

 

 

ㅁ controller에 MvcController 생성 

 

 
package com.br.sbatis.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MvcController {

   
    @GetMapping("/")
    public String mainPage() {
        return "main";
    }
}
 

 

- 단순히 메인페이지 이동용이다.

- @Contoller 어노테이션 붙인다.

 

 

 

 

ㅁ 서버 리스타트 후 메인페이지가 잘 뜨는지 확인한다.