[Spring boot] Bank App - MyBatis 설정 (DB 접근 기술)

2025. 2. 14. 12:49·Spring
728x90

🚀 학습 목표

1. MyBatis 란 뭘까?

2. MyBatis 의존성 설정 확인
3. yml 파일 매퍼 설정 확인
4. mapper 패키지 및 xml 파일 생성

 

📌 MyBatis 설정

# MyBatis 설정
mybatis:
  mapper-locations:
    - classpath:mapper/**/*.xml # MyBatis 매퍼 파일 경로 설정 (모든 XML 매퍼 파일 포함)
  configuration:
    map-underscore-to-camel-case: true # 데이터베이스의 언더스코어 네이밍을 카멜 케이스로 자동 매핑
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # MyBatis SQL 로그를 콘솔에 출력

🔹 1. MyBatis란?

MyBatis는 자바 언어를 위한 데이터베이스 연동 프레임워크로, SQL 쿼리와 자바 코드를 매핑하고 관리할 수 있도록 도와줍니다. SQL을 직접 작성하는 대신, XML 파일이나 어노테이션을 사용하여 쿼리를 정의하고, 자바 객체와 데이터베이스 간의 매핑을 설정할 수 있습니다.

📌 순수 JDBC 코드 예시

import java.sql.*;

public class JDBCExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String username = "root";
        String password = "password";

        try (Connection connection = DriverManager.getConnection(url, username, password)) {
            System.out.println("데이터베이스 연결 성공!");
            String sql = "SELECT * FROM users WHERE id = ?";
            try (PreparedStatement statement = connection.prepareStatement(sql)) {
                statement.setInt(1, 1);
                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
                        System.out.println("사용자 ID: " + resultSet.getInt("id"));
                        System.out.println("사용자 이름: " + resultSet.getString("name"));
                    } else {
                        System.out.println("사용자를 찾을 수 없습니다.");
                    }
                }
            }
        } catch (SQLException e) {
            System.out.println("데이터베이스 연결 오류: " + e.getMessage());
        }
    }
}

🔹 2. MyBatis 주요 개념

✅ 1) 매퍼(Mapper)

  • SQL 쿼리와 자바 메서드를 연결하는 인터페이스 또는 XML 파일
  • MyBatis가 데이터베이스와 상호작용할 수 있도록 설정

✅ 2) SQL 쿼리 매핑

  • MyBatis는 SQL 쿼리를 XML 파일이나 어노테이션으로 정의하고, 이를 통해 코드와 SQL을 분리

✅ 3) 파라미터 매핑

  • SQL 쿼리에 필요한 입력 값을 자바 객체의 속성과 매핑하여 활용

✅ 4) 결과 매핑

  • SQL 실행 결과를 자바 객체로 변환하여 활용 가능

✅ 5) 세션(Session)

  • 데이터베이스와 연결을 관리하는 객체로, 쿼리를 실행할 때마다 세션을 생성하고 관리

📌 3. MyBatis XML 태그 정리

MyBatis의 XML 매퍼에서 사용되는 주요 태그들을 정리해보겠습니다.

🔹 1) <mapper>

  • XML 문서가 특정 매퍼 인터페이스와 연결됨을 나타냅니다.

🔹 2) <select>

  • SELECT 쿼리를 정의하는 태그
  • id 속성: 매퍼 인터페이스의 메서드 이름과 일치해야 함
  • resultType: 결과를 매핑할 자바 클래스 지정
<select id="getUser" resultType="User">
    SELECT * FROM users WHERE id = #{id}
</select>

🔹 3) <insert>, <update>, <delete>

  • 각각 INSERT, UPDATE, DELETE 쿼리를 정의하는 태그
  • parameterType: 전달될 파라미터의 타입을 지정
<insert id="addUser" parameterType="User">
    INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>

🔹 4) <resultMap>

  • SQL 결과를 자바 객체의 필드와 매핑할 때 사용
  • 복잡한 조인 쿼리나 상속 관계를 표현하는데 유용
<resultMap id="UserResultMap" type="User">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
</resultMap>

🔹 5) <sql> & <include>

  • 재사용 가능한 SQL 조각을 정의할 때 사용
<sql id="userColumns">
    id, name, email, created_at
</sql>

<select id="getUser" resultType="User">
    SELECT <include refid="userColumns"/> FROM users WHERE id = #{id}
</select>

🔹 6) <if>, <choose>, <when>, <otherwise>

  • SQL 쿼리를 동적으로 생성할 때 사용
<select id="getUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null"> AND name = #{name} </if>
        <if test="email != null"> AND email = #{email} </if>
    </where>
</select>

🔹 7) <foreach>

  • 컬렉션을 반복 처리하여 IN 절을 만들 때 유용
