5 단계 설정 변경 지도
"분명 코드대로 했는데 DB 가 안 돼요..."
Spring 에서 DB 연결은 한 곳만 손대서 되는 일이 아닙니다. 여러 파일이 동시에 협업해야 합니다. 어디 하나가 빠지면 전체가 동작 안 합니다.
Spring Legacy 의 자동 설정은 거의 없습니다. 모든 부품을 우리가 직접 등록해줘야 합니다:
이걸 5 단계로 정리해 두면 매번 막막함이 줄어듭니다.
👉 이 5 곳 중 한 곳이라도 빠지면 전체가 동작 안 함.
<!-- MySQL 드라이버 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- HikariCP 커넥션 풀 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
<!-- MyBatis + Spring 통합 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.2</version>
</dependency>
<!-- Spring 의 JDBC 추상화 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.30</version>
</dependency>
pom.xml 수정 후 반드시 프로젝트 우클릭 → Maven → Update Project. 안 하면 빨간 줄이 안 사라짐.
<!-- (1) HikariCP 설정 객체 -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="1234" />
</bean>
<!-- (2) DataSource (실제 DB 연결의 진입점) -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<!-- (3) MyBatis SqlSessionFactory -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"
value="classpath:mybatis-config.xml" />
<property name="mapperLocations"
value="classpath:com/smhrd/mapper/*Mapper.xml" />
</bean>
<!-- (4) Mapper 자동 스캔 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.smhrd.mapper" />
</bean>
| Bean | 역할 |
|---|---|
hikariConfig | DB 연결 정보(URL, 계정 등) |
dataSource | 실제 연결을 만들고 풀로 관리 |
sqlSessionFactory | MyBatis 의 핵심. SQL 실행을 책임 |
MapperScannerConfigurer | 지정 패키지의 Mapper 인터페이스를 자동 스캔하고 Bean 으로 등록 |
👉 MapperScannerConfigurer 덕분에 우리가 매 Mapper 를 일일이 등록 안 해도 됨.
DB 연결 정보 자체가 틀린 건지(URL/계정), Bean 등록이 빠진 건지를 가려야 합니다.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- ⭐ 카멜 ↔ 스네이크 자동 변환 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!-- SQL 로그 출력 (개발 시) -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
</configuration>
👉 mapUnderscoreToCamelCase=true 가 핵심.
DB: created_at = '...' (스네이크)
VO: LocalDateTime createdAt (카멜)
결과: b.getCreatedAt() == null!
SELECT 는 성공하는데 객체 필드가 null 이면 → 이름 매핑 실패.
mapUnderscoreToCamelCase=true 로 해결. 상세는 다음 차시(◆ 카멜·스네이크 함정).
// src/main/java/com/smhrd/mapper/MemberMapper.java
package com.smhrd.mapper;
import com.smhrd.domain.Member;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MemberMapper {
Member selectOne(String id);
void insert(Member m);
}
<!-- src/main/resources/com/smhrd/mapper/MemberMapper.xml -->
<mapper namespace="com.smhrd.mapper.MemberMapper">
<select id="selectOne"
parameterType="string"
resultType="com.smhrd.domain.Member">
SELECT id, pwd FROM mymember WHERE id = #{id}
</select>
<insert id="insert" parameterType="com.smhrd.domain.Member">
INSERT INTO mymember(id, pwd)
VALUES(#{id}, #{pwd})
</insert>
</mapper>
namespaceidroot-context.xml 의 mapperLocations 가 가리키는 경로MapperScannerConfigurer 의 basePackage 안에"Invalid bound statement" 또는 "Method not found" 오류. 가장 빈번한 함정.
| 증상 | 의심 |
|---|---|
| No qualifying bean of type 'XxxMapper' | 인터페이스가 스캔 패키지 밖에 있음 |
| Invalid bound statement (not found) | namespace 또는 id 오타 |
| XML 자체를 못 찾음 | mapperLocations 경로 틀림 |
@Service
public class MemberService {
@Autowired
private MemberMapper mapper; // ← 이 한 줄
public Member find(String id) {
return mapper.selectOne(id);
}
}
👉 MapperScannerConfigurer 가 자동 등록한 Mapper Bean 을 받음.
NullPointerException — mapper 변수가 null 인 채로 메서드 호출됨.
@Autowired 가 빠지면 그 자리는 그냥 null. 그래도 컴파일은 되니 실행해야 알 수 있음.
| 증상 | 1순위 의심 | 점검 단계 |
|---|---|---|
| Cannot create connection | DB URL/계정/MySQL 가동 | ② |
| No class found | 의존성 누락 | ① |
| No qualifying bean | Bean 등록 누락 | ② or ④ |
| Invalid bound statement | namespace·id 오타 | ④ |
| 필드값 모두 null | 매핑 옵션 | ③ |
| NullPointerException at mapper | @Autowired 누락 | ⑤ |
DB 가 안 되면 어디부터 봐야 할지 막막했다. 한 곳 고치면 다른 곳이 또 깨졌다.
5 단계 지도를 외운다. DB 안 됨 오류를 만나면 5 곳을 차례로 점검한다.
다음: HikariCP 커넥션 풀 — 풀이 왜 필요한가.