JdbcTemplate을 사용할 때 자동 증가된 ID를 얻는 방법

22623 단어 springbootspring
이 기사에서는 JdbcTemplate 또는 NamedParameterJdbcTemplate 를 사용할 때 자동 증가 ID를 얻는 방법을 설명합니다.

테이블(MYSQL)



다음 데이터 테이블을 사용할 수 있다고 가정합니다.

CREATE TABLE `user` (
  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `balance` decimal(10,2) DEFAULT NULL,
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `enabled` tinyint unsigned NOT NULL,
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `update_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='user';


보시다시피 id 필드는 자동 증가 열입니다.

Jdbc 템플릿


spring-jdbc는 데이터 삽입 후 자동 증가된 ID 값을 가져오는 GeneratedKeyHolder 개체를 제공합니다.

package io.springcloud.test;

import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.time.LocalDateTime;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import io.springboot.demo.DemoApplication;
import lombok.extern.slf4j.Slf4j;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@Slf4j
public class DemoApplicationTest {

    @Autowired
    DataSource dataSource;

    @Test
    @Transactional
    @Rollback(false)
    public void test() {

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        // Create GeneratedKeyHolder object
        GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder();

        String sql = "INSERT INTO `user`(`balance`, `create_at`, `enabled`, `name`, `update_at`) VALUES(?, ?, ?, ?, ?);";

        // To insert data, you need to pre-compile the SQL and set up the data yourself.
        int rowsAffected = jdbcTemplate.update(conn -> {

            // Pre-compiling SQL
            PreparedStatement preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

            // Set parameters
            preparedStatement.setBigDecimal(1, new BigDecimal("15.88"));
            preparedStatement.setObject(2, LocalDateTime.now());
            preparedStatement.setBoolean(3, Boolean.TRUE);
            preparedStatement.setString(4, "JdbcTemplate");
            preparedStatement.setObject(5, LocalDateTime.now());

            return preparedStatement;

        }, generatedKeyHolder);


        // Get auto-incremented ID
        Integer id = generatedKeyHolder.getKey().intValue();

        log.info("rowsAffected = {}, id={}", rowsAffected, id);
    }
}


출력 로그는 다음과 같으며 모든 것이 정상입니다.

2022-06-06 17:03:11.240  INFO 8964 --- [           main] io.springcloud.test.DemoApplicationTest  : rowsAffected = 1, id=11


NamedParameterJdbcTemplate


NamedParameterJdbcTemplate 의 사용법은 JdbcTemplate 와 크게 다르지 않습니다. 그러나 ? 대신 SQL에서 명명된 매개변수를 사용하는 것을 지원합니다. 이 기능을 통해 개체 또는 맵을 매개변수로 직접 사용할 수 있습니다. 매우 친절합니다. 실제 개발에서는 사용하는 것이 더 좋습니다.

The NamedParameterJdbcTemplate also provides more rich methods, you can refer to the documentation to learn more.



import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import io.springboot.demo.DemoApplication;
import lombok.extern.slf4j.Slf4j;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@Slf4j
public class DemoApplicationTest {

    @Autowired
    DataSource dataSource;

    @Test
    @Transactional
    @Rollback(false)
    public void test() {

        NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

        // The GeneratedKeyHolder object is used to get the auto-incrementing ID.
        GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder();

        // SQL placeholders can use named parameters instead of "?".
        String sql = "INSERT INTO `user`(`balance`, `create_at`, `enabled`, `name`, `update_at`) VALUES(:balance, :create_at, :enabled, :name, :update_at);";

        // params
        Map<String, Object> params = new HashMap<>();
        params.put("balance", new BigDecimal("25.66"));
        params.put("create_at", LocalDateTime.now());
        params.put("enabled", Boolean.FALSE);
        params.put("name", "NamedParameterJdbcTemplate");
        params.put("update_at", LocalDateTime.now());

        int rowsAffected = namedParameterJdbcTemplate.update(sql, new MapSqlParameterSource(params), generatedKeyHolder);

        Integer id = generatedKeyHolder.getKey().intValue();

        log.info("rowsAffected = {}, id={}", rowsAffected, id);
    }
}



출력 로그는 다음과 같으며 모든 것이 정상입니다.

2022-06-06 17:10:19.167  INFO 12408 --- [           main] io.springcloud.test.DemoApplicationTest  : rowsAffected = 1, id=12


요약


GeneratedKeyHolder 개체를 통해 자동 증가된 ID를 가져옵니다.
JdbcTemplate 를 사용하는 경우 SQL을 사전 컴파일하고 매개변수를 직접 설정해야 하므로 더 번거롭습니다. NamedParameterJdbcTemplate를 사용하는 것이 더 좋습니다.
GeneratedKeyHolder에는 다른 방법이 있습니다. 자세한 내용은 documentation을 참조하십시오.

마지막으로 삽입한 2개의 데이터를 살펴봅니다.

mysql> select * from `user`;
+----+---------+---------------------+---------+----------------------------+---------------------+
| id | balance | create_at           | enabled | name                       | update_at           |
+----+---------+---------------------+---------+----------------------------+---------------------+
| 11 |   15.88 | 2022-06-06 17:03:11 |       1 | JdbcTemplate               | 2022-06-06 17:03:11 |
| 12 |   25.66 | 2022-06-06 17:10:19 |       0 | NamedParameterJdbcTemplate | 2022-06-06 17:10:19 |
+----+---------+---------------------+---------+----------------------------+---------------------+
2 rows in set (0.00 sec)


Reference https://www.springcloud.io/post/2022-06/jdbctemplate-id/

좋은 웹페이지 즐겨찾기