<select id="getUsersByIds" resultType="User">
    SELECT * FROM users WHERE id IN
    <foreach collection="idList" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

 

동적 SQL 사용 시, 쿼리의 가독성과 유지보수성을 위해 간결하게 유지하는 것이 중요합니다. 복잡한 동적 쿼리는 디버깅과 유지보수를 어렵게 할 수 있으므로, 꼭 필요한 경우에만 사용하는 것이 바람직합니다.


🔹 2. MyBatis 의존성 설정 확인

https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter/3.0.3

 

📌의존성 추가

implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'

 

🔹 3. yml 파일 매퍼 설정 확인

#mybatis 설정 부분 입니다.   
mybatis: 
  mapper-locations:
    - classpath:mapper/**/*.xml  # MyBatis 매퍼 파일 위치를 설정합니다. **는 모든 디렉토리, *.xml은 모든 XML 파일을 의미합니다.
  configuration:
    map-underscore-to-camel-case: true  # 데이터베이스의 언더스코어 네이밍(예: column_name)을 자바의 카멜케이스 네이밍(예: columnName)으로 매핑합니다.
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # SQL 로깅 구현체를 설정합니다. 이 설정을 통해 콘솔에 SQL 로그를 출력합니다.

logging:
  level:
    org.apache.ibatis: DEBUG  # MyBatis 로깅 레벨을 DEBUG로 설정하여, 실행되는 SQL 쿼리와 내부 로깅 정보를 콘솔에 출력합니다.

 

classpath:mapper/**/*.xml은 mapper 디렉토리와 그 하위의 모든 디렉토리에 있는 XML 파일을 클래스 경로에서 찾겠다는 의미입니다. 즉, MyBatis 매퍼 파일들이 프로젝트의 클래스 경로 아래 mapper 디렉토리에 위치해야 합니다.


🔹 4. mapper 패키지 및 xml 파일 생성

경로 확인

UserRepository + user.xml 정의

인터페이스 설계 - 역할을 설계하고 구현은 (xml 파일에서 처리)

 

UserRepository.java 파일 생성

package com.tenco.bank.repository.interfaces;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.tenco.bank.repository.model.User;

//interface 와 user.xml 매칭 - (메서드 명 기준)  
@Mapper // 반드시 선언해주어 한다. 
public interface UserRepository {
	public int insert(User user);
	public int updateById(User user);
	public int deleteById(Integer id);
	public User findById(Integer id);
	public List<User> findAll();
}

src/main/resources/user.xml 파일 생성 (UserRepository 구현체)

