MyBatis 와 로그 출력 해보기

gdhi·2023년 11월 29일
post-thumbnail

📖MyBatis 기초

JdbcTemplate 같은 녀석인데 더 줄여버렸다. JDBC vs SQL MAPPER vs ORM]
JDBC, SQL MAPPER, ORM

개발자가 지정한 SQL, 저장 프로시저 그리고 몇 가지 고급 매핑을 지원하는 Persistance(영속성, 데이터를 생성한 프로그램이 종료되어도 사라지지 않는 데이터의 특성) 프레임워커 이다.


📌MyBatis 프로젝트 생성

👉 전 프로젝트 복붙하며 늘 하던대로 설정

MyBatis Spring Boot Starter

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0'
	compileOnly 'jakarta.servlet:jakarta.servlet-api:6.0.0'
	implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1'
	implementation 'org.apache.tomcat:tomcat-jasper:10.1.16'
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.springframework.boot:spring-boot-starter-jdbc:3.2.0'
	implementation 'mysql:mysql-connector-java:8.0.33'
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
	testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3'
}

👉 아래 두 줄 추가

프로퍼티에

mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
추가
👉 mapper 안의 모든 xml 설정

👉 resources > mybatis > mapper 폴더 생성 후 MyUserDAO.xml 파일 생성


📍MyBatis 패키지, mapper


MyUserDTO 클래스

package com.MyBatis;

import lombok.Data;

@Data
public class MyUserDTO {
    private String id;
    private String name;

}



IMyUserDAO 인터페이스

package com.MyBatis;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface IMyUserDAO {
    List<MyUserDTO> list();
}



MyUserDAO.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.MyBatis.IMyUserDAO">
    <select id="list" resultType="com.MyBatis.MyUserDTO">
        select id, name from myuser
    </select>
</mapper>



MyController 클래스

package com.MyBatis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyController {
    
    @Autowired
    private IMyUserDAO userDAO;
    
    @RequestMapping("/")
    public @ResponseBody String root(){
        return "MyBatis 사용하기";
    }
    
    @GetMapping("/user")
    public String userListPage(Model model){
        model.addAttribute("users", userDAO.list());
        return "userList";
    }
}



userList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <%
        out.println("MyBatis : Hello World");
    %>
    
    <br>
    
    <c:forEach var = "dto" items="${users}">
        ${dto.id} / ${dto.name} <br>
    </c:forEach>
</body>
</html>



📍결과



❓어떤 구조로 실행?




👉 classpath의 리소스 폴더 안에 .xmlMyBatis 사용


<mapper namespace="인터페이스">
    <select id="메소드명" resultType="결과값 DTO">
        [쿼리문]select 속성(id, name...) from myuser ❗이름이 다르면 절대 안된다!!
    </select>
</mapper>


👉 실행









📖MyBatis로 간단한 게시판 만들기

2일차에 만든 Border를 MyBatis로 변경


📌BatisBorder 프로젝트 생성


📍BatisBorder 패키지, mapper

BorderDTO 클래스

package com.MyBatisBorder;

public class BorderDTO {
    private int id;
    private String writer;
    private String title;
    private String content;
}



IBorderDAO 인터페이스

package com.MyBatisBorder;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface IBorderDAO {
    public List<BorderDTO> listDao();
    public BorderDTO viewDao(String id);
    public int writeDao(BorderDTO borderDTO);
    public int deleteDao(String id);
}



BorderController 클래스

package com.MyBatisBorder;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class BorderController {

    @Autowired // 자식인 객체
    IBorderDAO dao;

    @RequestMapping("/")
    public String root(){
        return "redirect:list";
    }

    @RequestMapping("/list")
    public String userListPage(Model model){
        model.addAttribute("list", dao.listDao());
        return "list";
    }

    @RequestMapping("/view")
    public String view(@RequestParam("id") String id, Model model){
        model.addAttribute("dto", dao.viewDao(id));
        return "view";
    }

    @RequestMapping("/writeForm")
    public String writeForm(){
        return "writeForm"; // 화면만 나온다
    }

    @RequestMapping(value = "/write", method = RequestMethod.POST) // POST 방식으로 보낸다
    public String write(Model model, BorderDTO bbsDto){ //HttpRequest 필요없이 BBSDto에 담으면 된다
        dao.writeDao(bbsDto);
        return "redirect:list";
    }

    @RequestMapping("/delete")
    public String delete(@RequestParam("id") String id){
        dao.deleteDao(id);
        return "redirect:list";
    }
}



