JdbcTemplate IN 절에서 값 목록 사용

1. 소개

SQL 문에서 IN 연산자를 사용하여 표현식이 목록의 값과 일치하는지 테스트 할 수 있습니다. 따라서 여러 OR 조건 대신 IN 연산자를 사용할 수 있습니다.

이 튜토리얼에서는 값 목록을 Spring JDBC 템플릿 쿼리의 IN 절에 전달하는 방법을 보여줍니다.

2. IN 절에 목록 매개 변수 전달

IN 연산자를 사용하면 WHERE 절에 여러 값을 지정할 수 있습니다. 예를 들어, 지정된 ID 목록에 ID가있는 모든 직원을 찾는 데 사용할 수 있습니다.

SELECT * FROM EMPLOYEE WHERE id IN (1, 2, 3)

일반적으로 IN 절 내의 총 값 수는 가변적입니다. 따라서 동적 값 목록을 지원할 수있는 자리 표시자를 만들어야합니다.

2.1. 와 JdbcTemplate을

함께 JdbcTemplate을 , 우리가 사용할 수있는 '?' 값 목록에 대한 자리 표시 자로 문자. 개수 '?' 문자는 목록의 크기와 동일합니다.

List getEmployeesFromIdList(List ids) { String inSql = String.join(",", Collections.nCopies(ids.size(), "?")); List employees = jdbcTemplate.query( String.format("SELECT * FROM EMPLOYEE WHERE id IN (%s)", inSql), ids.toArray(), (rs, rowNum) -> new Employee(rs.getInt("id"), rs.getString("first_name"), rs.getString("last_name"))); return employees; } 

이 메서드에서는 먼저 ids.size () '?' 를 포함하는 자리 표시 자 문자열을 생성합니다. 쉼표로 구분 된 문자. 그런 다음이 문자열을 SQL 문의 IN 절에 넣습니다. 예를 들어, ids 목록 에 세 개의 숫자가있는 경우 SQL 문은 다음과 같습니다.

SELECT * FROM EMPLOYEE WHERE id IN (?,?,?)

에서 쿼리 방법, 우리는 통과 IDS의 IN 절 안에 자리와 일치하는 매개 변수로 목록을. 이런 식으로 입력 값 목록을 기반으로 동적 SQL 문을 실행할 수 있습니다.

2.2. 로 하는 NamedParameterJdbcTemplate

동적 값 목록을 처리하는 또 다른 방법은 NamedParameterJdbcTemplate 을 사용하는 것 입니다. 예를 들어 입력 목록에 대한 명명 된 매개 변수를 직접 만들 수 있습니다.

List getEmployeesFromIdListNamed(List ids) { SqlParameterSource parameters = new MapSqlParameterSource("ids", ids); List employees = namedJdbcTemplate.query( "SELECT * FROM EMPLOYEE WHERE id IN (:ids)", parameters, (rs, rowNum) -> new Employee(rs.getInt("id"), rs.getString("first_name"), rs.getString("last_name"))); return employees; }

이 메서드에서는 먼저 입력 ID 목록을 포함 하는 MapSqlParameterSource 개체를 생성 합니다. 그런 다음 동적 값 목록을 나타내는 데 하나의 명명 된 매개 변수 만 사용합니다.

내부적으로 NamedParameterJdbcTemplate 은 '?'를 명명 된 매개 변수로 대체합니다. 자리 표시 자와 JdbcTemplate 을 사용 하여 쿼리를 실행합니다.

3. 큰 목록 처리

목록에 많은 수의 값이있는 경우이를 JdbcTemplate 쿼리에 전달할 다른 방법을 고려해야 합니다.

예를 들어 Oracle 데이터베이스는 IN 절에서 1,000 개 이상의 리터럴을 지원하지 않습니다.

이를 수행하는 한 가지 방법 은 목록에 대한 임시 테이블만드는 것 입니다. 그러나 데이터베이스마다 임시 테이블을 만드는 방법이 다를 수 있습니다. 예를 들어, CREATE GLOBAL TEMPORARY TABLE 문을 사용하여 Oracle 데이터베이스에 임시 테이블을 만들 수 있습니다.

H2 데이터베이스에 대한 임시 테이블을 생성 해 보겠습니다.

List getEmployeesFromLargeIdList(List ids) { jdbcTemplate.execute("CREATE TEMPORARY TABLE IF NOT EXISTS employee_tmp (id INT NOT NULL)"); List employeeIds = new ArrayList(); for (Integer id : ids) { employeeIds.add(new Object[] { id }); } jdbcTemplate.batchUpdate("INSERT INTO employee_tmp VALUES(?)", employeeIds); List employees = jdbcTemplate.query( "SELECT * FROM EMPLOYEE WHERE id IN (SELECT id FROM employee_tmp)", (rs, rowNum) -> new Employee(rs.getInt("id"), rs.getString("first_name"), rs.getString("last_name"))); jdbcTemplate.update("DELETE FROM employee_tmp"); return employees; }

여기에서 먼저 입력 목록의 모든 값을 보관할 임시 테이블을 만듭니다. 그런 다음 입력 목록의 값을이 테이블에 삽입합니다.

결과 SQL 문 에서 IN 절의 값은 임시 테이블 에서 가져 왔으며 많은 자리 표시자가있는 IN 절을 구성하지 않았습니다.

마지막으로 쿼리를 완료 한 후 나중에 다시 사용할 수 있도록 임시 테이블을 정리합니다.

4. 결론

이 자습서에서는 JdbcTemplateNamedParameterJdbcTemplate 을 사용 하여 SQL 쿼리의 IN 절에 대한 값 목록을 전달하는 방법을 보여주었습니다 . 또한 임시 테이블을 사용하여 많은 수의 목록 값을 처리하는 다른 방법을 제공했습니다.

항상 그렇듯이 기사의 소스 코드는 GitHub에서 사용할 수 있습니다.