<?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.tenco.bank.repository.interfaces.UserRepository">
	
	<!-- 반드시 세미콜론을 제거 해야 한다   -->
	<!-- #{username} 객체에 속성값으로 설정 해야 한다  -->
	<insert id="insert">
		insert into user_tb	(username, password, fullname, created_at)
		values( #{username}, #{password}, #{fullname}, now())
	</insert>
	
	<update id="updateById">
		update user_tb set username = #{username}, 
						password = #{password},
			   			fullname = #{fullname} where id = #{id}
	</update>
	
	<delete id="deleteById">
		delete from user_tb where id = #{id}
	</delete>
	
	<select id="findById" resultType="com.tenco.bank.repository.model.User">
		select * from user_tb where id = #{id}
	</select>
	
	<select id="findAll" resultType="com.tenco.bank.repository.model.User">
		select * from user_tb	
	</select>

</mapper>

 

: 쿼리는 항상 DB 에서 테스트 후에 복사 붙여 넣기 해주세요 (H2에 문법과 RDBMS 에서 적용되는 문법이 다를 수 있습니다.)

 

📌AccountRepository.java 파일 생성

package com.tenco.bank.repository.interfaces;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.tenco.bank.repository.model.Account;

@Mapper // 반드시 작성 
public interface AccountRepository {

	public int insert(Account account);
	public int updateById(Account account);
	public int deleteById(Integer id, String name);
	
	// 고민! - 계좌 조회 
	// --> 한사람에 유저는 여러개의 계좌 번호를 가질 수 있다. 
	public List<Account> findByUserId(@Param("userId") Integer principalId);
	// --> account id 값으로 계좌 정보 조회 
	public Account findByNumber(@Param("number") String id);
	
	// 코드 추가 예정
	
}

 

📌  account.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.tenco.bank.repository.interfaces.AccountRepository"> 
	
	<insert id="insert">
		insert into account_tb(number, password, balance, user_id, created_at)
		values(#{number}, #{password}, #{balance}, #{userId}, now())
	</insert>	
	
	<update id="updateById">
		update account_tb set number = #{number}, password = #{password},
			balance = #{balance}, user_id = #{userId} where id = #{id}
	</update>
	
	<delete id="deleteById">
		delete from account_tb where id = #{id}
	</delete>
	
	
	<select id="findByUserId" resultType="com.tenco.bank.repository.model.Account">
		select * from account_tb where user_id = #{userId} 
	</select>
	
	<select id="findByNumber"  resultType="com.tenco.bank.repository.model.Account">
		select * from account_tb where number = #{number}
	</select>
</mapper>

 

 

📌 HistoryRepository.java 파일 생성

package com.tenco.bank.repository.interfaces;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.tenco.bank.repository.model.History;

@Mapper
public interface HistoryRepository {
	
	public int insert(History history);
	public int updateById(History history);
	public int deleteById(Integer id);
	
	// 계좌 조회 
	public History findById(Integer id);
	public List<History> findAll();
}

 

📌 history.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.tenco.bank.repository.interfaces.HistoryRepository">

	<insert id="insert" parameterType="com.tenco.bank.repository.model.History">
		insert into
		history_tb(
		amount, w_balance, d_balance,
		w_account_id, d_account_id
		)
		values(
		#{amount}, #{wBalance}, #{dBalance},
		#{wAccountId}, #{dAccountId}
		)
	</insert>

	<update id="updateById" parameterType="com.tenco.bank.repository.model.History">
		update history_tb
		set amount = #{amount},
		w_balance = #{wBalance},
		d_balace = #{dBalance},
		w_account_id = #{wAccountId},
		d_account_id = #{dAccountId}
		where id =
		#{id}

	</update>

	<delete id="deleteById" parameterType="int">
		delete from history_tb
		where id = #{id}
	</delete>

	<select id="findById" resultType="com.tenco.bank.repository.model.History">
		select * from history_tb where id = #{id}
	</select>

	<select id="findAll" resultType="com.tenco.bank.repository.model.History">
		select * from history_tb
	</select>

</mapper>

마무리 정리

📌 MyBatis는 SQL과 코드의 분리를 통해 유지보수성을 높이고, JDBC보다 효율적으로 데이터베이스를 다룰 수 있습니다.
📌 XML 기반뿐만 아니라 어노테이션 기반으로도 사용할 수 있으며, 동적 SQL을 활용하면 복잡한 조건문도 쉽게 처리할 수 있습니다.
📌 대규모 프로젝트에서는 MyBatis의 매퍼 구조를 잘 설계하여 유지보수를 쉽게 하고, 필요 시 Hibernate 등과 병행 사용을 고려할 수도 있습니다.
📌 Spring Boot와 결합하여 사용할 때는 Configuration 설정과 세션 관리를 신경 써야 합니다.

'Spring' 카테고리의 다른 글

Spring[Spring boot] Bank App - 회원가입(화면구현)  (2) 2025.02.15
[Spring boot] Bank App - 회원가입  (0) 2025.02.15
[Spring boot] Bank App - Exception Handler  (0) 2025.02.13
[Spring boot] Bank App - MainController, mainPage.jsp 구현  (2) 2025.01.15
[Spring boot] Bank App - 화면 구현(레이아웃 분리)  (0) 2025.01.15
'Spring' 카테고리의 다른 글
  • Spring[Spring boot] Bank App - 회원가입(화면구현)
  • [Spring boot] Bank App - 회원가입
  • [Spring boot] Bank App - Exception Handler
  • [Spring boot] Bank App - MainController, mainPage.jsp 구현
공돌이 출신 개발자
공돌이 출신 개발자
공돌이 출신 개발자입니다
  • 공돌이 출신 개발자
    공돌이 출신 개발자
    공돌이 출신 개발자
  • 전체
    오늘
    어제
    • 분류 전체보기 (124)
      • Database (0)
        • SQL (0)
        • 1일 1쿼리 (9)
      • Flutter (40)
        • Dart 언어 (18)
        • App (22)
      • Git (0)
      • Http 기초 지식 (14)
      • HTML5 & CSS3 (0)
      • Java (33)
      • JSP (0)
      • JavaScript (0)
      • Linux (0)
      • MSA (0)
      • Project (0)
      • React (0)
      • Spring (19)
      • 설치 메뉴얼 (1)
      • [Flutter] 프로젝트 (눈길) (8)
        • 작업일지 (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    SQL
    메서드
    HTTP
    Android
    데이터
    flutter
    앱개발
    앱 개발
    로그인
    SQLD
    클래스
    Java
    JAVA 기초
    코딩
    개발
    프로그래밍
    공부
    객체지향
    1일1쿼리
    spring boot
    안드로이드 앱 개발
    dart
    android studio
    블로그 만들기
    프로젝트
    회원가입
    안드로이드
    객체
    플러터
    jsp
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
공돌이 출신 개발자
[Spring boot] Bank App - MyBatis 설정 (DB 접근 기술)
상단으로

티스토리툴바