스프링 초기화 도구 (Spring Initializr)를 사용하여 스프링 부트 프로젝트를 생성합니다. 필요한 의존성을 추가합니다.
Spring Web
Spring JDBC
MySQL Driver
스프링 초기화 도구를 사용하여 기본 설정을 하면 pom.xml 파일에 필요한 의존성이 추가됩니다.
스프링 부트와 MySQL 드라이버 의존성을 추가합니다.
<dependencies>
<!-- Spring Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
application.properties 또는 application.yml 파일에 데이터베이스 연결 설정을 추가합니다.
spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
데이터베이스 테이블과 매핑되는 모델 클래스를 생성합니다.
package com.example.demo.model;
public class User {
private Long id;
private String name;
private String email;
// Getters and Setters
}
순수 JDBC를 사용하여 데이터베이스 작업을 수행할 DAO 클래스를 생성합니다.
package com.example.demo.dao;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
private static final class UserRowMapper implements RowMapper<User> {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
return user;
}
}
public List<User> findAll() {
String sql = "SELECT * FROM users";
return jdbcTemplate.query(sql, new UserRowMapper());
}
public User findById(Long id) {
String sql = "SELECT * FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
}
public int save(User user) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
return jdbcTemplate.update(sql, user.getName(), user.getEmail());
}
public int update(User user) {
String sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
return jdbcTemplate.update(sql, user.getName(), user.getEmail(), user.getId());
}
public int deleteById(Long id) {
String sql = "DELETE FROM users WHERE id = ?";
return jdbcTemplate.update(sql, id);
}
}
비즈니스 로직을 처리하는 서비스 클래스를 생성합니다.
package com.example.demo.service;
import com.example.demo.dao.UserDao;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserDao userDao;
public List<User> getAllUsers() {
return userDao.findAll();
}
public User getUserById(Long id) {
return userDao.findById(id);
}
public void saveUser(User user) {
userDao.save(user);
}
public void updateUser(User user) {
userDao.update(user);
}
public void deleteUser(Long id) {
userDao.deleteById(id);
}
}
RESTful API를 제공하는 컨트롤러 클래스를 생성합니다.
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
@PostMapping
public void createUser(@RequestBody User user) {
userService.saveUser(user);
}
@PutMapping("/{id}")
public void updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
이제 스프링 부트 애플리케이션을 실행하면 순수 JDBC를 사용하여 MySQL 데이터베이스와 연동된 RESTful API가 작동합니다.
스프링 초기화 도구 (Spring Initializr)를 사용하여 스프링 부트 프로젝트를 생성합니다. 필요한 의존성을 추가합니다.
스프링 초기화 도구를 사용하여 기본 설정을 하면 pom.xml 파일에 필요한 의존성이 추가됩니다.
MyBatis와 MySQL 드라이버 의존성을 추가합니다.
<dependencies>
<!-- Spring Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
application.properties 또는 application.yml 파일에 데이터베이스 연결 설정을 추가합니다.
spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.mapper-locations=classpath:mappers/*.xml
데이터베이스 테이블과 매핑되는 모델 클래스를 생성합니다.
package com.example.demo.model;
public class User {
private Long id;
private String name;
private String email;
// Getters and Setters
}
SQL 쿼리를 정의할 MyBatis 매퍼 인터페이스를 생성합니다.
package com.example.demo.mapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users")
List<User> findAll();
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(Long id);
@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int save(User user);
@Update("UPDATE users SET name=#{name}, email=#{email} WHERE id=#{id}")
int update(User user);
@Delete("DELETE FROM users WHERE id = #{id}")
int deleteById(Long id);
}
SQL 쿼리를 XML 파일에 정의할 수도 있습니다. 이는 더 복잡한 쿼리나 재사용 가능한 쿼리를 관리할 때 유용합니다.
src/main/resources/mappers/UserMapper.xml 파일을 생성합니다.
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="findAll" resultType="com.example.demo.model.User">
SELECT * FROM users
</select>
<select id="findById" parameterType="Long" resultType="com.example.demo.model.User">
SELECT * FROM users WHERE id = #{id}
</select>
<insert id="save" parameterType="com.example.demo.model.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>
<update id="update" parameterType="com.example.demo.model.User">
UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="Long">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
비즈니스 로직을 처리하는 서비스 클래스를 생성합니다.
package com.example.demo.service;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<User> getAllUsers() {
return userMapper.findAll();
}
public User getUserById(Long id) {
return userMapper.findById(id);
}
public void saveUser(User user) {
userMapper.save(user);
}
public void updateUser(User user) {
userMapper.update(user);
}
public void deleteUser(Long id) {
userMapper.deleteById(id);
}
}
RESTful API를 제공하는 컨트롤러 클래스를 생성합니다.
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
@PostMapping
public void createUser(@RequestBody User user) {
userService.saveUser(user);
}
@PutMapping("/{id}")
public void updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
이제 스프링 부트 애플리케이션을 실행하면 MyBatis를 사용하여 MySQL 데이터베이스와 연동된 RESTful API가 작동합니다.
JDBC와 MyBatis는 모두 Java 애플리케이션에서 데이터베이스와 상호작용하기 위해 사용되지만, 접근 방식과 기능 면에서 큰 차이가 있습니다. 아래는 두 기술의 주요 차이점을 설명합니다.

JDBC는 단순하고 모든 제어를 직접 할 수 있는 반면, MyBatis는 더 높은 수준의 추상화를 제공하여 개발자의 생산성을 높이고 코드의 유지보수성을 향상시킵니다. MyBatis는 특히 대규모 프로젝트에서 SQL 쿼리를 관리하고 재사용하는 데 유리합니다.
역할:
데이터베이스와의 직접적인 상호작용을 담당합니다.
SQL 쿼리를 실행하여 데이터베이스에서 데이터를 조회, 삽입, 업데이트, 삭제 등의 작업을 수행합니다.
특징:
특정 데이터베이스 기술 (예: JDBC, Hibernate)과 밀접하게 연관됩니다.
데이터베이스와 상호작용하는 메서드들을 정의합니다.
예시:
public class UserDao {
public User findById(Long id) {
// 데이터베이스에서 ID로 사용자 조회
}
public int save(User user) {
// 데이터베이스에 사용자 저장
}
// 기타 데이터베이스 작업 메서드
}
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
// 스프링 데이터 JPA가 구현체를 자동 생성
}
public class UserDto {
private Long id;
private String name;
private String email;
// Getters and Setters
}
특징 DAO (Data Access Object) Repository DTO (Data Transfer Object)
주요 역할 데이터베이스와의 직접적인 상호작용 도메인 객체와 데이터 소스 간의 상호작용 추상화 계층 간 데이터 전송
연관 기술 JDBC, Hibernate 등 데이터베이스 기술 스프링 데이터 JPA 등 ORM 프레임워크 -
주요 기능 SQL 쿼리 실행, 데이터 조회, 삽입, 수정, 삭제 데이터 액세스 로직 추상화 데이터를 단순히 전송
추상화 수준 저수준 (SQL 쿼리 중심) 고수준 (메서드 호출 중심) N/A
사용 계층 데이터 액세스 계층 데이터 액세스 계층 프레젠테이션 계층, 서비스 계층
비즈니스 로직 포함될 수 있음 포함될 수 있음 없음
예시 코드 설명
DAO 예시:
java
Copy code
public class UserDao {
public User findById(Long id) {
// 데이터베이스 연결, SQL 쿼리 실행, ResultSet 처리 등 직접 처리
}
public int save(User user) {
// 데이터베이스 연결, SQL 쿼리 실행
}
// 기타 데이터베이스 작업 메서드
}
Repository 예시 (스프링 데이터 JPA):
java
Copy code
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
// 기본적인 CRUD 메서드는 JpaRepository에 의해 자동으로 제공됨
}
DTO 예시:
java
Copy code
public class UserDto {
private Long id;
private String name;
private String email;
// Getters and Setters
}
결론
DAO는 데이터베이스와의 직접적인 상호작용을 담당합니다.
Repository는 데이터 액세스 로직을 더 높은 수준에서 추상화하여 제공하며, 주로 스프링 데이터 JPA와 같은 프레임워크에서 사용됩니다.
DTO는 데이터 전송을 목적으로 하는 객체로, 주로 계층 간 데이터 전송을 위해 사용됩니다.
이들을 적절히 사용함으로써 애플리케이션의 구조를 더 명확하게 하고, 유지보수성을 높일 수 있습니다.
먼저, 데이터베이스 연결을 설정하는 클래스를 만듭니다.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DataSourceUtil {
public static Connection getConnection() throws SQLException {
String url = "jdbc:mysql://localhost:3306/your_database_name";
String username = "your_username";
String password = "your_password";
return DriverManager.getConnection(url, username, password);
}
}
다음으로, DAO 클래스를 작성하여 JDBC를 사용하여 데이터베이스 작업을 수행합니다.
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class UserDao {
public List<User> findAll() {
List<User> users = new ArrayList<>();
String sql = "SELECT * FROM users";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
User user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
users.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
// 예외 처리 로직 추가
}
return users;
}
public User findById(Long id) {
User user = null;
String sql = "SELECT * FROM users WHERE id = ?";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setLong(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
}
}
} catch (SQLException e) {
e.printStackTrace();
// 예외 처리 로직 추가
}
return user;
}
public int save(User user) {
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getEmail());
return pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
// 예외 처리 로직 추가
return 0;
}
}
public int update(User user) {
String sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getEmail());
pstmt.setLong(3, user.getId());
return pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
// 예외 처리 로직 추가
return 0;
}
}
public int deleteById(Long id) {
String sql = "DELETE FROM users WHERE id = ?";
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setLong(1, id);
return pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
// 예외 처리 로직 추가
return 0;
}
}
}
위에서 작성한 DAO 클래스를 사용하여 데이터베이스 작업을 수행하는 예시 코드를 작성합니다.
public class Main {
public static void main(String[] args) {
UserDao userDao = new UserDao();
// 모든 사용자 조회
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println("User ID: " + user.getId() + ", Name: " + user.getName() + ", Email: " + user.getEmail());
}
// 특정 사용자 조회
Long userId = 1L;
User user = userDao.findById(userId);
if (user != null) {
System.out.println("Found User ID: " + user.getId() + ", Name: " + user.getName() + ", Email: " + user.getEmail());
} else {
System.out.println("User with ID " + userId + " not found.");
}
// 새로운 사용자 추가
User newUser = new User();
newUser.setName("Alice");
newUser.setEmail("alice@example.com");
int rowsAffected = userDao.save(newUser);
if (rowsAffected > 0) {
System.out.println("New user added successfully.");
} else {
System.out.println("Failed to add new user.");
}
// 사용자 업데이트
user.setEmail("updated.email@example.com");
rowsAffected = userDao.update(user);
if (rowsAffected > 0) {
System.out.println("User updated successfully.");
} else {
System.out.println("Failed to update user.");
}
// 사용자 삭제
rowsAffected = userDao.deleteById(2L);
if (rowsAffected > 0) {
System.out.println("User deleted successfully.");
} else {
System.out.println("Failed to delete user.");
}
}
}
위 예시에서는 스프링 프레임워크의 JDBC Template을 사용하지 않고도 순수 JDBC를 이용하여 데이터베이스 작업을 수행하는 방법을 보여주었습니다. DataSourceUtil 클래스를 통해 데이터베이스 연결을 설정하고, UserDao 클래스를 통해 JDBC를 사용하여 데이터베이스 조회, 삽입, 업데이트, 삭제 작업을 구현하였습니다. 이를 통해 JDBC Template을 사용하지 않고도 직접 JDBC API를 활용하여 데이터베이스 작업을 할 수 있습니다.