Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

DBFlute Fess 2017

102 views

Published on

2017年DBFlute Fessでお話した内容です。
DBFlute Fess : https://connpass.com/event/70648/
DBFlute : http://dbflute.seasar.org/
Pull Request : https://github.com/dbflute/dbflute-core/pull/54

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

DBFlute Fess 2017

  1. 1. 目次
  2. 2. ● 舟木 初 (ふなき はじめ) ● U-NEXT新卒1年目 ● ずっとLastaFluteで開発 ● 今回が初めてのオープンソースコミット
  3. 3. DBFluteにコミットをしました。 カラムの連結検索で、 nullが含まれていても大丈夫なようにした
  4. 4. 複数カラムに分かれた住所に対する曖昧検索 市町村区 丁目番地 建物部屋番号 検索値 渋谷区 神宮前3-35-2 クローチェ6F ← 渋谷区神宮前 世田谷区 北沢1-2-3 メゾン201 ← 北沢1-2-3メゾン
  5. 5. (DBとしては検索カラムがあったほうがよかったかもしれないが・・・) LikeSearchOptionで連結検索できるので・・! cb.query().setAddress1_LikeSearch(body.address, op -> { UnregisteredUserCB dreamCruiseCB = cb.dreamCruiseCB(); op.addCompoundColumn(dreamCruiseCB.specify().columnAddress2()); op.addCompoundColumn(dreamCruiseCB.specify().columnAddress3()); op.likeContain(); });
  6. 6. 連結するとこうなる さすがDBFlute! 一件落着! 市町村区 丁目番地 建物部屋番号 → 連結した値 渋谷区 神宮前3-35-2 クローチェ6F → 渋谷区神宮前3-35-2クローチェ6F 世田谷区 北沢1-2-3 メゾン201 → 世田谷区北沢1-2-3メゾン201
  7. 7. あれ・・・? 連結したカラムの値にひとつでもNULLがあると・・・? 市町村区 丁目番地 建物部屋番号 → 連結した値 渋谷区 神宮前3-35-2 クローチェ6F → 渋谷区神宮前3-35-2クローチェ6F 世田谷区 北沢1-2-3 NULL → NULL
  8. 8. NULLが空文字になればいいのに。 市町村区 丁目番地 建物部屋番号 → 連結した値 渋谷区 神宮前3-35-2 クローチェ6F → 渋谷区神宮前3-35-2クローチェ6F 世田谷区 北沢1-2-3 NULL → 世田谷区北沢1-2-3””
  9. 9. ふなき「カラムを連結するとき、 NULLを空文字として扱ってくれる機能はありますか?」 くぼさん「ないねえ」 ふなき「了解です。まあ大丈夫です。」
  10. 10. くぼさん「別に、ふなきくん、 プルリクしても いいんだからね笑」
  11. 11. プルリクしよう 1. dbflute-coreとdbflute-test-active-docksideをフォークして 2. dbflute-coreでcoalesceを使えるように修正して 3. テストコードをdbflute-test-active-dockside書いて 4. プルリクだす! 5. レビューしてもらう!
  12. 12. 発行されるSQLを見てみた。 select dfloc.ADDRESS1 as ADDRESS1, dfloc. ADDRESS2 as ADDRESS2 from USER dfloc where dfloc.ADDRESS1 || dfloc.ADDRESS2 like ‘%渋谷区西参道%' escape '|'
  13. 13. こうなってほしい select dfloc.ADDRESS1 as ADDRESS1, dfloc. ADDRESS2 as ADDRESS2 from USER dfloc where dfloc.ADDRESS1 || dfloc.ADDRESS2 like ‘%渋谷区西参道%' escape '|' coalesce(dfloc. ADDRESS1,'') || coalesce(dfloc. ADDRESS2,'')
  14. 14. DBFluteのなか このあたりでcoalesceを足せばよさそう。 public abstract class ConditionKey implements Serializable { ・ ・ protected ColumnRealName resolveCompoundColumn(ColumnRealName baseRealName, ConditionOption option) { ・ ・ final List<SpecifiedColumn> compoundColumnList = option.getCompoundColumnList(); final List<ColumnRealName> realNameList = new ArrayList<ColumnRealName>(); realNameList.add(baseRealName); // already cipher for (SpecifiedColumn specifiedColumn : compoundColumnList) { realNameList.add(doResolveCompoundColumn(option, specifiedColumn)); } final OnQueryStringConnector stringConnector = option.getStringConnector(); final String connected = stringConnector.connect(realNameList.toArray()); return ColumnRealName.create(null, new ColumnSqlName(connected)); } ・ ・ }
  15. 15. public abstract class ConditionKey implements Serializable { ・ ・ protected ColumnRealName resolveCompoundColumn(ColumnRealName baseRealName, ConditionOption option) { ・ ・ final List<SpecifiedColumn> compoundColumnList = option.getCompoundColumnList(); final List<ColumnRealName> realNameList = new ArrayList<ColumnRealName>(); realNameList.add(baseRealName); // already cipher realNameList.add(doResolveCompoundColumnOption(option, baseRealName)); // already cipher for (SpecifiedColumn specifiedColumn : compoundColumnList) { realNameList.add(doResolveCompoundColumn(option, specifiedColumn)); realNameList.add(doResolveCompoundColumnOption(option, doResolveCompoundColumnCipher(option, specifiedColumn))); } ・ ・ } protected ColumnRealName doResolveCompoundColumnOption(ConditionOption option, ColumnRealName columnRealName) { if (option.isNullCompoundedAsEmpty()) { return toColumnRealName("coalesce(" + columnRealName + ",'')"); } return columnRealName; } ・ ・ }
  16. 16. cb.query().setAddress1_LikeSearch("渋谷区西参道", op -> { op.likeContain(); op.addCompoundColumn(dreamCruiseCB.specify().columnAddress2()); op.compoundsNullAsEmpty(); }); optionで呼び出す coalesce(dfloc. ADDRESS1,'') || coalesce(dfloc. ADDRESS2,'')
  17. 17. // ## Assert ## assertTrue(Srl.containsIgnoreCase(popCB().toDisplaySql(), "coalesce")); assertHasAnyElement(vendorCheckList); assertTrue(vendorCheckList.size() >= 3); // inserted 3 entities for (VendorCheck vendorCheck : vendorCheckList) { assertContains(vendorCheck.getTypeOfChar() + vendorCheck.getTypeOfVarchar(), "bcd"); } テストコードも書いた ※VendorCheckというテスト用のテーブルがある
  18. 18. レビュー
  19. 19. ● https://github.com/dbflute/dbflute-core/pull/54/files ● https://github.com/dbflute-test/dbflute-test-active- dockside/pull/11/files
  20. 20. 目次

×