GrapeCity.devlog

グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉の、製品のTIPSや発売などに関する最新情報をお届けします。

GrapeCity

Wijmo & SpringでつくるCRUDアプリケーション(2)アプリ開発編

Wijmo & SpringでつくるCRUDアプリケーション(2)アプリ開発編

みなさん、こんにちは。今回は「Wijmo & SpringでつくるCRUDアプリケーション」シリーズの後編となる「アプリ開発編」をお送りいたします。前編の記事では「環境構築編」として、「JDK」と「Spring」による開発環境とデータベース「MySQL」の準備を行いました。ここからはいよいよアプリケーションを開発していきます。

アプリケーション概要

実際の作業に入る前に、これから開発するアプリケーションについて概要を整理したいと思います。タイトルにもある通り、今回開発するアプリケーションはMySQLデータの生成(Create)、読込(Read)、更新(Update)、削除(Delete)を行うCRUDアプリケーションです。以下は今回開発するアプリケーションの構造とデータの流れを簡易的に示した概念図になります。

アプリケーションの構造とデータの流れ

フロントエンドに「Wijmo(ウィジモ)」のコントロール(FlexGridCollectionView)、バックエンドにSQLデータベースを用意し、この間の通信(データベースからのデータ取得やデータ操作)をWebAPIで行うようにアプリケーションを構築します。スクラッチでは大変難しい開発ですが、Springにある数々の機能を活用することで簡単に素早くアプリケーションを完成させることができますので、早速やってみましょう。

プロジェクトの作成

最初に、今回開発するアプリケーションのプロジェクトをSpring Tool Suite(以降、STS)上に作成します。STSを起動し、以下の手順に沿ってプロジェクトを作成してください。

  1. メニューからFileNewSpring Starter Projectを選択します。
  2. New Spring Starter Project画面で、Nameに"spring-demo"と入力して、Nextボタンをクリックします。
  3. New Spring Starter Project Dependencies画面で、次の4つをチェックして、Finishボタンをクリックすると、プロジェクトが作成されます。
  • WebSpring Web
  • SQLMySQL Driver
  • SQLSpring Data JPA
  • Template EnginesThymeleaf

この際、チェックした依存関係に応じてプロジェクトで使用するライブラリが設定されるようになっています。各ライブラリの機能概要は以下の通りです。

Spring WebWeb開発を効率的にするライブラリ
MySQL DriverMySQLを扱うためのライブラリ
Spring Data JPAデータベース操作を簡単に行うためのライブラリ
ThymeleafHTMLテンプレートを取り扱うためのライブラリ

データベースの設定

次にデータベースの設定をして、アプリケーションが前編で作成したMySQLのデータテーブルにアクセスできるようにします。STSのPackage Explorerツリーにあるspring-demosrc/main/resourcesapplication.propertiesファイルを開いて、次のコードを記述します。後述するデータベース処理(エンティティやリポジトリによる処理)の際、この設定に基づいて、Springフレームワークが自動的にMySQLへの接続を行います。

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=パスワード

※"test"はDB名です
※"パスワード"にはMySQLをセットアップした際に設定したパスワードを記述してください。

エンティティの作成

データベースの設定が終わったら、いよいよ本格的にソフトウェア処理の実装に入って行きます。はじめに作るのはエンティティ・クラスです。これはデータベースで永続化される情報を保持するクラスとなっており、そのオブジェクトはアプリケーション処理のなかでデータベースのレコードデータに相当する役割を果たします。

以下の手順に沿ってエンティティ・クラスを作成してください。

  1. STSのPackage Explorerツリーで"spring-demo"を選択します。
  2. メニューからFileNewClassを選択します。
  3. Nameに"Order"と入力して、Finishボタンをクリックします。
  4. Order.javaファイルに次のコードを記述します。
package com.example.demo;

import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="orders")
public class Order {
    @Id
    @Column(name="id")
    private Integer id;
    @Column(name="product")
    private String product;
    @Column(name="date")
    private Date date;
    @Column(name="price")
    private Integer price;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getProduct() {
        return product;
    }
    public void setProduct(String product) {
        this.product = product;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public Integer getPrice() {
        return price;
    }
    public void setPrice(Integer price) {
        this.price = price;
    }
}

リポジトリの作成

次に「リポジトリ」という機能を使って、データベースに対するCRUD処理を実装します。後述する理由により、コード量は非常に少量です。

以下の手順に沿ってリポジトリ・クラスを作成してください。

