0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring Bootでデータを保存する-その1(登録)

Last updated at Posted at 2024-07-14

背景・目的

Spring Bootでデータベースへのアクセスを試してみたでは、DBアクセスを試してみました。
今回は、Accessing JPA Data with RESTを試してみます。

まとめ

下記に特徴を整理します

特徴 説明
H2 ・Java SQL データベース
・高速、OSS、JDBC
・組み込み、サーバ、インメモリDB
・ブラウザベースのコンソール
・スモールフットプリント、2.5MBのJarファイル
H2の主な特徴 ・非常に高速なデータベースエンジン
・オープンソース
・Javaで書かれている
・標準SQL、JDBC APIをサポート
・組み込みおよびサーバーモード、クラスタリングのサポート
・強力なセキュリティ機能
・PostgreSQL ODBCドライバ
・複数バージョンの同時実行
H2の接続モード ・埋め込みモード(JDBC を使用したローカル接続)
・サーバー モード (TCP/IP 経由の JDBC または ODBC を使用したリモート接続)
・混合モード(ローカル接続とリモート接続を同時に実行)

概要

今回、RESTによりリクエストを受けて、H2データベースにデータを保存します。

H2

H2 Database Engineを基に整理します。

Welcome to H2, the Java SQL database. The main features of H2 are:

  • Very fast, open source, JDBC API
  • Embedded and server modes; in-memory databases
  • Browser based Console application
  • Small footprint: around 2.5 MB jar file size
  • Java SQL データベース
    • 高速、OSS、JDBC
    • 組み込み、サーバ、インメモリDB
    • ブラウザベースのコンソール
    • スモールフットプリント、2.5MBのJarファイル

Features

主な特徴

  • 非常に高速なデータベースエンジン
  • オープンソース
  • Javaで書かれた
  • 標準SQL、JDBC APIをサポート
  • 組み込みおよびサーバーモード、クラスタリングのサポート
  • 強力なセキュリティ機能
  • PostgreSQL ODBCドライバ
  • 複数バージョンの同時実行

追加機能

  • ディスクベースまたはインメモリのデータベースとテーブル、読み取り専用データベースのサポート、一時テーブル
  • トランザクション サポート (コミットされていない読み取り、コミットされた読み取り、繰り返し読み取り、スナップショット)、2 フェーズ コミット
  • 複数の接続、行レベルのロック
  • コストベースのオプティマイザー、複雑なクエリに遺伝的アルゴリズムを使用、管理不要
  • スクロール可能で更新可能な結果セットのサポート、大きな結果セット、外部結果のソート、関数は結果セットを返すことができます
  • 暗号化データベース(AES)、SHA-256パスワード暗号化、暗号化機能、SSL

SQL サポート

  • 複数のスキーマ、情報スキーマのサポート
  • 参照整合性 / カスケード制約、チェック制約による外部キー制約
  • 内部結合と外部結合、サブクエリ、読み取り専用ビュー、インラインビュー
  • トリガーと Java 関数 / ストアド プロシージャ
  • XMLやロスレスデータ圧縮を含む多くの組み込み関数
  • ラージオブジェクト(BLOB/CLOB)や配列を含む幅広いデータ型
  • シーケンスと ID 列、生成された列 (関数ベースのインデックスに使用できます)
  • ORDER BY、GROUP BY、HAVING、UNION、OFFSET / FETCH (PERCENT および WITH TIES を含む)、LIMIT、TOP、DISTINCT / DISTINCT ON (...)
  • ウィンドウ関数
  • ICU4Jライブラリのサポートを含む照合のサポート
  • ユーザーとロールのサポート
  • IBM DB2、Apache Derby、HSQLDB、MS SQL Server、MySQL、Oracle、PostgreSQL の互換モード。

セキュリティ機能

  • SQLインジェクション問題に対する解決策が含まれています
  • ユーザーパスワード認証にはSHA-256とソルトを使用します
  • サーバー モード接続の場合、ユーザー パスワードはネットワーク経由でプレーン テキストで送信されることはありません (安全でない接続を使用している場合でも、これは TCP サーバーにのみ適用され、H2 コンソールには適用されません。また、データベース URL でパスワードを設定した場合にも適用されません)。
  • すべてのデータベースファイル(データのバックアップに使用できるスクリプトファイルを含む)は、AES-128暗号化アルゴリズムを使用して暗号化できます
  • リモートJDBCドライバはTLS経由のTCP/IP接続をサポートします。
  • 内蔵ウェブサーバーはTLS経由の接続をサポートしています
  • パスワードは文字列ではなく文字配列を使用してデータベースに送信できます。

