1概要

この記事では、Spring JDBCモジュールの実用的な使用例について説明します。

Spring JDBCのすべてのクラスは4つの別々のパッケージに分けられます。



  • core


    – JDBCのコア機能。いくつかの重要な

このパッケージのクラスには、

JdbcTemplate



SimpleJdbcInsert、


SimpleJdbcCall

、および

NamedParameterJdbcTemplate

があります。



  • datasource


    – データソースにアクセスするためのユーティリティクラス。それはまた持っています

Java EEコンテナの外部でJDBCコードをテストするためのさまざまなデータソース実装。



  • object


    – オブジェクト指向のDBアクセス。それはできます

照会を実行し、その結果をビジネス・オブジェクトとして戻す。また、照会結果をビジネス・オブジェクトの列とプロパティーの間にマップします。



  • support




    core



    object

    の下にあるクラスのサポートクラス

パッケージ例えば。

SQLException

変換機能を提供します。


2構成

まず始めに、データソースの簡単な設定から始めましょう(この例ではMySQLデータベースを使用します)。

@Configuration
@ComponentScan("org.baeldung.jdbc")
public class SpringJdbcConfig {
    @Bean
    public DataSource mysqlDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/springjdbc");
        dataSource.setUsername("guest__user");
        dataSource.setPassword("guest__password");

        return dataSource;
    }
}

あるいは、開発やテストのために組み込みデータベースを有効に活用することもできます。これはHSQL組み込みデータベースのインスタンスを作成し、それに単純なSQLスクリプトを事前に設定するクイック設定です。

@Bean
public DataSource dataSource() {
    return new EmbeddedDatabaseBuilder()
        .setType(EmbeddedDatabaseType.HSQL)
        .addScript("classpath:jdbc/schema.sql")
        .addScript("classpath:jdbc/test-data.sql").build();
}

最後に –

datasource

にXML設定を使用しても同じことができます。

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/springjdbc"/>
    <property name="username" value="guest__user"/>
    <property name="password" value="guest__password"/>
</bean>


3

JdbcTemplate

と実行中のクエリ


3.1. 基本的なクエリ

JDBCテンプレートは、私たちが興味を持っているほとんどの機能にアクセスするための主要なAPIです。

  • コネクションの作成と終了

  • 文とストアドプロシージャコールの実行


  • ResultSet

    を反復処理して結果を返す

最初に、

JdbcTemplate

が何をできるかを見るための簡単な例から始めましょう。

int result = jdbcTemplate.queryForObject(
    "SELECT COUNT(** ) FROM EMPLOYEE", Integer.class);

また、これは簡単なINSERTです。

public int addEmplyee(int id) {
    return jdbcTemplate.update(
        "INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", 5, "Bill", "Gates", "USA");
}

パラメータを提供する標準的な構文に注意してください – `?`文字を使うこと次に、この構文の代替方法を見てみましょう。


3.2. 名前付きパラメータを使用したクエリ

  • 名前付きパラメータ** をサポートするには、フレームワークで提供されているもう1つのJDBCテンプレートである

    NamedParameterJdbcTemplate

    を使用します。

さらに、これは

JbdcTemplate

をラップし、「



」を使用してパラメータを指定するという従来の構文の代替方法を提供します。内部的には、名前付きパラメータをJDBCの「?」プレースホルダに置き換え、ラップされた

JDCTemplate

に委任してクエリを実行します。

SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("id", 1);
return namedParameterJdbcTemplate.queryForObject(
    "SELECT FIRST__NAME FROM EMPLOYEE WHERE ID = :id", namedParameters, String.class);

名前付きパラメーターの値を提供するために

MapSqlParameterSource

を使用していることに注目してください。

たとえば、Beanのプロパティを使用して名前付きパラメータを決定する以下の例を見てみましょう。

Employee employee = new Employee();
employee.setFirstName("James");

String SELECT__BY__ID = "SELECT COUNT(** ) FROM EMPLOYEE WHERE FIRST__NAME = :firstName";

SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(employee);
return namedParameterJdbcTemplate.queryForObject(SELECT__BY__ID, namedParameters, Integer.class);