  1. STSのPackage Explorerツリーで"spring-demo"を選択します。
  2. メニューからFileNewClassを選択します。
  3. Nameに"OrderRepository"と入力して、Finishボタンをクリックします。
  4. OrderRepository.javaファイルに次のコードを記述します。
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository <Order, Integer> {
}

「リポジトリ」は「Spring Data」ライブラリによって提供されているインターフェースです。データベースに対するCRUD処理などが定義されています。通常、利用するデータベースに合わせて実装を行い使用しますが、今回は"JpaRepository"という既存のクラスを継承して使用しているので、新たにCRUD処理を実装する必要はありません。

サービスの作成

ここまででアプリケーションからデータベース操作をする準備が整いました。次は、フロントエンドからのリクエストとデータベース操作処理をつなぐ、「サービス」処理を作成します。

以下の手順に沿ってサービス・クラスを作成してください。

  1. STSのPackage Explorerツリーで"spring-demo"を選択します。
  2. メニューからFileNewClassを選択します。
  3. Nameに"OrderService"と入力して、Finishボタンをクリックします。
  4. OrderService.javaファイルに次のコードを記述します。
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service
@Transactional
public class OrderService {
    @Autowired
    OrderRepository orderRepository;

    public List<Order> findAll() {
        return orderRepository.findAll();
    }

    public Order save(Order order) {
        return orderRepository.save(order);
    }

    public void deleteById(Integer id) {
        orderRepository.deleteById(id);
    }
}

コントローラの作成

バックエンド処理の仕上げに、コントローラを作成します。コントローラ・クラスにはCRUD処理に対応するURLを定義し、そのURLに対応したサービスの呼び出しを実装します。

以下の手順に沿ってコントローラ・クラスを作成してください。