その他の機能とツール

  • フットプリントが小さい(約2.5 MB)、メモリ要件が低い
  • 複数のインデックスタイプ(Bツリー、ツリー、ハッシュ)
  • 多次元インデックスのサポート
  • CSV(カンマ区切り値)ファイルのサポート
  • リンクされたテーブルと組み込みの仮想「範囲」テーブルのサポート
  • ステートメントをサポートEXPLAIN PLAN; 洗練されたトレースオプション
  • パフォーマンスを向上させるために、データベースの終了を遅らせたり無効にしたりすることができます。
  • オートコンプリート機能を備えた Web ベースのコンソール アプリケーション (多くの言語に翻訳)
  • データベースはSQLスクリプトファイルを生成できる
  • データベースの内容をダンプできるリカバリツールが含まれています
  • 変数のサポート(たとえば、累計を計算するため)
  • 準備されたステートメントの自動再コンパイル
  • 少数のデータベースファイルを使用する
  • データの整合性を保つために、各レコードとログエントリにチェックサムを使用します。
  • 十分にテスト済み(高いコード カバレッジ、ランダム化されたストレス テスト)

接続モード

次の接続モードがサポートされています。

  • 埋め込みモード(JDBC を使用したローカル接続)
  • サーバー モード (TCP/IP 経由の JDBC または ODBC を使用したリモート接続)
  • 混合モード(ローカル接続とリモート接続を同時に実行)

実践

前提

下記を前提としています。

  • Mac
  • VSCode
  • Java 17
  • Maven 3.9.8

プロジェクトの作成

  1. VSCodeを起動します
  2. 表示>コマンドパレットをクリックします
  3. 下記を選択します
    • Spring Initializrを選択し、3.3.1
    • Java
  4. GroupIdを指定します
  5. ArtifactIdを指定します
  6. Package TypeにJarを指定します
  7. Javaバージョンに17を指定します
  8. DependencyにSpring Webを指定します
  9. 作成後、Add Workspaceをクリックします
  10. 追加されました
    image.png

pom.xmlの修正

  1. dependenciesに下記を追加します
    <dependency>
        <groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
    <dependency>
    	<groupId>com.mysql</groupId>
    	<artifactId>mysql-connector-j</artifactId>
    	<scope>runtime</scope>
    </dependency>
    
    

application.properties

  1. H2 Databaseを利用するためにapplication.propertiesに下記を追加します。
    spring.application.name=rest-db
    spring.datasource.url=jdbc:h2:mem:testdb
    spring.datasource.driverClassName=org.h2.Driver
    
    spring.h2.console.enabled=true
    

Create a Domain Object

  1. Personクラスを作成します
  2. 下記のコードを追加します
    package com.example.data.rest_db;
    
    import jakarta.persistence.Column;
    import jakarta.persistence.Entity;
    import jakarta.persistence.GeneratedValue;
    import jakarta.persistence.GenerationType; // Add this import statement
    import jakarta.persistence.Id;
    import jakarta.persistence.Table;
    
    @Entity
    @Table(name = "people")
    public class Person {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column
        private Long id;
        
        @Column(length = 50,nullable = false)
        private String firstName;
    
        @Column(length = 50,nullable = false)
        private String lastName;
    
        public Long getId() {
          return id;
        }
        public void setId(Long id) {
          this.id = id;
        }
        public String getFirstName() {
          return firstName;
        }
        public void setFirstName(String firstName) {
          this.firstName = firstName;
        }
        public String getLastName() {
          return lastName;
        }
        public void setLastName(String lastName) {
          this.lastName = lastName;
        }
    }
    
    • @Entity
      • JPAエンティティとして認識される
    • @Table(name="people")
      • エンティティクラスに割り当てられるテーブルを指定する
      • nameでテーブル名を指定(省略も可能)
    • @Id
      • プライマリーキーになる
    • @Column
      • フィールドに割り当てられるカラム名を指定する(省略した場合、フィールド名がそのままカラム名として使われる)