以前のように手動で名前付きパラメータを指定する代わりに、

BeanPropertySqlParameterSource

実装を使用していることに注意してください。


3.3. Javaオブジェクトへのクエリ結果のマッピング

もう1つの非常に便利な機能は、RowMapperインタフェースを実装することによって、クエリ結果をJavaオブジェクトにマッピングする機能です。

たとえば、クエリによって返されたすべての行に対して、Springは行マッパーを使用してJava Beanを生成します。

public class EmployeeRowMapper implements RowMapper<Employee> {
    @Override
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
        Employee employee = new Employee();

        employee.setId(rs.getInt("ID"));
        employee.setFirstName(rs.getString("FIRST__NAME"));
        employee.setLastName(rs.getString("LAST__NAME"));
        employee.setAddress(rs.getString("ADDRESS"));

        return employee;
    }
}

その後、行マッパーをクエリAPIに渡して、完全に読み込まれたJavaオブジェクトを取得できます。

String query = "SELECT **  FROM EMPLOYEE WHERE ID = ?";
List<Employee> employees = jdbcTemplate.queryForObject(
    query, new Object[]{ id }, new EmployeeRowMapper());


4例外翻訳

Springには、独自のデータ例外階層(

DataAccessException

をルート例外として)が付属しています。そして、基礎となるすべての生の例外をそれに変換します。

そのため、低レベルの永続性例外を処理する必要がなくなり、Springが

DataAccessException

またはそのサブクラスの1つで低レベルの例外をラップするという事実から恩恵を受けます。

また、これにより、例外処理メカニズムは、使用している基礎となるデータベースから独立したものになります。

その上、デフォルトの

SQLErrorCodeSQLExceptionTranslator

では、独自の

SQLExceptionTranslator

の実装も提供できます。

これはカスタム実装の簡単な例です。整合性制約違反があるときにエラーメッセージをカスタマイズします。

public class CustomSQLErrorCodeTranslator extends SQLErrorCodeSQLExceptionTranslator {
    @Override
    protected DataAccessException customTranslate
      (String task, String sql, SQLException sqlException) {
        if (sqlException.getErrorCode() == -104) {
            return new DuplicateKeyException(
                "Custom Exception translator - Integrity constraint violation.", sqlException);
        }
        return null;
    }
}

このカスタム例外トランスレータを使用するには、

setExceptionTranslator()

メソッドを呼び出してそれを

JdbcTemplate

に渡す必要があります。

CustomSQLErrorCodeTranslator customSQLErrorCodeTranslator = new CustomSQLErrorCodeTranslator();
jdbcTemplate.setExceptionTranslator(customSQLErrorCodeTranslator);


5 SimpleJdbcクラスを使ったJDBC操作


SimpleJdbc

クラスを使用すると、SQL文を簡単に構成および実行できます。これらのクラスはデータベースメタデータを使用して基本的なクエリを構築します。


SimpleJdbcInsert

および

SimpleJdbcCall

クラスは、挿入およびストアドプロシージャ呼び出しを実行するためのより簡単な方法を提供します。


5.1

SimpleJdbcInsert


最小限の設定で簡単なinsert文を実行する方法を見てみましょう。

  • INSERT文は

    SimpleJdbcInsert

    ** の設定に基づいて生成されます。テーブル名、列名、および値を指定するだけです。

まず、

SimpleJdbcInsert

を作成しましょう。

SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("EMPLOYEE");

次に、列の名前と値を入力して、操作を実行しましょう。

public int addEmplyee(Employee emp) {
    Map<String, Object> parameters = new HashMap<String, Object>();
    parameters.put("ID", emp.getId());
    parameters.put("FIRST__NAME", emp.getFirstName());
    parameters.put("LAST__NAME", emp.getLastName());
    parameters.put("ADDRESS", emp.getAddress());

    return simpleJdbcInsert.execute(parameters);
}

さらに、

データベースで主キー

を生成できるようにするために、

executeAndReturnKey()

APIを使用できます。自動生成される実際の列も設定する必要があります。

SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
                                        .withTableName("EMPLOYEE")
                                        .usingGeneratedKeyColumns("ID");

Number id = simpleJdbcInsert.executeAndReturnKey(parameters);
System.out.println("Generated id - " + id.longValue());

最後に、

BeanPropertySqlParameterSource



MapSqlParameterSource.

を使用してこのデータを渡すこともできます。


5.2.

SimpleJdbcCall


を使用したスト​​アドプロシージャ

また、ストアドプロシージャの実行を見てみましょう – 私たちは

SimpleJdbcCall

抽象化を利用します

SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource)
                             .withProcedureName("READ__EMPLOYEE");

public Employee getEmployeeUsingSimpleJdbcCall(int id) {
    SqlParameterSource in = new MapSqlParameterSource().addValue("in__id", id);
    Map<String, Object> out = simpleJdbcCall.execute(in);

    Employee emp = new Employee();
    emp.setFirstName((String) out.get("FIRST__NAME"));
    emp.setLastName((String) out.get("LAST__NAME"));

    return emp;
}


6. バッチ操作

もう1つの単純なユースケース – 複数の操作をまとめてバッチ処理すること。


6.1.

JdbcTemplate


を使用した基本的なバッチ操作


JdbcTemplateを使用すると、

batchUpdate()

APIを介して

バッチ操作を実行できます。

ここで興味深い部分は、簡潔で非常に有用な

BatchPreparedStatementSetter

実装です。

public int[]batchUpdateUsingJdbcTemplate(List<Employee> employees) {
    return jdbcTemplate.batchUpdate("INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)",
        new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setInt(1, employees.get(i).getId());
                ps.setString(2, employees.get(i).getFirstName());
                ps.setString(3, employees.get(i).getLastName());
                ps.setString(4, employees.get(i).getAddress();
            }
            @Override
            public int getBatchSize() {
                return 50;
            }
        });
}


6.2.

NamedParameterJdbcTemplate


を使用したバッチ操作


NamedParameterJdbcTemplate



batchUpdate()

APIを使用してバッチ操作を行うこともできます。

このAPIは以前のものよりも単純です – パラメータ値を設定するための内部プリペアドステートメントセッターを持っているので、パラメータを設定するために特別なインターフェースを実装する必要はありません。

代わりに、パラメータ値を

SqlParameterSource

の配列として

batchUpdate()

メソッドに渡すことができます。

SqlParameterSource[]batch = SqlParameterSourceUtils.createBatch(employees.toArray());
int[]updateCounts = namedParameterJdbcTemplate.batchUpdate(
    "INSERT INTO EMPLOYEE VALUES (:id, :firstName, :lastName, :address)", batch);
return updateCounts;


7. Spring Boot

付きのSpring JDBC

Spring Bootは、リレーショナルデータベースでJDBCを使用するためのスターター

spring-boot-starter-jdbc

を提供します。

すべてのSpring Bootスターターと同様に、これは私たちのアプリケーションを素早く立ち上げるのにも役立ちます。


7.1. Mavenの依存関係

私たちはhttps://search.maven.org/search?q=a:spring-boot-starter-jdbc[

spring-boot-starter-jdbc

]依存関係とデータベースの依存関係を必要とします。それを使用します。私たちの場合、これは

MySQL

です。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>


7.2. 構成

Spring Bootは自動的にデータソースを設定します。プロパティを

properties

ファイルに指定するだけです。

spring.datasource.url=jdbc:mysql://localhost:3306/springjdbc
spring.datasource.username=guest__user
spring.datasource.password=guest__password

これらの設定を行うだけで、アプリケーションは起動して実行され、他のデータベース操作に使用できます。

前のセクションで標準のSpringアプリケーションについて明示した構成は、Spring Bootの自動構成の一部として含まれています。


8結論

この記事では、Spring FrameworkのJDBC抽象化について調べ、Spring JDBCが提供するさまざまな機能を実際の例で説明しました。

また、Spring Boot JDBCスターターを使用してSpring JDBCをすばやく開始する方法も検討しました。