borderDAO.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.MyBatisBorder.IBorderDAO">
    <select id="listDao" resultType="com.MyBatisBorder.BorderDTO">
        select * from simple_bbs order by id desc
    </select>
    <select id="viewDao" resultType="com.MyBatisBorder.BorderDTO">
        select * from simple_bbs where id = #{param1}
    </select>
    <insert id="writeDao">
        insert into simple_bbs(writer, title, content) values(#{param1}, #{param2}, #{param3})
    </insert>
    <delete id="deleteDao">
        delete from simple_bbs where id = #{param1}
    </delete>
</mapper>



list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8">
    <title>게시판</title>
</head>
<body>
    <table width="500" cellpadding="0" cellspacing="0" border="1">
            <tr>
                <th>번 호</th>
                <th>작성자</th>
                <th>제 목</th>
                <th>삭 제</th>
            </tr>
            <tr>
                <c:forEach items="${list}" var="dto">
            </tr>
            <tr>
                <td>${dto.id}</td>
                <td>${dto.writer}</td>
                <td><a href="view?id=${dto.id}">${dto.title}</a></td>
                <td><a href="delete?id=${dto.id}">X</a></td>
            </tr>
            <tr>
                </c:forEach>
            </tr>
    </table>

    <p><a href="writeForm">글 작성</a></p>
</body>
</html>



view.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8">
    <title>Document</title>
</head>
<body>
    내용보기 <br>

    <hr>

    작성자 : ${dto.writer} <br>
    제 목 : ${dto.title} <br>
    내 용 : ${dto.content} <br>

    <hr>

    <br><p>
        <a href="list">목록보기</a>
    </p>
</body>
</html>



wirteForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <table width="500" cellpadding="0" cellspacing="0" border="1">
        <form action="write" method="post">
            <tr>
                <td>작성자</td>
                <td><input type="text" name="writer" size="100"></td>
            </tr>
            <tr>
                <td>제 목</td>
                <td><input type="text" name="title" size="100"></td>
            </tr>
            <tr>
                <td>내 용</td>
                <td><input type="text" name="content" size="100"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="입력">
                &nbsp;&nbsp; <a href="list">목록보기</a></td>
            </tr>
        </form>
        </table>
</body>
</html>

📍결과









💷부트스트랩을 사용 간단한 게시판 만들어보기

위에는 너무 구리다.. 새 프로젝트로 이쁘게 꾸며보고 전에 만들었던 것 처럼 작성시간, 수정 등등 예쁘게 꾸며보자.


📌board 테이블 생성

create table `mybatisbbs`.`board`(
	`num`           int not null auto_increment,
	`name` 			varchar(100)  not null,
	`subject`		varchar(100) not null,
	`content`		text         not null,
	`registDay`		varchar(100),
	primary key(num)
)default charset=utf8;

select * from board; 

drop table `mybatisbbs`.`board`;



📌MyBatis Mapper 생성


📍borderDAO.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.MybatisTestBoard.IBoardDAO">
    <select id="listDao" resultType="com.MybatisTestBoard.BoardDTO">
        select * from board order by num desc
    </select>
    <select id="viewDao" resultType="com.MybatisTestBoard.BoardDTO">
        select * from board where num = #{num}
    </select>
    <insert id="writeDao">
        insert into board(name, subject, content, registDay) values(#{name}, #{subject}, #{content}, #{registDay})
    </insert>
    <update id="updateDao">
        update board set name=#{name}, subject=#{subject}, content=#{content}, registDay=#{registDay} where num = #{num}
    </update>
    <delete id="deleteDao">
        delete from board where num = #{num}
    </delete>
</mapper>



📌application.properties 설정

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

#spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
#spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/mybatisbbs
spring.datasource.url=jdbc:mysql://localhost:3306/mybatisbbs
spring.datasource.username=root
spring.datasource.password=1234

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



📌BoardDTO 클래스 생성

package com.MybatisTestBoard;

import lombok.Data;

import java.time.LocalDate;

@Data
public class BoardDTO {
    private int num; // 글 번호
    private String name; // 작성자
    private String subject; // 글 제목
    private String content; // 글 내용
    private LocalDate registDay = LocalDate.now(); // 작성 날짜
}



📌IBoardDAO 인터페이스 생성

package com.MybatisTestBoard;

import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Mapper
public interface IBoardDAO {

    public List<BoardDTO> listDao();
    public BoardDTO viewDao(String num);
    public int writeDao(BoardDTO dto);
    public int updateDao(BoardDTO dto);
    public int deleteDao(String num);
}



📌BoardController 클래스 생성

package com.MybatisTestBoard;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.LocalDate;

@Controller
public class BoardController {

    @Autowired // 자식인 객체
    IBoardDAO dao;

    @RequestMapping("/")
    public String root(){
        return "redirect:list";
    }

    @RequestMapping("/list")
    public String userListPage(Model model){
        model.addAttribute("list", dao.listDao());
        return "list";
    }

    @RequestMapping("/view")
    public String view(@RequestParam("num") String num, Model model){
        model.addAttribute("dto", dao.viewDao(num));
        return "view";
    }

    @RequestMapping("/writeForm")
    public String writeForm(){
        return "writeForm"; // 화면만 나온다
    }

    /*@RequestMapping(value = "/write", method = RequestMethod.POST) // POST 방식으로 보낸다
    public String write(Model model, BorderDTO bbsDto){ //HttpRequest 필요없이 BBSDto에 담으면 된다
        dao.writeDao(bbsDto);
        return "redirect:list";
    }*/

    @RequestMapping(value = "/write", method = RequestMethod.POST)
    public String write(BoardDTO dto){

        //LocalDate registDay = LocalDate.now();

        //model.addAttribute("registDay", registDay);
        dao.writeDao(dto);

        System.out.println(dto.getRegistDay());

        return "redirect:list";

    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(BoardDTO dto){

        dao.updateDao(dto);

        return "redirect:list";
    }

    @RequestMapping("/delete")
    public String delete(@RequestParam("num") String num){

        dao.deleteDao(num);

        return "redirect:list";
    }
}



📌list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8">
    <title>게시판</title>
        <link
    	href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"
    	rel="stylesheet"
    	integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9"
    	crossorigin="anonymous">
</head>
<body>

    <nav class = "navbar navbar-expand navbar-dark bg-dark">
    	<div class = "container">
    		<div class = "navbar-header">
    			<a class = "navbar-brand" href="list">게시판</a>
    		</div>
    	</div>
    </nav>

	<div class="text-bg-info p-3">
		<div class="container">
			<h1 class="display-1">게시판</h1>
		</div>
	</div>

	<br>
	<br>

	<div class="container">
		<div class="row" align="center">
			<div style="padding-top:50px">
				<table class="table table-hover">
					<tr>
						<th>번호</th>
						<th>제목</th>
						<th>작성시간</th>
						<th>글쓴이</th>
					</tr>
                <c:forEach items="${list}" var="dto">
            </tr>
            <tr>
                <td>${dto.num}</td>
                <td><a href="view?num=${dto.num}">${dto.subject}</a></td>
                <td>${dto.registDay}</td>
                <td>${dto.name}</td>
            </tr>
            <tr>
                </c:forEach>
            </tr>
    </table>
			</div>
			<div class="form-group row">
				<div class="col-sm-offset-2 col-sm-10">
					<p>
						<a href="writeForm"
							class="btn btn-primary">게시글 작성</a>
					</p>
				</div>
			</div>
		</div>
	</div>

</body>
</html>



📌view.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8">
    <title>Document</title>
     <link
     href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"
     rel="stylesheet"
     integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9"
     crossorigin="anonymous">
</head>
<body>
    <nav class = "navbar navbar-expand navbar-dark bg-dark">
    	<div class = "container">
    		<div class = "navbar-header">
    			<a class = "navbar-brand" href="list">게시판</a>
    		</div>
    	</div>
    </nav>
	<div class="text-bg-info p-3">
		<div class="container">
			<h1 class="display-1">게시판</h1>
		</div>
	</div>
	<div class="container">
	    <form action="update?num=${dto.num}" class="form-horizontal" method="post">
                <div class="form-group row">
    				<label class="col-sm-2 control-label">작성자</label>
    				<div class="col-sm-3">
    					<input name = "name" class="form-control"
    						value='${dto.name}'>
    				</div>
    	        </div>

    			<div class="form-group row">
    				<label class="col-sm-2 control-label">글 제목</label>
    				<div class="col-sm-3">
    					<input name = "subject" class="form-control"
    						value='${dto.subject}'>
    				</div>
    			</div>

    			<div class="form-group row">
    				<label class="col-sm-2 control-label">글 내용</label>
    				<div class="col-sm-8" style="word-break: break-all">
    					<textarea rows="10" cols="100" id = "content" name="content" class="form-control">${dto.content}</textarea>
    				</div>
    			</div>

    			<div class="form-group row">
    				<div class="col-sm-offset-2 col-sm-10">
    					<p>
    					    <input type="submit" class="btn btn-success" value="수정" >
    						<!--<a href="update?num=${dto.num}" class="btn btn-success">수정</a>-->
    						<a href="delete?num=${dto.num}" class="btn btn-warning">삭제</a>
    						<a href="list"
    							class="btn btn-primary">목록</a>
    					</p>
    				</div>
    			</div>
    	    </form>
    </div>
</body>
</html>



📌writeForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8">
    <title>게시글 작성</title>
    	<link
    	href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"
    	rel="stylesheet"
    	integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9"
    	crossorigin="anonymous">
    	<script type="text/javascript">
            function checkForm() {
                if(!document.newWrite.name.value) {
                    alert("이름을 입력하세요.");
                	return false;
                }
                if(!document.newWrite.subject.value) {
                	alert("제목을 입력하세요.");
                	return false;
                }
                if(!document.newWrite.content.value) {
                	alert("내용을 입력하세요.");
                	return false;
                }
            }
        </script>
</head>
<body>
        <nav class = "navbar navbar-expand navbar-dark bg-dark">
            	<div class = "container">
            		<div class = "navbar-header">
            			<a class = "navbar-brand" href="list">게시판</a>
            		</div>
            	</div>
            </nav>
    	<div class="text-bg-warning p-3">
    		<div class="container">
    			<h1 class="display-1">게시글 작성</h1>
    		</div>
    	</div>

    	<div class="container">
    		<form action="write" name="newWrite" class="form-horizontal" method="post" onsubmit="return checkForm()" >
    				<div class="form-group row">
    					<label class="col-sm-2 control-label">이름</label>
    					<div class="col-sm-3">
    						<input name="name" type="text" class="form-control" placeholder="이름을 입력하세요.">
    					</div>
    				</div>

    				<div class="form-group row">
    					<label class="col-sm-2 control-label">제목</label>
    					<div class="col-sm-5">
    						<input name="subject" type="text" class="form-control" placeholder="제목을 입력하세요.">
    					</div>
    				</div>

    				<div class="form-group row">
    					<label class="col-sm-2 control-label">내용</label>
    					<div class="col-sm-8">
    						<textarea rows="5" cols="50" name="content" class="form-control"
    									placeholder="내용을 입력하세요."></textarea>
    					</div>
    				</div>

    				<div class="form-group row">
    					<div class="col-sm-offset-2 col-sm-10">
    						<input type="submit" class="btn btn-primary" value="등록" >
    						<input type="reset" class="btn btn-danger" value="다시 입력">
    					</div>
    				</div>

    		</form>
    	</div>
</body>
</html>



📌결과

👉 작성

👉 수정

👉 삭제









📖MyBatis로 SQL 로그 출력하기


📌logback-spring.xml 만들기

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative] [%thread]
            %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.MyBatisBorder" level="debug"/>

    <root level="info">
        <appender-ref ref="console"/>
    </root>
</configuration>

👉 콘솔창



📌Resource Bundle로 properties 만들기

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jsSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0

📍logback-spring.xml 추가하기

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative] [%thread]
            %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.MyBatisBorder" level="debug"/>

    <!-- log4j2-jdbc4 -->
    <logger name="jdbc" level="OFF"/>
    <logger name="jdbc.sqlonly" level="OFF"/>
    <logger name="jdbc.sqltiming" level="DEBUG"/>
    <logger name="jdbc.resultset" level="OFF"/>
    <logger name="jdbc.resultsettable" level="DEBUG"/>
    <logger name="jdbc.connection" level="OFF"/>
    <!-- log4j2-jdbc4 -->

    <root level="info">
        <appender-ref ref="console"/>
    </root>
</configuration>

📍build.gradle 의존성 추가

Log4Jdbc Log4j2 JDBC 4 1 » 1.16

implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'


📍application.properties 수정

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

spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/jdbc 
spring.datasource.username=root
spring.datasource.password=1234

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

📍결과

👉 2번 삭제









📖서비스의 개념과 사용

👉 스프링 웹 MVC의 요청 처리 시 흐름

트랜잭션

실행이 올바르게 된다면 적용, 하지만 실행이 중간에서 실패가 되면 이전 실행 흐름 모두 취소

다음은 다음시간에

0개의 댓글