Create a Person Repository

  1. com.example.data.rest_db.repositoriesパッケージを作成します
  2. PersonRepositoryインタフェイスを作成します
  3. 下記のコードを追加します
    package com.example.data.rest_db.repositories;
    
    import com.example.data.rest_db.Person;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface PersonRepository extends JpaRepository<Person, Long> {
    }
    
    • @Repository
      • データアクセスを表している

Controllerを作成する

  1. WebControllerクラスを作成します
  2. 下記のコードを追加します
    package com.example.data.rest_db;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    import com.example.data.rest_db.repositories.PersonRepository;
    
    import jakarta.transaction.Transactional;
    
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    import java.util.List; // Add this import statement
    import org.springframework.web.bind.annotation.RequestMethod;
    
    
    @Controller
    public class WebController {
      @Autowired
      PersonRepository repository;
    
      @RequestMapping("/")
      public ModelAndView index(
        @ModelAttribute("formModel") Person person,
        ModelAndView mav) {
    
        mav.setViewName("index");
        mav.addObject("title","Test page");
        mav.addObject("message","This is JPA sample content.");
        List<Person> list = repository.findAll();
        mav.addObject("people", list);
    
        return mav;
      }
      
      
      @RequestMapping(value = "/", method=RequestMethod.POST)
      @Transactional
      public ModelAndView form(
        @ModelAttribute("formModel") Person person,
        ModelAndView mav) {
    
        repository.saveAndFlush(person);
        return new ModelAndView("redirect:/");
      }
    }
    
    
    
    • @Autowired
      • PersonRepositoryインスタンスをフィールドに関連付ける
      • Beanオブジェクトに関連付けを行う
    • findAllメソッド
      • PersonRepositoryには、findAllのメソッドはない
      • 継承元のJpaRepositoryに用意されている
    • @ModelAttribute
      • エンティティクラスのインスタンスを自動的に用意する
    • saveAndFlushメソッド
      • 引数のエンティティを永続化する

テンプレートの作成

  1. index.htmlを作成します
  2. 下記のコードを追加します
    <!DOCTYPE html>
    <html> 
    <head>
        <title>top page</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css">
    </head>
    <body class="container">
      <h1 class="display-4 mb-4" th:text="${title}"></h1>
      <p th:text="${message}"></p>
      <form method="post" action="/" th:object="${formModel}">
        <div class="mb-3">
          <label for="name" class="form-label">FirstName</label>
          <input type="text" class="form-control" name="firstName" th:value="*{firstName}" />
        </div>
        <div class="mb-3">
          <label for="name" class="form-label"></label>LastName</label>
          <input type="text" class="form-control" name="lastName" th:value="*{lastName}" />
        </div>
        <div class="mb-3">
          <input type="submit" class="btn btn-primary" value="Create" />
        </div>
      </form>
    
      <table class="table">
        <thread>
          <tr>
            <th>firstName</th>
            <th>lastName</th>
          </tr>
        </thread>
        <tbody>
          <tr th:each="person : ${people}">
            <td th:text="${person.firstName}"></td>
            <td th:text="${person.lastName}"></td>
          </tr>
        </tbody>
      </table>
    </body>
    </html>
    

ビルド

  1. 下記のコマンドを実行し、ビルドします
    $ mvn clean install
    $ ls -l target/rest-db-0.0.1-SNAPSHOT.jar
    -rw-r--r--  1 XXXX  XXX  47717020  7 13 23:17 target/rest-db-0.0.1-SNAPSHOT.jar
    $
    
  2. 下記のコマンドを実行します
    $ java -jar target/rest-db-0.0.1-SNAPSHOT.jar
    

確認

  1. ブラウザを開き、localhost:8080でアクセスします。表示されました
    image.png

  2. 次にH2コンソールを開きます。localhost:8080/h2-console/にアクセスします。
    image.png

1.Test Connectionをクリックします。接続されました
image.png

  1. 次にConnectをクリックします。クエリエディタのようなものが見えました。Peopeテーブルはすでに登録されているようです
    image.png

  2. SELECTを実行します。まだデータはありません
    image.png

  3. FirstNameとLastNameに入力し、Createをクリックします。登録されました
    image.png

  4. H2コンソールでも確認できました
    image.png

Spring Bootを再起動

  1. Spring Bootを再起動します

  2. トップページにアクセスすると、登録したデータは消えています。これはメモリ上に保存しているからですね
    image.png

  3. H2コンソールからも消えています
    image.png

考察

今回は、H2データベースを使ってローカルに立てたDBに対して登録を行いました。次回は更新や削除を試します。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?