東京でDoma勉強会やったぞ!!! #doma_tokyo
Doma 作者の 中村さん 、 Domaヘビーユーザーの がくぞさん と一緒にDoma勉強会を東京で開催してきました!!!
スライド
私のスライドはこちら。 2本、話させて頂きました。 Domaの主要な機能を私なりに紹介した発表と、ドメインクラスで型最高!という発表です。
がくぞさんのスライドはこちら。 collect検索の活用方法、なるほど感すごかったです。 真似させてもらいます!
そして、中村さんのスライドはこちら。 Doma開発のスタンス、我々ユーザーとの向き合い方に感動しました!!
他の方々のブログ、Togetterなど
- 「Doma勉強会 in 東京」に行ってきました。 - シュンツのつまづき日記
- Doma勉強会 in 東京に行ってきた #doma_tokyo - Splash of waters - 2nd. Season
- 【7/9(土)】Doma勉強会 in 東京でLTしてきました #doma_tokyo - Javaプログラマーのはしくれダイアリー
- 【7/9(土)】Doma勉強会 in 東京 - Togetterまとめ
- Doma勉強会 in 東京に行ってきました #doma_tokyo #eventdots - Chonaso’s Commentary
- 【7/9(土)】Doma勉強会 in 東京 に参加してきた - てんてんのぶろぐ
TLへのリアクション
内容については、他の方々のブログにお任せするとして、ここからは当日のTLから幾つかのツイートをピックアップして、リアクションしたいと思います。
どこかにテンプレート的なものがあるらしい? > build.gradle #doma_tokyo
— 寝起き (@nashcft) 2016年7月9日
これです!
Dialectって主にページネーションの方言を吸収するのか。offsetやらlimitやら。 #doma_tokyo #eventdots
— 多田真敏(MasatoshiTada) (@suke_masa) 2016年7月9日
通常のSELECT文をページネーションするクエリや、 悲観排他するクエリに変換する際にRDBMSの方言を吸収するためのものですね。
ページネーションはH2なら offset と limit を使うけど、Oracleなら rownum を使うし、悲観排他はOracleなら for update を使うけど、SQLServerなら with(updlock) を使う、といった感じです。 この辺をDomaの中で吸収してくれるのが Dialect です。
ページネーションとかはSelectOptionsとかの話かなhttps://t.co/PETWtejqLi#doma_tokyo #eventdots
— やんく (@yy_yank) 2016年7月9日
そうです。 Domaは SelectOptions で offset と limit を指定する事ができます。 他にも悲観排他、それからカウント取得なんかの指定もできます。
#doma_tokyo NetBeansでは...らしい。(私はMavenでビルド定義して使ってる)
— Den (@den2sn) 2016年7月9日
これは私の誤りのようです。 Mavenプロジェクトなのか、Gradleプロジェクトなのか、そういった違いにもよるのかも知れませんが、少なくともMavenプロジェクトだと何も不都合なく使えるようです。 NetBeans、ごめんなさい。
アクセサいらんのか#doma_tokyo #eventdots
— やんく (@yy_yank) 2016年7月9日
Domaはエンティティのフィールドを直接見に行くのでアクセサメソッドは不要です。
エンティティリスナーでcreate_user、create_dateを設定したいという場合には非常に便利そう。
— Junki Yamada(シュンツ) (@glory_of) 2016年7月9日
共通項目クラスとかを用意する必要はありそうだけど。 #doma_tokyo #eventdots
仰る通り、共通項目だけを持つ基底クラスとなるエンティティを作る必要があります。 基底クラスがあればエンティティリスナーは1つで良いので、楽といえば楽です。
これは後日、サンプルを作ろうと思います。 (私のGitHubリポジトリを漁ったら既にあるかも知れませんが)
Stream にした場合はページングはやってくれるのかな? #doma_tokyo
— いとうちひろ(Chihiro Ito) (@chiroito) 2016年7月9日
ページネーションは SelectOptions の offset と limit で指定します。 Stream 検索はあくまでも ResultSet.next してエンティティにマッピングする処理を Stream で表現しているだけです。
Streamを返す版はリソース忘れが無いようにそのままだとコンパイル時に警告を出してくれます。close処理を書いたら心を込めてアノテーションつけると警告を外せます。 #doma_tokyo
— がくぞ (@gakuzzzz) 2016年7月9日
Stream を返すためではなく、他の事に心を込めような!!!
……と、冗談はさておき、元々はSpring Batchの ItemReader では ResultSet.next がメソッドをまたぐ必要があるため、それに対応しやすいように入れられた機能です。 通常は使う機会は無いと思います。
これも後日サンプルを書いてみようと思います。
RomaをSpringで使う場合、Spring Bootしか選択肢ないのかな?
— Takafumi Iju (@ijufumi_0810) 2016年7月9日
Boot以外では使えたりしないかな?#doma_tokyo #eventdots
Spring BootではないSpringでも使えます。 実装には doma-spring-boot-autoconfigure が参考になると思います。
Domaが必要とするのは DataSource だけですので、SpringでもJava EEでもJava SEでも、基本的にどこでも使えます。
ローカルトランザクション、Java SE環境で使えるのか#doma_tokyo #eventdots
— やんく (@yy_yank) 2016年7月9日
使えます。 やってる事は単純で Connection.setAutoCommit と Connection.commit と Connection.rollback を組み合わせてトランザクションを行っているだけです。 あとは ThreadLocal を利用してトランザクションの期間中 Connection をスレッドに紐付けています。
LocalTransactionDataSource まわりのコードは小さいので、読んでみるのも楽しいですよ!
今って[at]Transactionalアノテーションサポートしてる? #doma_tokyo
— Ktz (@ktz_alias) 2016年7月9日
@Transactional はJava EEやSpringといったコンテナの機能で、Domaはサポートしていません。 Domaの範囲からは逸脱すると私は考えます。
とはいえ、例えばGuiceのような軽量コンテナであってもインターセプタの機能を有しているので、 Domaのローカルトランザクションと組み合わせて宣言的トランザクション機能を自作することは可能です。
これも後日サンプルをGuiceとDomaで書いてみますね。
こんな感じで検索すればSQLも引っ掛けられる(STS) #doma_tokyo #eventdots pic.twitter.com/r2US1mwupJ
— Junki Yamada(シュンツ) (@glory_of) 2016年7月9日
シュンツさん、ありがとうございます!!!
「エンティティをDAO内で定義したい」は比較的実装しやすいかもしれません。すでにドメインクラスはネストし
— toshihiro nakamura (@nakamura_to) 2016年7月9日
て定義できるようになっていますし。 #doma_tokyo #eventdots
ソッコーで実装されててわろた。
「主キー検索クエリは自動で組み立てたい」は実装自体は簡単。ポリシーとして整合性を保てるか?アノテーションの書き方をどうするか?などが問題になりそうです。#doma_tokyo #eventdots
— toshihiro nakamura (@nakamura_to) 2016年7月9日
ですね、よくわかります。 (なのでわがまま言うつもりはありません)
社員ID,名前、住所、役職とか、これをstringではなく、ドメインクラスにしていくと、クラス数爆発しそう。線引きはどうするんだろ。 #doma_tokyo #eventdots
— まめぴか@ (@mame_pika) 2016年7月9日
確かに、ドメインクラスを推進するとクラス数は多くなりますが、型の恩恵を受けられるメリットの方が大きいと私は判断しています。
ドメインクラスのgetValueをアプリケーションで呼ばない場合、プレゼンテーション層に値を渡す場合はどうすればいいんだろ?
— Takafumi Iju (@ijufumi_0810) 2016年7月9日
toStringでvalueを返せば良いのかな?#doma_tokyo #eventdots
フレームワークや共通部品のような抽象的な層なら getValue へのアクセスを許可します。 テンプレートにドメインクラスを渡す場合はコンバータを書きます(例えばJAXBの XmlAdapter )。 その際、コンバータには getValue へのアクセスを許可します。
domaのコミュニティ素敵だなあ #doma_tokyo
— 寝起き (@nashcft) 2016年7月9日
ありがとうございます。 本当に嬉しいお言葉です。 イベントを開催して良かった。
蛇足:DDDとの対比(個人的な見解)
ドメインクラスという名前のせいか、DDDに関係するのかな?といったツイートを見かけた事がありますが、DomaはDDD用のフレームワークではありません。 しかし、DDDで語られる各要素がDomaで言えば何なのかを考える事はできます。
個人的には次のように考えています。
- Domaの「テーブルと1対1にマッピングするエンティティ」は、DDDの「エンティティ」に相当する
- Domaの「検索結果にマッピングするエンティティ」と「ドメインクラス」は、DDDの「値オブジェクト」に相当する
懇親会について
今回、懇親会の企画はしていたのですが、参加者を募集しませんでした。 これは、本当に私の我儘でして、中村さん、がくぞさんと私自身がたくさん話したい!と強く思っていたので、広く募集はせずにスタッフと最後まで残って会場の現状復帰に付き合ってくれた方々数名だけとさせて頂きました。
我儘を通した甲斐があって、楽しい夕食の時間を過ごさせて頂きました。
イベント会場であるdotsについて
dots. のイベントスペース、おしゃで綺麗で木の床があって受付にお姉さんがいてかなり良い!!!!!#eventdots
— さらちむ (@syobochim) 2016年7月9日
ほんまそれ。
最高でした! 勉強会を開催したい方には、会場候補におすすめします!
謝辞
このイベントを開催しようと思ったきっかけは、春に東京へ遊びに行った際、一緒に晩御飯を食べてくれる人を募集したらがくぞさんが来てくださったところから始まりました。 がくぞさんが「一緒にやりましょう」と言ってくださったので中村さんにもお声がけする勇気が出ました。 がくぞさん、本当にありがとうございました!
同じく、その晩御飯の席に参加してくださっており、会場としてdotsを挙げてくださった とーますさん にも感謝です! dotsに関する事のサポートや、懇親会のお店の手配をしてくださり、ありがたかったです。 晩御飯、美味しかったー!
それから、運営の手伝いを買って出てくださった多田さん、やんくさん、ありがとうございました! 無茶振りのLTにも応えてくださり、イベントがより華やかになりました!
そして、中村さん、突然お声がけしたにも関わらず登壇を快く引き受けてくださってありがとうございました! ずっと以前からお会いしたくて、でもきっかけが無くて、がくぞさんのおかげで勇気を出せて、お声がけして、ようやくお会いできました。 本当に、本当に嬉しかったです!!!
あと、友人(と表現させてください)の しょぼちむ、 うがさん、 てんてんさん、 ちっひー、 はすぬまさん、 @suzukijさん、 Denさん、 まめぴー、来てくださってありがとうございました! 中村さんの前での発表はこれでもか!!!ってぐらい緊張していたけど、みんなが居ると思えばこそ最後まで発表できた気がします。
シュンツさん、来てくださってありがとうございました! 参加登録者を見て、密かに「お会いできる!」とワクワクしていました。 お会いできて嬉しかったです!
最後になりますが、参加してくださった皆さん、本当にありがとうございました! 皆さんのおかげでイベントが賑やかになり、楽しく過ごす事ができました。
本当に楽しい、夢のような1日でした。
みんなで撮った集合写真は、MBPのデスクトップを飾っています。
関Javaで使ってたスマホでスライドめくるやつ
今日は関Javaでした!
で、私も発表したんですが……
スマホで操作してる?#kanjava
— opengl-8080 (@opengl_8080) 2016年6月12日
スマホでスライド操作?#kanjava
— セセリ (@serorigundam) 2016年6月12日
うらがみさんのiPhone操作プレゼン、Reveal.jsとRemotes.ioとかかな?#kanjava
— 佐々木和繁うなぎ㌠ (@kazsharp) 2016年6月12日
うらがみさんのスライド操作。
— EOA (@fukamiAO) 2016年6月12日
まさかのアイポンから?!
アプリ自作??#kanjava
……というツイートを見て、気付いてくれた! そこに興味持ってくれて嬉しいぞ! という感じなので、これについて書きます。
スライドめくるやついいなー
いろんな人が発表しているのを見ていると、なんかリモコン的なやつとか指輪っぽいやつでリモートでスライドめくってて「いいなーアレ」と思っていました。
で、自分も発表する時に使いたいなと思ったんですけど、スマホがリモコン的に使えそうだし操作はページ送りできたら良いだけだし作るかー、と。
作ってみた
ざっくり言うと、Webアプリになっていまして、スマホのブラウザでページを開くとWebSocketで通信を開始し、コマンドを送ってページ送りを行っています。
使い方と仕組み
使い方と共にもうちょい詳しく書きます。
まずコードを clone して、ビルドします。
git clone https://github.com/backpaper0/slider.git
cd slider
gradlew build
すると build/libs/slider.jar が出力されます。
スライドを表示する端末でWebアプリを起動します。
java -jar build/libs/slider.jar
なお、サーバーにはUndertowを使っています。 また、mainメソッドの起動にはSpringBootを使っています。
Webアプリが起動するとスマホのブラウザからWebページを開く必要があるのですが、そのために私はスマホでテザリングをしています。 テザリングをして、 ipconfig とか ifconfig で端末のIPアドレスを確認したら http://<ipaddress>:8080/ へスマホでアクセスします。
画面はこんな感じ。
Left と Right でそれぞれ左・右にページを送ります。 その際、スクリーンショットを撮ってブラウザに送ります。 スクリーンショットは Screenshot ボタンでも取得できます。 そして Presentation ですが、これは私が利用している remark というスライドツールのプレゼンテーションモードを切り替えるために使います。
これらの実現方法ですが、まず Screenshot や Left のボタンを押すとWebSocketでサーバーにコマンドを送ります。 コマンドと言っても SCREENSHOT や LEFT といった単純な文字列です。
サーバーではコマンドを受け取ると Robotクラス を利用して スクリーンショットを撮ったり 、 「左ボタンを押す」というシステム入力イベントを発生させたり します。 これでスライドのページ送りができました。 なお、スクリーンショットはBase64エンコードしてData URIにしてブラウザに送っています。 ブラウザ側ではそれをそのままCanvasに書き出しています。
欲しいものは作ればいいや
仕組みとしては以上でして、まあ説明してみると大したことはしていないんですが、これまでプライベートコーディングではフレームワークを試したりサンプルコードばかり書き捨てていたので、改めて「欲しいと思ったものを自分でも作れるもんだなー」としみじみ思いました。 欲しけりゃ作ろ、と思うようになってきたのは、この数年で出会った何人かのエンジニアのお陰です。 名前を出すのは照れくさいので出しませんが、本当に尊敬しています。
まとめ
- 作ってはみたものの、使う機会を逃しており今回が初の実践でしたが、なかなか上手く行って良かった!
- 何人かの方に気付いて貰えて嬉しかった!(「機会があったら使わせて欲しい」とまで言ってくれた方も居た!)
使いながらもっと便利になるようにちまちまメンテしたい所存です。