  1. STSのPackage Explorerツリーで"spring-demo"を選択します。
  2. メニューからFileNewClassを選択します。
  3. Nameに"OrderController"と入力して、Finishボタンをクリックします。
  4. OrderController.javaファイルに次のコードを記述します。
package com.example.demo;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("api/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @RequestMapping(method = RequestMethod.GET)
    List<Order> getOrders() {
        return orderService.findAll();
    }

    @RequestMapping(method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    Order insertOrder(@Validated @RequestBody Order order) {
        return orderService.save(order);
    }

    @RequestMapping(value = "{id}", method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.OK)
    Order updateOrder(@PathVariable("id") Integer id, @Validated @RequestBody Order order) {
        order.setId(id);
        return orderService.save(order);
    }

    @RequestMapping(value = "{id}", method = RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.OK)
    void deleteOrder(@PathVariable("id") Integer id) {
        orderService.deleteById(id);
    }
}

HTMLテンプレートの作成

ここからフロントエンド関連の開発です。まずはアプリケーションで表示されるWebページの雛形、HTMLテンプレートを作ります。内容のほとんどは通常のHTMLと変わりませんが、依存関係で設定したテンプレートライブラリ「Thymeleaf」の機能を使い、"th:src"でJavaScript処理を展開している部分が特徴です。

以下の手順に沿ってHTMLテンプレートを作成します。

  1. STSのPackage Explorerツリーで"spring-demo"を選択します。
  2. src/main/resourcestemplatesフォルダを右クリックして、メニューからNewOtherを選択します。
  3. Select a wizard画面で、WebHTML Fileを選択して、Nextボタンをクリックします。
  4. ファイル名に"index.html"と入力して、Finishボタンをクリックします。
  5. index.htmlファイルに次のコードを記述します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Wijmo DB接続サンプル</title>
<!-- Wijmo -->
<link rel="stylesheet" href="https://cdn.grapecity.com/wijmo/5.latest/styles/wijmo.min.css">
<script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.min.js"></script>
<script src="https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.min.js"></script>
<script src="https://cdn.grapecity.com/wijmo/5.latest/controls/cultures/wijmo.culture.ja.min.js"></script>
</head>
<body>
    <h2>Wijmo & Spring CRUDアプリケーション</h2>
    <button onclick="update()">更新</button>
    <div id="flexGrid"></div>
    <script th:src="@{/app.js}"></script>
</body>
</html>

※上記のコードでは、例としてWijmoの参照として弊社デモサイトで参照しているWijmoトライアル版のURLを設定しています。実際の評価、開発、運用に際しては弊社ウェブサイトよりダウンロードしたトライアル版、およびご購入された製品版ライブラリをご利用ください。

Wijmoを使ったJavaScript処理の実装

次にUI処理をJavaScriptで実装していきます。以下の手順に沿ってJSファイルを作成し処理を実装します。なお、処理の詳細についてはコード内のコメントをご参照ください。

  1. STSのPackage Explorerツリーで"spring-demo"を選択します。
  2. src/main/resourcesstaticフォルダを右クリックして、メニューからNewOtherを選択します。
  3. Select a wizard画面で、JavaScriptJavaScript Source Fileを選択して、Nextボタンをクリックします。
  4. ファイル名に"app.js"と入力して、Finishボタンをクリックします。
  5. app.jsファイルに次のコードを記述します。
var cv = new wijmo.collections.CollectionView(null, {
    // CollectionViewのtrackChangesプロパティを設定して
    // 変更データの追跡を有効にします。
    trackChanges: true
});
var flexGrid = new wijmo.grid.FlexGrid('#flexGrid', {
    autoGenerateColumns: false,
    itemsSource: cv,
    columns: [
        { header: 'ID', binding: 'id', width: 60 },
        { header: '商品名', binding: 'product', width: 200 },
        { header: '受注日', binding: 'date', width: 120 },
        { header: '金額', binding: 'price', width: 100, format: 'c' }
    ],
    allowAddNew: true,
    allowDelete: true
});

// ------------------------------------
// Read:読み込み処理
// wijmo.httpRequestメソッドでHTTP要求を送信します
// ------------------------------------
wijmo.httpRequest('/api/orders', {
    success: function (xhr) {
        cv.sourceCollection = JSON.parse(xhr.response, function (key, value) {
            if (key == 'date') {
                // MySQLの日付値はyyyy-MM-ddという形式の文字列として取得されるので、
                // Globalize.parseDateメソッドでJSの日付値に変換します。
                return wijmo.Globalize.parseDate(value, 'yyyy-MM-dd');
            } else {
                return value;
            }
        });
    }
});

// 更新ボタンクリック時の処理
// 変更データを取得して、CRUD処理のHTTP要求を送信します。
function update() {
    // Update:更新処理
    for (var i = 0; i < cv.itemsEdited.length; i++) {
        wijmo.httpRequest('/api/orders/' + cv.itemsEdited[i].id, {
            method: 'PUT',
            data: cv.itemsEdited[i]
        });
    }
    // Create:生成処理
    for (var i = 0; i < cv.itemsAdded.length; i++) {
        wijmo.httpRequest('/api/orders/', {
            method: 'POST',
            data: cv.itemsAdded[i]
        });
    }
    // Delete:削除処理
    for (var i = 0; i < cv.itemsRemoved.length; i++) {
        wijmo.httpRequest('/api/orders/' + cv.itemsRemoved[i].id, {
            method: 'DELETE'
        });
    }
}

アプリの実行

ここまでで、処理の実装作業は全て完了しました。いよいよ動作確認です。以下の手順に沿ってアプリケーションをビルドして実行してみましょう。

  1. Package Explorer画面で、"spring-demo"を選択します。
  2. メニューからRun AsSpring Boot Appを選択します。
  3. Console画面に次のようなログが出力され、アプリが実行されます。


アプリケーションのビルドと実行
ビルド・実行時のSTSコンソール画面

普段お使いのウェブブラウザを起動し、localhost:8080にアクセスしてアプリの動作を確認していきましょう。"CRUD"の各処理についてひとつずつ見てきたいと思います。

読込処理(Read)

アプリを実行すると、画面に配置されたFlexGridにDBデータが表示されます。データベースからの読込処理が正常に動作していることを確認できました。

読込処理

生成処理(Create)

次に生成処理について確認したいと思います。FlexGridにある新規行(空白の行)に対して新しいデータを入力し、更新ボタンをクリックしてページを再読み込みしてみましょう。新しいデータの追加(生成)を確認できるかと思います。

生成処理

更新処理(Update)

FlexGridにある任意データ内容を変更して、更新ボタンをクリックしページを再読み込みすると、データが更新されていることが確認できます。画像はFlexGridの最終行データを編集・更新した例です。

更新処理

削除処理(Delete)

FlexGridの最終行を選択(行ヘッダをクリック)してからDeleteキーを押下すると、行が削除されます。更新ボタンをクリックしてページを再読み込みすると、データが削除されていることを確認できます。

削除処理

多様なバックエンドのお供に、グレープシティのJS製品

今回はWijmoコントロールをUIとしながら、バックエンドのデータベースに対し読込、生成、更新、削除処理を実施するSpringアプリケーションを作成しました。Java初挑戦といった方もフレームワークの恩恵を受け意外と簡単に開発を終えることができたのではないでしょうか。Spring、大変便利なフレームワークですね。

また同時に、Wijmoの利便性も実感いただけたのではと思います。今回のようにフロントエンドとバックエンド間のやり取りをWebAPIとJSONデータで構築すれば、Springに限らず、どのようなバックエンド、フレームワークでもそのフロントエンドにWijmoを利用することが可能です。

Wijmoのほか、グレープシティのJS製品ではいずれも同様のやり方が可能となっていますので、SpringやJava以外のテクノロジで開発を実施されている皆様もぜひ一度、弊社のJavaScript製品をお試しいただければ幸いです。

  • グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉ではエンジニア経験者を幅広く募集しています。
  • グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉の製品のデモアプリケーションをお試しください。