[면접 회고] part. DB 연동

falsovsveritas·2025년 3월 24일

기술면접

목록 보기
3/10

1. JPA, R2DBC 사용 경험

JPA 사용 경험

✅ JPA(Java Persistence API)는 객체와 데이터베이스를 매핑하는 ORM 기술입니다. Hibernate 같은 구현체를 사용하여 SQL을 직접 작성하지 않고도 데이터베이스 연동이 가능합니다.

JpaRepository 또는 EntityManager를 활용하여 CRUD 작업을 수행할 수 있습니다.

🔹 JPA 사용 예제

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {}

R2DBC 사용 경험

✅ R2DBC(Reactive Relational Database Connectivity)는 비동기 & 논블로킹 방식의 데이터베이스 연동 기술로, 리액티브 프로그래밍(WebFlux 등)과 함께 사용됩니다.

Flux, Mono 같은 리액티브 스트림을 통해 데이터를 효율적으로 처리할 수 있습니다.

🔹 R2DBC 사용 예제

@Repository
public interface UserRepository extends ReactiveCrudRepository<User, Long> {}
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public Flux<User> getUsers() {
        return userRepository.findAll(); // 비동기 Flux 반환
    }
}

2. Spring과 JDBC를 같이 쓴 거냐?

이 질문은 두 가지 의도를 가질 수 있습니다.

1️⃣ Spring이 제공하는 JDBC 관련 기능을 이해하고 활용했는지?

✅ Spring에서 JDBC를 사용할 때 JdbcTemplate 같은 편의 기능을 활용했는지를 묻는 것입니다. Spring을 사용하면서 단순히 기존 JDBC만 사용했는지, 아니면 Spring이 제공하는 편의 기능(JdbcTemplate 등)을 활용했는지를 확인.

💡 좋은 답변 예시(Spring의 JDBC 지원 기능을 활용했을 경우):

"네, Spring에서 제공하는 JdbcTemplate을 사용하여 JDBC와 연동했습니다. JDBC의 번거로운 리소스 관리나 예외 처리를 간소화하고, SQL을 직접 작성할 수 있어 최적화가 가능하기 때문에 사용했습니다."

=> 이 답변의 의미:

  • Spring에서 JDBC 관련 기능(JdbcTemplate)을 제공한다는 것을 알고 있다.
  • 직접 SQL을 컨트롤하면서도 Spring의 이점을 활용했다는 것을 보여줄 수 있음.

JdbcTemplate을 사용하면 SQL을 직접 작성하면서도 Connection, Statement, ResultSet 관리가 자동화됩니다.

🔹 JdbcTemplate 사용 예제

@Autowired
private JdbcTemplate jdbcTemplate;

