Background
Speedment は、Java エンティティを生成し、データベースとの通信プロセスを管理するために使用できるオープンソース ツール セットです。グラフィカル ツールを使用してデータベースに接続し、ドメイン モデルを表す ORM フレームワーク コードの完全なセットを生成できます。ただし、Speedment は単なるコード ジェネレーターではなく、アプリケーションにプラグインできるランタイム プログラムであり、Java 8 ストリーミング コードを最適化された SQL クエリに変換できるようになります。これもこの記事で具体的にお話しする部分です。
コードを生成
Maven プロジェクトで Speedment の使用を開始するには、次のコード行を pom.xml ファイルに追加する必要があります。この例では MySQL を使用していますが、PostgreSQL または MariaDB の使用を選択することもできます。 Oracle のような独自のデータベースは、企業顧客が利用できます。
Pom.xml
<properties> <speedment.version>3.0.1</speedment.version> <db.groupId>mysql</db.groupId> <db.artifactId>mysql-connector-java</db.artifactId> <db.version>5.1.39</db.version></properties><dependencies> <dependency> <groupId>com.speedment</groupId> <artifactId>runtime</artifactId> <version>${speedment.version}</version> <type>pom</type> </dependency> <dependency> <groupId>${db.groupId}</groupId> <artifactId>${db.artifactId}</artifactId> <version>${db.version}</version> </dependency></dependencies><build> <plugins> <plugin> <groupId>com.speedment</groupId> <artifactId>speedment-maven-plugin</artifactId> <version>${speedment.version}</version> <dependencies> <dependency> <groupId>${db.groupId}</groupId> <artifactId>${db.artifactId}</artifactId> <version>${db.version}</version> </dependency> </dependencies> </plugin> </plugins></build>
これで、このツールキットを簡単に使用できる多数の新しい Maven リポジトリにアクセスできるようになりました。 Speedment UI を開始するには、次のコマンドを実行します:
mvn speedment:tool
これにより、データベースに接続してコード生成を構成するプロセスが表示されます。最も簡単な開始方法は、最初にデフォルト設定で実行することです。 「生成」ボタンを押すと、Speedment はデータベースのメタデータを分析し、エンティティやエンティティ マネージャーなどのクラスをプロジェクトに追加します。
Speedment の初期化
ドメイン モデルが生成されたら、Speedment をセットアップするのは簡単です。新しい Main.java ファイルを作成し、次のコード行を追加します。表示されるクラスは生成されるため、データベース スキーマ、テーブル、および列の名前に基づいて名前が付けられます。
Main.java
public class Main { public static void main(String... param) { final HaresApplication app = new HaresApplicationBuilder() .withPassword("password") .build(); } }
上記のコードは、生成されたコンストラクター パターンを使用して新しいアプリケーション エンティティを作成します。コンストラクターを使用すると、データベース パスワードなどの実行時構成の詳細を設定できます。
アプリケーション エンティティを取得したら、それを使用して、生成されたエンティティ マネージャーにアクセスできます。ここでは、データベースに「hare」、「キャロット」、「human」、「friend」という 4 つのテーブルがあります (完全なデータベース定義はここにあります)。
final CarrotManager carrots = app.getOrThrow(CarrotManager.class);final HareManager hares = app.getOrThrow(HareManager.class);final HumanManager humans = app.getOrThrow(HumanManager.class);final FriendManager hares = app.getOrThrow(FriendManager.class);
これで、これらのエンティティ マネージャーを使用してすべての CRUD 操作を実行できるようになります。
エンティティの作成
エンティティの作成は非常に簡単です。エンティティ生成の実装を使用し、列の値を設定してデータ ソースに永続化するだけです。
hares.persist( new HareImpl() .setName("Harry") .setColor("Gray") .setAge(8) );
persist メソッドは、「id」などの自動生成キーがすでに設定されている (潜在的に) Hare の新しいインスタンスを返します。永続化後も Harry を使い続けたい場合は、persist メソッドによって返される次のコードを使用できます:
final Hare harry = hares.persist( new HareImpl() .setName("Harry") .setColor("Gray") .setAge(8) );
永続化操作が失敗した場合、たとえば外部キーが一意性制約に違反した場合、 SpeedmentException がスローされます。これを確認し、このウサギのレコードの永続化を妨げる暗黙的な要因がある場合は、エラー メッセージを表示する必要があります。
try { final Hare harry = hares.persist( new HareImpl() .setName("Harry") .setColor("Gray") .setAge(8) ); } catch (final SpeedmentException ex) { System.err.println(ex.getMessage()); return; }
エンティティの読み取り
Speedment ランタイムの最も優れた機能は、Java 8 の Stream API を使用してデータベース内のデータをストリーミングできる機能です。 「なぜこれがクールなのでしょうか?」と自問するかもしれません。 「最近では Hibernate でもストリーミング操作がサポートされています!」というのが答えでした。
Speedment ストリーミング操作を使用する最も優れた点は、ストリーム構築の中間アクションと終了アクションの両方が考慮されることです。これは、ストリームの作成後にフィルターをストリームに追加すると、SQL ステートメントの作成時にそのフィルターも考慮されることを意味します。
これは、データベース内のウサギのレコードの総数をカウントする例です。
final long haresTotal = hares.stream().count();System.out.format("There are %d hares in total.%n", haresTotal);
このコードが生成する SQL クエリは次のとおりです:
SELECT COUNT(id) FROM hares.hare;
ここでの終了操作は .count() であるため、Speedment は SELECT COUNT(…) ステートメントを作成することを認識しています。また、「hare」テーブルの主キーが「id」列であることも認識しているため、データベースに送信されるステートメント全体をこれに減らすことができます。
より複雑な例としては、名前が「rry」で始まり、年齢が 5 歳以上のウサギの数を見つけることが考えられます。これは次のように書くことができます:
final long complexTotal = hares.stream() .filter(Hare.NAME.endsWith("rry")) .filter(Hare.AGE.greaterOrEqual(5)) .count();
Speedment によって生成された、検索されたビルダーを使用してフィルターを定義します。これにより、プログラムでストリームを分析し、次のような SQL ステートメントにまとめることが可能になります:
SELECT COUNT(id) FROM hares.hareWHERE hare.name LIKE CONCAT("%", ?)AND hare.age >= 5;
ストリームを最適化できない Speedment オペレーションを追加すると、通常の Java 8 ストリームが処理されるのと同じように動作します。ストリーミング操作をより効率的にできる、生成された Location Builder の使用を制限することはありません。
final long inefficientTotal = hares.stream() .filter(h -> h.getName().hashCode() == 52) .count();
上記のコードは、次のように非常に非効率なステートメントを生成しますが、それでも実行できます。
SELECT id,name,color,age FROM hares.hare;
エンティティの更新
既存のエンティティの更新は、エンティティの読み取りと永続化と非常に似ています。エンティティのローカル コピーを変更しても、update() メソッドを呼び出すまではデータベースの内容には影響しません。
以下では、以前に Hare を使用して作成したハリーを取り出し、その色を茶色に変更します。
harry.setColor("brown");final Hare updatedHarry = hares.update(harry);
如果更新被接受了,那么管理器会返回hare的一个新的拷贝,因为我们在后面会继续使用这个实例。就想做“创建”的例子中,更新可能会失败。也许颜色被定义为“值唯一”,棕色已经存在于hare中。那样的话,会抛出一个SpeedmentException异常.
我们也可以通过合并多个实体到一个流中来同时更新他们。加入我们想将所有名字为Harry的hare变为棕色,我们可以这样做:
hares.stream() .filter(Hare.NAME.equal("Harry")) .map(Hare.COLOR.setTo("Brown")) .forEach(hares.updater()); // 更新流中存在的元素
我们还应该使用try-catch语句来确保在运行过程中有失败发生时警告用户。
try { hares.stream() .filter(Hare.NAME.equal("Harry")) .map(Hare.COLOR.setTo("Brown")) .forEach(hares.updater()); } catch (final SpeedmentException ex) { System.err.println(ex.getMessage()); return; }
实体删除
我们需要知道的最后一个 CRUD 操作就是从数据库中删除实体。这个操作几乎和“更新”操作时等同的。假如说我们要把年龄超过10岁的兔子的记录都删除,就要这样做:
try { hares.stream() .filter(Hare.AGE.greaterThan(10)) .forEach(hares.remover()); // Removes remaining hares} catch (final SpeedmentException ex) { System.err.println(ex.getMessage()); return; }
总结
通过阅读本文你已经了解了如何在一个 Maven 工程中对 Speedment 进行设置,还有如何使用 Java 8 的 Stream API 来从数据库中创建、更新、读取以及删除实体。这是你可以利用 Speedment 所能进行的操作的一个小的子集, 但已经是一个能让你上手的好的开始了。更多的示例以及更加高级的使用场景可以在 GitHub-page 上找到。
更多Java 8 Streams 中的数据库 CRUD 操作相关文章请关注PHP中文网!