SpringBoot 를 배워보자

두 테이블에 공통된 대조 필드가 있을 때, 사용자가 원하는 필드들만 출력되도록 동적 쿼리를 작성

_Blue_Sky_ 2024. 12. 2. 23:15
728x90
728x90

 

MyBatis에서 동적으로 조인하는 예제를 작성하려면, 조건에 따라 두 테이블 a와 b를 조인하는 방식입니다. 각 테이블에서 어떤 출력 필드를 포함할지 동적으로 결정하도록 설정할 수 있습니다.

여기서는 두 테이블에 공통된 대조 필드가 있을 때, 사용자가 원하는 필드들만 출력되도록 동적 쿼리를 작성합니다. 예를 들어, 테이블 a와 b에는 id라는 공통 대조 필드가 있고, 출력 필드는 각 테이블에서 특정 컬럼만 선택할 수 있습니다.

1. SQL Mapper 파일 (XML)

<mapper namespace="com.example.mapper.UserMapper">

  <!-- 동적 조인 쿼리 -->
  <select id="selectJoinedUsers" resultMap="userResultMap">
    SELECT
      <if test="fieldsA != null">
        <foreach collection="fieldsA" item="field" separator=",">
          a.${field}
        </foreach>
      </if>

      <if test="fieldsB != null">
        <foreach collection="fieldsB" item="field" separator=",">
          b.${field}
        </foreach>
      </if>

    FROM a
    JOIN b
    ON a.id = b.id
    WHERE 1=1
    <if test="filter != null">
      <foreach collection="filter" item="filterCondition" separator="AND">
        ${filterCondition}
      </foreach>
    </if>
  </select>

</mapper>

2. Java 인터페이스

package com.example.mapper;

import com.example.domain.User;
import java.util.List;

public interface UserMapper {
  List<User> selectJoinedUsers(List<String> fieldsA, List<String> fieldsB, List<String> filter);
}

 

728x90

3. Service 클래스 (Java)

package com.example.service;

import com.example.domain.User;
import com.example.mapper.UserMapper;
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> getJoinedUsers(List<String> fieldsA, List<String> fieldsB, List<String> filter) {
    return userMapper.selectJoinedUsers(fieldsA, fieldsB, filter);
  }
}

4. Controller 클래스 (Java)

package com.example;

import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class UserController {

  @Autowired
  private UserService userService;

  public List<User> getJoinedUsers(@RequestParam List<String> fieldsA, 
                                    @RequestParam List<String> fieldsB, 
                                    @RequestParam(required = false) List<String> filter) {
    return userService.getJoinedUsers(fieldsA, fieldsB, filter);
  }
}

동적 SQL 설명

  1. 동적 컬럼 선택 (fieldsA, fieldsB):
    • fieldsA와 fieldsB는 각각 테이블 a와 b에서 출력할 컬럼을 동적으로 지정하는 리스트입니다.
    • foreach를 사용하여 해당 필드들을 동적으로 콤마로 구분하여 출력합니다.
  2. 동적 조인 (JOIN):
    • 두 테이블 a와 b는 id라는 공통 필드로 조인합니다. a.id = b.id 조건은 고정입니다.
  3. 동적 필터링 (filter):
    • 사용자가 조건을 제공할 수 있도록 filter 리스트를 매개변수로 받습니다. 각 조건은 AND로 구분되며, <foreach>를 사용하여 동적으로 추가됩니다.
    • 예를 들어, filter 리스트가 ["a.name = 'John'", "b.age > 30"]일 경우, WHERE 절은 WHERE a.name = 'John' AND b.age > 30이 됩니다.
728x90

예시 사용

// Service 호출 예시
List<String> fieldsA = Arrays.asList("name", "email");
List<String> fieldsB = Arrays.asList("age", "status");
List<String> filter = Arrays.asList("a.name = 'John'", "b.age > 30");

List<User> users = userService.getJoinedUsers(fieldsA, fieldsB, filter);

SQL 실행 결과

이렇게 위의 조건을 사용하면, 다음과 같은 SQL이 동적으로 생성됩니다:

SELECT a.name, a.email, b.age, b.status
FROM a
JOIN b ON a.id = b.id
WHERE a.name = 'John' AND b.age > 30

동적 SQL의 핵심

  • 동적 컬럼 선택: 사용자가 선택한 필드만 출력되도록 하여, 필요 없는 데이터를 제외하고 결과를 반환합니다.
  • 동적 필터링: 사용자가 지정한 조건에 맞는 데이터를 필터링하여 반환합니다.
  • 조인 처리: a와 b 테이블의 id 컬럼을 기준으로 JOIN을 수행합니다.

이러한 방식으로 MyBatis에서 동적으로 조인할 때, 쿼리에서 출력할 필드나 조건을 유연하게 처리할 수 있습니다.

728x90
728x90