public List<User> getUsers() {
    String sql = "SELECT * FROM users";
    return jdbcTemplate.query(sql, (rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name")));
}

2️⃣ ORM(MyBatis, JPA)을 사용했는지 확인하려는 의도

✅ Spring 프로젝트에서 JDBC를 직접 쓰는 경우는 많지 않고, 대부분 MyBatis나 JPA를 사용합니다. 하지만 성능 최적화가 필요한 경우 JDBC를 직접 사용할 수도 있습니다.
그래서 면접관이 "Spring과 JDBC를 같이 썼다 = SQL을 직접 작성했다는 건가?"를 확인하고 싶었을 수도 있다.

💡 좋은 답변 예시:

"Spring과 JDBC를 직접 사용한 적은 거의 없고, 일반적으로 MyBatis나 JPA 같은 ORM을 사용했습니다. 하지만 특정 성능 튜닝이 필요한 경우 JdbcTemplate을 사용하여 직접 SQL을 작성한 경험이 있습니다."

=> 이 답변의 의미:

  • 실무에서는 보통 MyBatis/JPA를 사용하지만, 필요하면 JDBC도 쓸 수 있다는 걸 보여줌.
  • 성능이 중요한 경우에는 JPA 대신 JDBC를 쓸 수도 있다는 걸 어필할 수 있음.

🎯 면접관이 진짜 원하는 답변을 하려면?

Spring JDBC 관련 기능(JdbcTemplate)을 알고 있는지 보여주자.
ORM(MyBatis, JPA)도 함께 고려했는지 설명하자.
JDBC를 직접 쓴 경우라면, 그 이유(SQL 최적화, 성능 문제 해결 등)를 설명하자.

💡 좋은 대답 예시:

"보통 Spring에서는 JPA나 MyBatis 같은 ORM을 사용하지만, SQL을 직접 컨트롤할 필요가 있을 때 JdbcTemplate을 활용했습니다. 예를 들면, JPA의 N+1 문제를 피해야 할 때나, 복잡한 SQL 튜닝이 필요할 때 JdbcTemplate을 사용해 최적화한 경험이 있습니다."


3. Spring에서 제공하는 JDBC 템플릿으로 연동했는지, 직접 코드 작성했는지?

Spring JDBC Template은 Spring Framework에서 제공하는 JDBC(Simple JDBC) API를 쉽게 사용할 수 있도록 도와주는 유틸리티 클래스입니다.
JDBC의 복잡한 SQL 실행, 예외 처리, 커넥션 관리 등을 자동으로 처리하여 개발자의 부담을 줄여줍니다.

✅ Spring에서 JDBC를 사용할 때 JdbcTemplate을 활용하면 코드가 간결해지고 예외 처리, 리소스 관리가 자동화됩니다.

✅ 직접 JDBC 코드를 작성하면 Connection, Statement, ResultSet을 직접 관리해야 하므로 코드가 길어지고 유지보수가 어려워질 수 있습니다.

📌 왜 JDBC Template을 사용할까?

기본적인 JDBC 코드를 사용하면 다음과 같은 문제점이 있습니다.

❌ 순수 JDBC 코드(JDBC를 직접 작성한 경우)의 문제점

String sql = "SELECT * FROM users WHERE id = ?";
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
     PreparedStatement pstmt = conn.prepareStatement(sql)) {

    pstmt.setInt(1, 1);
    try (ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            System.out.println("User: " + rs.getString("name"));
        }
    }
} catch (SQLException e) {
    e.printStackTrace();
}

🔴 문제점:

  • 반복적인 코드 (Connection, Statement, ResultSet 등)
  • 예외 처리 필요 (try-catch 블록)
  • 리소스 정리 필요 (close() 호출 필요)

Spring JDBC Template을 사용하면 위의 문제를 해결할 수 있음!

Spring JDBC Template을 사용한 경우 예제

@Autowired
private JdbcTemplate jdbcTemplate;

