Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Aug 25 12:53
    nakamura-to commented #320
  • Aug 25 12:53
    nakamura-to commented #320
  • Aug 25 11:55

    nakamura-to on master

    Next development version [ci sk… (compare)

  • Aug 25 07:00

    nakamura-to on 2.25.1-release

    (compare)

  • Aug 25 06:59

    nakamura-to on master

    2.25.1 released Merge pull request #325 from do… (compare)

  • Aug 25 06:59
    nakamura-to closed #325
  • Aug 25 06:57
    nakamura-to opened #325
  • Aug 25 06:54

    nakamura-to on 2.25.1

    (compare)

  • Aug 25 06:54

    nakamura-to on 2.25.1-release

    2.25.1 released (compare)

  • Aug 25 06:48

    nakamura-to on fix-null-dereference

    (compare)

  • Aug 25 06:48

    nakamura-to on master

    Fix null dereference Merge pull request #324 from do… (compare)

  • Aug 25 06:48
    nakamura-to closed #324
  • Aug 25 06:46
    nakamura-to milestoned #324
  • Aug 25 06:46
    nakamura-to labeled #324
  • Aug 25 06:45
    nakamura-to opened #324
  • Aug 25 06:44

    nakamura-to on fix-null-dereference

    Fix null dereference (compare)

  • Aug 25 06:44

    nakamura-to on master

    Next development version [ci sk… Merge branch 'master' of github… (compare)

  • Aug 25 06:25

    nakamura-to on master

    Next development version [ci sk… (compare)

  • Aug 25 03:51

    nakamura-to on 2.25.0-release

    (compare)

  • Aug 25 03:51

    nakamura-to on master

    2.25.0 released Merge pull request #323 from do… (compare)

Toshihiro Nakamura
@nakamura-to
「SQLは単独で完結していた方が保守性が高い」というスタンスでいるのでどちらかというと設計思想からは外れますね。とは言え、もう少し利点/欠点を整理して検討してみたい気持ちがあります。
Toshihiro Nakamura
@nakamura-to
とりあえず思いついたものを共有しておきます
# 利点
- SQLの一部の重複を除去できるという点ではメンテナンスしやすい
  - ただし「SQLは単独で完結していた方が保守性が高い」というこれまでのスタンスと矛盾する

# 欠点
- SQLファイルからDaoを呼び出すのは依存関係が逆転していてわかりにくい
  - Dao -> SQL -> Dao -> SQL のようにコードを追わないといけない
- 見かけはメソッドを呼び出すようなのに実はSQLを組み立てているというのは直感的でない
  - わかりやすい記法を考える必要がある

# 疑問(検討事項)
- そもそも重複の除去が目的ならSQLファイルを使う以外の方法が適切では?
  - @SqlProcessorを使うとか
- 使える箇所を限定する必要があるだろうか?
- 直接他のSQLファイルをincludeできるようにした方が良い?
  - パラメータの引き渡しはどうするべきか?
  - 頼むファイルへのパスの書き方はどうするべきか?
- DaoSQLの間で循環参照が発生し得るのでコンパイル時にチェックするコードが必要?
  - 解析に時間がかからないだろうか?
- エラー報告時の行番号や列番号にズレが発生するはずなので対応が必要そう
- include対象のSQLファイルのパスは実行時に解決しないといけない
  - 今は全部コンパイル時に決まるが
- includeできるSQLファイルは同じDaoに所属するものだけにすべきか?
kakusuke
@kakusuke

ご検討ありがとうございます。

利点としては、

  • パフォーマンス向上
  • インターフェースをあまり汚さない
    あたりを思いつきました。
    最初にSQL内で・・・と思った動機が、searchByIdsのような、内部で使う前提で作ったメソッドが問答無用で外向きに公開されてしまっていて、間違って使われてしまうのを防げないのでなんとかしたい、ということなんですよね。

自分で言い出しておいてなんですが、

  • AOPしてた場合に挙動がおかしくなる可能性がある
  • connectionが別の場合、意図していないデータが返ってくる可能性がある
    というあたりも欠点になりますかね。
    外から渡せるようにしたほうがよさそうですね。

@SqlProcessorがまさにやりたいことを実現するツールだと思うのですが、ちょっと力技すぎて使いにくいかなーと思います。
ASTレベルで変換できる仕組みがあれば嬉しいです。

上記を踏まえて、例えばこんな感じはどうでしょうか?

Hoge.java

interface Hoge {
  @Select
 InClause<Integer> getIdsByCondition(Condition cond);

  @Select
  List<Hoge> search(InClause<Integer> ids);
}

searchByIds.sql

SELECT /*%expand*/* FROM hoge WHERE id IN /*ids*/(1)

InClause返すメソッドの引数にInClauseがないことをチェックすれば循環参照はほぼ起こらないかと思います。
この形であれば、エラー報告時の問題以外の他の問題は解決できたかと。

kakusuke
@kakusuke
補足ですが、InClauseがIN句のパラメータに指定された場合、ASTを変形してIN句のノードとまるっと置き換えるような実装をイメージしています。
Toshihiro Nakamura
@nakamura-to
InClause に対応するSQLはどうやって指定する想定ですか?
あ、 getIdsByCondition で取得するんですね
Toshihiro Nakamura
@nakamura-to
同じ @Select のアノテーションでSQLの実行結果を返したりASTを返したりするのはちょっとわかりにくいかもしれないですね。別のアノテーションを導入するのも手ですが、ASTというアプリでは直接利用する必要がないものをDaoで返すのもちょっと違和感あります。そう考えるとSQLファイルから別のSQLファイルをincludeできるようにするのが一番自然な気がしてきました。(もしこれまでのスタンスを変えて実装するならばですが)
kakusuke
@kakusuke

なるほど。もしSQLファイルのincludeできるようにするなら、

interface Hoge {
  @Select
  List<Integer> getIdsByCondition(Condition cond);

  @Select
  @SqlInclude(value = "canonical.name.of.Hoge.getIdsByCondition", name = "ids")
  List<Hoge> search(@SqlIncludeParam(target = "ids", name = "cond") Condition cond);
}
SELECT /*%expand*/* FROM hoge WHERE id IN /*#include ids*/(1)

みたいな感じですかね?

個人的な感覚ですが、Daoにpublicなメソッドしか生やせない以上、アプリでは直接利用する必要がないものを返すことで、普通に使えるメソッドじゃないぞという意図を表現できるんじゃないかなーと思っていまして、違和感はむしろメリットかなとも思えます。

Toshihiro Nakamura
@nakamura-to
SQLファイルの中でinclude対象のSQLファイル名(やパス)を指定することを想定していました。こんな感じです。
interface Hoge {
  @Select
  List<Hoge> search(Condition cond);
}
SELECT /*%expand*/* FROM hoge WHERE id IN /*#include getIdsByCondition.sql cond*/(1)
Toshihiro Nakamura
@nakamura-to
@kakusuke 検索条件の再利用の件で提案いただきましたが、一旦見送らせてください。便利になることはあるとは思うのですが、どうしても複雑さが上回ってしまうのではないかという考えに至りました。 :bow:
Toshihiro Nakamura
@nakamura-to
Raw String Literalsですが、JDK 12にも入らないようですね :cry:
https://www.infoq.com/news/2018/12/jdk-12-new-features
Doma 3はRaw String LiteralsがリリースされるJDKのバージョンまでは一旦ペンディングにしようと思っています。なお、皆さんからいくつか英語に翻訳したドキュメントのPRもらっていますが、これらについてはDoma 3まで待たずDoma2に反映していこうと思います。
Junki Yamada(シュンツ)
@glory_of_twitter
わかりました。
今後、翻訳するドキュメントの対象となるブランチはmasterに変えた方が良いですか?
Toshihiro Nakamura
@nakamura-to
そうですね、masterブランチに送っていただけると助かります :smile: (もしすでに翻訳途中であればdoma3ブランチに送っていただいても全く問題ないです)。Wikiも更新しておきました。
https://github.com/domaframework/doma/wiki/English-docs-for-Doma-2-and-3
Junki Yamada(シュンツ)
@glory_of_twitter
わかりました。
これ以降翻訳したもについてはmasterブランチにPRを送ります :smiley:
Toshihiro Nakamura
@nakamura-to
ありがとうございます! doma3ブランチにもらったPRは全てmasterブランチに反映させました。こちらで参照できます。
https://doma.readthedocs.io/ja/latest/transaction/
しばらく日本語と英語が混在しますがそれでいいかなーと思っています。
Toshihiro Nakamura
@nakamura-to
現時点で35個のドキュメントのうち20個の翻訳が終わりました。半分超えましたね!
Toshihiro Nakamura
@nakamura-to
以前、この場で、アノテーションにSQLを記述する機能について相談させてもらいましたが、Doma 2の次のバージョンで実験的に入れてみることにしました。以前はDoma 3から入れる予定で多少の互換性は失われてもいいと思っていましたが、Doma 2に入れるとなるとそういうわけにはいかないので、改めて仕様を検討した結果こんな感じになりました。
https://gist.github.com/nakamura-to/c9e3c9299d006ebdb8e74ceed6a6baf9
Toshihiro Nakamura
@nakamura-to
JDKのraw string literalsの導入はまだ先ですが、同様の機能をもつKotlinで使えたら便利なのかと思って(実験的ですが)早めの導入としました。
kakusuke
@kakusuke
@nakamura-to 反応遅れましてすみません :sweat_drops:
Domaの設計思想からは外れた提案だったにもかかわらず、
お時間使ってご検討いただきありがとうございました
Toshihiro Nakamura
@nakamura-to
@kakusuke いえいえ。取り込めませんでしたが提案ありがとうございました :bow:
@bufferings_twitter ドキュメントの翻訳ですが、wikiで basic.rst のところを担当されることになっていますが、こちらに余裕がありますので私のほうで引き取らせてもらいますね :smile:
Junki Yamada(シュンツ)
@glory_of_twitter

@nakamura-to すいません。
バッチ挿入のドキュメントのところで確認したいことがあります。

下記のinsertableのところについてです。
https://doma.readthedocs.io/en/stable/query/batch-insert/#insertable
@BatchInsert の insertable」となっているのですが、
正しくは「@Columnのinsertable」かと思ったのですがあっていますか?

PRを出した後に気づいたのですが、
修正の必要があればmerge前に直した方が良いかと思い質問させていただきました。
domaframework/doma#292

Toshihiro Nakamura
@nakamura-to
@glory_of_twitter いつもありがとうございます!「 @Column のinsertable」が正しいですね。merge前の修正お願いします :bow:
Junki Yamada(シュンツ)
@glory_of_twitter
@nakamura-to 修正しました!
mergeをお願いします。
Toshihiro Nakamura
@nakamura-to
mergeしました。他にもPRありがとうございます。おかげ様で全部のドキュメントが翻訳できました!これで一段落かなーと思っています。近い内にリリースして、今後はさらなる改善という形で進めていきます。
現在のmasterのドキュメントをビルドしてlatest版で参照できるようにしています。英語が得意なユーザーの協力が得られた嬉しいなーということでトップページにメッセージ載せています。 https://doma.readthedocs.io/en/latest/
みぞやん
@mizoyan432_twitter
現在、s2daoを使用していた社内システムをspring bootにコンバートするというプロジェクトをはじめました。クライアントアプリ(Java→C#)サーバサイドアプリ(Seasar2→Spring Boot)という構成になります。
殆どは機械的なコンバートになります。
で、DBアクセスについてはdoma2を採用するつもりで検証をしています。
規模感で言いますと、5DB,各500テーブルくらい。サブシステムがDBごとに分かれています。各サブシステムに10個程度のサーバーサイドアプリケーションがあります
みぞやん
@mizoyan432_twitter
相談したい事なのですがいくつかあるのですが、まず(Q1)doma2で1:n,n:1の読み込み出来ないとFAQに書いてあったのですが、代替手段はないでしょうか?
みぞやん
@mizoyan432_twitter
doma-genを改良してEntity, Dao, Criteria(汎用),Select用Controllerを作成しsubsystem1-dao.jar, subsystem1-dao-server.war, sysbsystem1-ss0-server.war〜sysbsystem1-ss9-server.war の様に構成していこうと思ってます。
-server.warはサーバサイドアプリケーションだと思ってください。
この中でsubsystemN-dao.jarは各アプリケーション用のデータベースごとに用意し、各サブシステムのプロジェクトでは全てdependencyに設定してあります。
(Q2)この様にdao.jarを共用する様なjar訳は普通にありますか?
みぞやん
@mizoyan432_twitter
ちょっと抽象的な質問になってしまっててすいません。
Toshihiro Nakamura
@nakamura-to
Q1に関してはdoma2ではサポートしていないので、アプリケーション側で1:nやn:1の関連を持ったオブジェクトを組み立ててもらう必要があります。Streamの機能などをうまく使えばフラットなオブジェクトから1:nやn:1の関連を持ったオブジェクトは作りやすいと思います。また、ちょっと難易度高い印象を持っていますがCollectorを使う方法もありますね。
http://gakuzzzz.github.io/slides/doma_practice/#29
Q2について私はそういったライブラリ構成にしたことがないので特に意見がありません。何らかの課題を解決し便利であるのであれば良い方法の一つなのかなーと思います。
みぞやん
@mizoyan432_twitter
回答ありがとうございます。このまま進めてみようと思います。フラットなオブジェクトから1.n, n:1は頑張ってみます
みぞやん
@mizoyan432_twitter
trancateをかけたい場合はdaoのメソッドにはどのannotationをつけたら良いでしょうか?
Toshihiro Nakamura
@nakamura-to
@Updateが良いと思います。こんな感じで書いて対応するSQLファイルにtruncate文を記述してみてください。
  @Update(sqlFile = true)
  int trancate(Staff staff);
みぞやん
@mizoyan432_twitter
分かりました。明日試してみます
みぞやん
@mizoyan432_twitter
思った通りの動作をするのを確認しました。ありがとうございました
みぞやん
@mizoyan432_twitter

すいません。確認ミスでした。

@Update(sqlFile = true)
int trancate();
こんな感じでやった時にDOMA4002 パラメータの数は1つでなければいけませんというエラーが出て
@Update(sqlFile = true)
int trancate(customerEntity dummy);
という定義に変えてみたそうです。

sqlは
truncate table customer;
と指定してます。

引数なしにするのは無理ですか?
みぞやん
@mizoyan432_twitter
truncate table customer;だと、DOMA4122 メソッドのパラメータdummyがSQLファイルで参照されていません。が出てしまいますね……
Toshihiro Nakamura
@nakamura-to
なるほど。 @Update使えませんね... すみません。こんな感じでデフォルトメソッドで任意のSQLを実行してもらうのが良さそうです。
@Dao
public interface CustomerDao {
    default void truncate() {
        Config config = Config.get(this);
        UpdateBuilder builder = UpdateBuilder.newInstance(config);
        builder.sql("truncate table customer");
        builder.execute();
    }
}
みぞやん
@mizoyan432_twitter
確かにこれならいきそうです。明日、またやってみます
みぞやん
@mizoyan432_twitter
いきました。ありがとうございました。junitで確認できました
Toshihiro Nakamura
@nakamura-to
@mizoyan432_twitter 今更ですみません。上記の話ですが、こんな感じで書けそうです。
@Script
 void trancate();
みぞやん
@mizoyan432_twitter
そうなんですね。この書き方もちょっと試してみますね