public List<User> getUsers() {
    String sql = "SELECT * FROM users";
    return jdbcTemplate.query(sql, (rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name")));
}

🔹 개선된 점:
반복 코드 제거 (Connection, Statement, ResultSet 관리 불필요)
자동 예외 처리 (SQL 예외를 DataAccessException으로 변환)
더욱 간결한 코드

📌 Spring JDBC Template 주요 기능

1️⃣ SELECT (조회)

public List<User> getAllUsers() {
    String sql = "SELECT * FROM users";
    return jdbcTemplate.query(sql, (rs, rowNum) -> 
        new User(rs.getInt("id"), rs.getString("name"))
    );
}

2️⃣ SELECT (단일 값 조회)

public int getUserCount() {
    String sql = "SELECT COUNT(*) FROM users";
    return jdbcTemplate.queryForObject(sql, Integer.class);
}

3️⃣ INSERT (데이터 추가)

public void addUser(String name) {
    String sql = "INSERT INTO users (name) VALUES (?)";
    jdbcTemplate.update(sql, name);
}

4️⃣ UPDATE (데이터 수정)

public void updateUser(int id, String name) {
    String sql = "UPDATE users SET name = ? WHERE id = ?";
    jdbcTemplate.update(sql, name, id);
}

5️⃣ DELETE (데이터 삭제)

public void deleteUser(int id) {
    String sql = "DELETE FROM users WHERE id = ?";
    jdbcTemplate.update(sql, id);
}

📌 JdbcTemplate vs. MyBatis vs. JPA 비교

비교 항목JdbcTemplateMyBatisJPA (Hibernate)
방식SQL 직접 사용SQL 매핑(XML, 어노테이션)ORM (객체 매핑)
SQL 작성 필요✅ 직접 작성✅ 직접 작성❌ 자동 생성 (JPQL 지원)
코드량많음중간적음
자동화 수준낮음중간높음
성능높음 (SQL 최적화 가능)중간낮음 (Lazy Loading 주의)
복잡성낮음중간높음

JdbcTemplate: SQL을 직접 작성하고 성능 최적화가 가능하지만 코드량이 많음.
MyBatis: SQL을 XML이나 어노테이션으로 관리하여 가독성이 높음.
JPA: SQL 없이 객체 매핑이 가능하지만 성능 튜닝이 필요함.

SQL을 직접 제어하면서 간편한 JDBC 활용을 원하면 JdbcTemplate을 사용하면 좋음! 🚀


4. DB 연동 방식

1️⃣ 직접 연동 (Embedded / 파일 기반)

  • 애플리케이션이 직접 DB 파일을 읽고 씀.
  • 서버 없이 로컬에서 동작.
  • 예시: SQLite, H2, Realm(DB가 파일 형태로 저장됨).

✅ 장점

  • 서버 없이 간단하게 사용 가능.
  • 설치 및 설정이 간단.

❌ 단점

  • 동시 접속이 어려워 다중 사용자 환경에서 부적합.
  • 대량의 데이터를 처리하기 어려움.

2️⃣ JDBC (Java Database Connectivity)

  • Java 애플리케이션과 관계형 데이터베이스(RDBMS)를 연결하는 표준 API.
  • SQL을 직접 작성하여 데이터 조회 및 변경 가능.

✅ 장점

  • 다양한 데이터베이스(MySQL, PostgreSQL, Oracle 등)와 연동 가능.
  • SQL을 직접 사용할 수 있어 세밀한 제어 가능.

❌ 단점

  • SQL을 직접 작성해야 하므로 반복 코드가 많아질 수 있음.
  • 데이터베이스 변경 시 SQL도 수정해야 함.

🔹 JDBC 연동 예제 (Java & MySQL)

import java.sql.*;

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

        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {

            while (rs.next()) {
                System.out.println("User: " + rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

3️⃣ R2DBC (Reactive Relational Database Connectivity)

  • 비동기 & 논블로킹 방식의 데이터베이스 연동 기술.
  • 리액티브 프로그래밍을 지원하는 애플리케이션(WebFlux 등)과 함께 사용됨.
  • 예시: Spring WebFlux + R2DBC + PostgreSQL

✅ 장점

  • 비동기 & 논블로킹 방식으로 고성능 애플리케이션 개발 가능.
  • Flux, Mono 같은 리액티브 스트림을 통해 데이터를 효율적으로 처리.

❌ 단점

  • 기존 JDBC 기반 애플리케이션과 호환되지 않음.
  • SQL을 직접 사용해야 하므로 ORM보다 사용이 번거로울 수 있음.

🔹 R2DBC 연동 예제 (Spring Boot & PostgreSQL)

import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Table("users")
public class User {
    @Id
    private Long id;
    private String name;
}
@Repository
public interface UserRepository extends ReactiveCrudRepository<User, Long> {
}
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public Flux<User> getUsers() {
        return userRepository.findAll(); // 비동기 Flux 반환
    }
}
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping
    public Flux<User> getUsers() {
        return userService.getUsers();
    }
}

4️⃣ ORM (Object-Relational Mapping)

  • 객체(Object)와 데이터베이스의 테이블을 매핑하여 SQL을 자동화하는 방식.
  • 예시: JPA(Java), Hibernate, MyBatis, Django ORM, SQLAlchemy

✅ 장점

  • SQL을 직접 작성하지 않아도 됨.
  • 데이터베이스 변경 시 코드 수정이 최소화됨.

❌ 단점

  • 내부적으로 SQL을 생성하므로 성능 튜닝이 어렵거나 비효율적인 쿼리가 발생할 수 있음.
  • 학습 비용이 높음.

🔹 JPA 사용 예제 (Spring Boot & Hibernate)

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    
    // Getter, Setter
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

5️⃣ REST API를 통한 연동

  • 데이터베이스와 직접 연결하지 않고, API 서버를 통해 데이터를 주고받는 방식.
  • 프론트엔드와 백엔드가 분리된 환경에서 주로 사용됨.
  • 예시: Spring Boot REST API + MySQL, Express.js + MongoDB

✅ 장점

  • 애플리케이션과 DB가 분리되므로 확장성이 높음.
  • 다양한 클라이언트(Web, Mobile)에서 같은 API를 사용할 수 있음.

❌ 단점

  • API 서버를 추가로 개발해야 함.
  • REST API 요청/응답 처리로 인해 성능이 저하될 수도 있음.

🔹 REST API 연동 예제 (Node.js & Express + MongoDB)

const express = require('express');
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/testdb');

const UserSchema = new mongoose.Schema({ name: String });
const User = mongoose.model('User', UserSchema);

const app = express();
app.use(express.json());

app.get('/users', async (req, res) => {
    const users = await User.find();
    res.json(users);
});

app.listen(3000, () => console.log('Server running on port 3000'));

6️⃣ GraphQL을 통한 연동

  • REST API의 대안으로 등장한 방식.
  • 클라이언트가 원하는 데이터만 요청할 수 있어 불필요한 데이터 전송을 줄일 수 있음.
  • 예시: Apollo Server(Node.js), Hasura, GraphQL with Django

✅ 장점

  • 필요한 데이터만 가져올 수 있어 네트워크 효율이 높음.
  • 여러 리소스를 한 번의 요청으로 가져올 수 있음.

❌ 단점

  • 설정 및 학습 비용이 높음.
  • 캐싱, 보안 처리 등 추가적인 고민이 필요함.

🔹 GraphQL 연동 예제 (Node.js & Apollo Server)

const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type User {
    id: ID!
    name: String!
  }

  type Query {
    users: [User]
  }
`;

const resolvers = {
  Query: {
    users: () => [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }]
  }
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});

Spring의 데이터베이스 연동 방식 비교

방식특징장점단점
파일 기반(DB 직접 접근)로컬 파일 형태간단하고 빠름확장성이 낮음
JDBC (SQL 직접 사용)Java 표준 API세밀한 제어 가능SQL 직접 작성 필요
R2DBC (비동기 SQL API)논블로킹 & 리액티브높은 동시성 처리기존 JDBC와 호환 안 됨
ORM (JPA, Hibernate)객체와 DB 매핑SQL 없이 개발 가능성능 튜닝 어려움
MyBatisSQL 매핑(XML, 어노테이션)SQL 제어 가능코드량이 많아질 수 있음
REST APIAPI 서버와 통신확장성이 높음API 개발 필요
GraphQL필요 데이터만 요청효율적인 데이터 조회복잡한 설정

JdbcTemplate: SQL을 직접 작성하면서도 Spring의 기능을 활용하고 싶을 때 사용
JPA (Hibernate): ORM을 활용하여 데이터베이스 연동을 간소화하고 싶을 때 사용
MyBatis: SQL을 직접 관리하면서도 XML/어노테이션을 활용하고 싶을 때 사용
R2DBC: 비동기 환경에서 데이터베이스 연동이 필요할 때 사용

0개의 댓글