きり丸の技術日記

技術検証したり、資格等をここに残していきます。

Java

Flywayで特定のDBだけSQLを実行する(Spring, vender, Postgres)

小ネタ。なお、私のユースケースを満たせていなかったので、調査結果だけです。 環境 Java 17 org.flywaydb 8.5.13 org.springframework.boot 2.7.7 対応 設定ファイルの変更 PostgresやOracle等々で実行するSQLを変更するために、spring.flyway.locationsに…

Javaで1行でNull許容の配列を作りたかった

結局、願ったとおりに動かなかったので、思考錯誤したときのメモだけ残します。 環境 Java 17 対応 Collections.singletonList(T o)を使用することで、1行でnull許容した配列を作成できます。 動作確認 1行で配列を作成する方法は、List.of(), Arrays.asList…

開始日と解約"月"を元に暦上で日割のない解約"日"を求める(Java)

小ネタ。「今年の12月に解約したい。日割りが必要ない日付を教えてほしい」といった、解約する「年月」までは把握しているが、解約する「年月日」までは分からないといったケースに対応するロジックをJavaで求めます。 環境 Java 17 対応 暦上の1ヵ月の定義…

よく使うInterfaceの活用方法【Java】

Java Advent Calendar 2022の8日目の記事です。指摘コメントよろしくお願いします。 Javaに限らず、interfaceは使い道を理解することは難しいです。この記事では、私が普段使用しているinterfaceの使い方実例を記すことで、情報共有を行うことを目的としてい…

JavaのMockitoで部分モックをしたい・本物のメソッドを呼びたい(PartialMock, Answer)

JavaのMockitoを使って、対象クラスをモックにすることがあります。ただし、該当クラスのメソッドすべてではなく一部だけモックにして、他は本物のメソッドを呼びたいことがあります。 今回は、モッククラスから本当のメソッドを呼ぶ方法、デフォルト設定で…

MyBatisでEagerLoad, LazyLoadをする(Annotationにて)

MyBatisのアノテーションで親クラスのデータ取得時に、子や孫クラスを一緒に取得する方法(EAGER LOAD)、必要になってから取得する方法(LAZY LOAD)を記載します。 なお、常に子クラスと一緒に扱うときはEAGER LOAD, 必要に応じて子クラスを使用する場合は…

LazyLoadのエンティティを取得しようとしてClass Not Foundが発生した(原因不明・Spring・MyBatis)

自宅で再現できなかったので原因はわかっていません。しかし、対策はうまくいったので残します。 MyBatisにてLazyLoadで取得したエンティティの子データをJavaでgetter経由で取得しようとしました。その時にClass Not Foundが発生しました。詳細なメッセージ…

Javaでデバッグ用にnullは出力しないToStringのようなメッセージを出力したい(JSON, Object Mapper, JsonInclude.Include.NON_NULL)

タイトルではToStringを加工するような書き方をしていますが、処理イメージを伝えるものですのでToStringは使用しません。 デバッグのためにLombokで大量のフィールドをもつクラスをToStringで出力すると、当然大きな文字列となります。基本的には全フィール…

build.gradleファイルを分割する(別gradleファイルを読み込む)

JavaでGradleで開発していると、build.gradleに静的解析タスクであったり、コード自動生成タスクであったり、間接的なタスクが増えることがあります。 今回は不要なタスクを別ファイルのgradleファイルに分割する方法を記事にします。 環境 Java 17 Gradle 7…

Javaで現在行を取得する

Javaで現在行を取得する方法を記載します。 環境 Java 17 対応 現在スレッドのlineNumberを取得すれば、現在行が取得できます。 return Thread.currentThread().getStackTrace()[2].getLineNumber(); 0番目 Threadクラス 1番目 この処理している行 2番目 呼…

SpringのInterceptorでGETメソッド以外を拒否するようにコードで表現する

※ 特に見どころはありません。 業務都合にて、「アプリケーションをメンテナンスモードに切り替えても、参照系APIだけは参照できるようにしたい。更新系APIは拒否したい。」との要望が出てきました。 そもそも、「そんなこと可能?」ということを素振りした…

Javaで期間と期間を比較して重複チェックする

よくある内容の記事ですので、特別な内容はありません。私が迷わないようにするための記事です。 日付と日付を比較することは簡単ですが、日付の開始日と終了日をまとめた期間と期間を比較して、重複があることをチェックするのはたいへんです。なお、次の式…

Javaでストラテジーパターンを素振りする

ストラテジーパターンというGoFのデザインパターンが良いコード悪いコードでも紹介されていたので、素振りします。 自分の言葉で上手な言語化ができていないので、メリットは参考情報や良いコード悪いコードの購入、または別の方の記事を参考にしてください…

JavaのStaticメソッドをMockitoでモックする(ネストしたメソッドも値を返すようにする)

Javaのオープンチャットに「staticメソッドをMockitoでモックして値を返したい。NestするとNullが返るので、それを回避したい」という要望があったので、素振りしました。 環境 SpringBootStarterTestを基本としています。 Java 17 org.springframework.boot…

Javaのラムダ式(Stream API)で複数キーでCollectors.groupingByする

JavaのStream APIにて、複数キーでCollectors.groupingByする方法を記載します。 環境 Java 17 対応 前提として、次のrecordの項目を元に、Collectors.groupingByをします。 public record Book(String id, String language, int year, String salesTerritor…

Javaのラムダ式(Stream API)でNullableな項目にCollectors.groupingByする

Javaのラムダ式(Stream API)にて、Collectors.groupingByというグルーピングしてくれるメソッドがあります。ただし、このメソッドの引数はNonNullである必要があり、万が一Nullが混ざってしまうとNullPointerException: element cannot be mapped to a nul…

Gradleでマルチモジュールにしている状態から別モジュールのテストコードを共有する

テストのセットアップメソッドや、ファイルからドメインを生成するメソッド等々の便利メソッドを作るとします。マルチモジュールの場合、基本的にはプロダクトコードしか依存しないので、テストの便利メソッドは共有しません。 今回の記事では、テストコード…

【設計論】文字列だと単純にラップした型でも便利

ちょっとポエム寄りのお話です。 プリミティブ型をラップした型を作成することは、対象の業務を表現できることがメリットです。たとえば、主キーのIDが文字列だった場合に、次の制約があった場合でもプリミティブ型では伝えられません。 頭文字3桁がシステム…

メソッド呼出回数によって返却値を変更する(正常と例外)【JavaのMockito】

Mockitoを使用して、モックにしたメソッドの呼出回数によって正常な値と例外を返却する方法を残します。 環境 Java 17 org.mockito.junit.jupiter 4.0.0 ユースケース 1 対応 次の現在日付を返却するメソッドをモックにします。 public interface OffsetDate…

Javaでメソッド参照を使ったまま、ラムダ式で条件否定をする(Predicate.not)

私はラムダ式での可読性を上げるため、メソッド参照を使用することが多いです。ただ、メソッド参照を使用したまま条件否定する方法を知らなかったため、無名関数を使用して条件を否定していました。または、内部で条件否定をしたメソッドを別に用意している…

Javaで日付の差が何ヵ月かを計算する。あまりは切り上げる (LocalDate, ChronoUnit)

閏年等を考慮しだしたら混乱したのでメモ残します。 環境 Java 17 対応 対応自体は簡単で、ChronoUnit.MONTHESで月の差分を取得できます。今回は、1ヵ月に満たない日付がある場合は切り上げるので+1するだけです。 LocalDate start; LocalDate end; ChronoUn…

Lombokで自動生成されるGetterのprefixを変更したかった(Accessor prefixが使いたかった)

うまくいかなかったことのメモ。 環境 IntelliJ IDEA 2021.3.3 (Ultimate Edition) 2022/05/07時点 きっかけになったツイート なるほど。APIでyyyymmddのフォーマットを期待するrequest date型を用意してたけど、そこからlocaldateに変換するときにメソッド…

Javaでnull様等のnullという文字列を埋める(String#formatted)

以前にMessage.formatを使用して、null様のnullという文字列を埋める方法を調べました。 Java15にて新しくStringにformattedメソッドが増え、null様のnullという文字列を埋める方法が新しくできるようになりました。内部的に使用しているFormatterクラス自体…

Java 8以降、Javaで文字列の日付存在チェックする(閏年でないときの閏日チェック)(Check leap day)

JSON等でデータのやりとりをする時には、直接日付型を渡すことができません。文字列で渡す必要があります。 ただし、日付に関しては閏年が存在するため、単純な正規表現では文字列の異常値を検出できません。 今回の記事では、Javaで文字列の日付が存在する…

JavaのLombokのWithアノテーションを素振りした

個人用ネタ。 今回素振りするのはLombokのWithアノテーションです。他の言語でも同様の機能を達成したいときにwithという名前を使ってみてはいかがでしょうか。おそらく、Javaに限らず他言語でも通用するメソッドです。 環境 Java 17 ゴール LombokのWithア…

JavaにてJSONからインスタンスを生成する(テスト時に重宝)

個人的にはテストで多用していることが多いです。JacksonライブラリのObjectMapper最高ですね。 具体的にどのようなユースケースで使用しているかという点に関しては、一番最後に記載しています。 なお、Jacksonライブラリを使用したObjectMapperの記事は大…

Springで同一クラス別コンポーネントをDIしたい(nameGeneratorとFullyQualifiedAnnotationBeanNameGenerator)

Springで開発していると、別のコンポーネントだが、同一のクラス名を作りたくなることがあります。この同名クラスをDIしない場合は、特に問題は発生しません。しかし、同一クラス名をDIしてしまうと、BeanDifinitionStoreExceptionが発生してしまいます。 こ…

JavaをSonarCloudでカバレッジ取りながら静的分析する(Gradle, 2021年)

2021年になってGitHub Actions等のCIを使ったSonarCloud連携がしやすくなったので、手順を纏めます。 今回の記事では、JaCoCoでカバレッジを取得して、コードをSonarCloudへ連携できることをゴールとします。 環境 Java 11 JaCoCo SonarQube 3.3 Gradle 7.0.…

Javaで配列の特定の条件を満たすデータのみを操作したかった

※ 泥臭いやり方でしか実践できていません。 JavaのLINEオープンチャットにて、「配列内部の特定条件のみ変換したい」という質問がありました。 今後、同様の質問が来たときにスマートな回答ができるようにいくつか検証したメモを残します。なお冒頭にも書い…

SpringBootで実際のDBにつなげてユニットテストする

SpringBootで実際に起動してあるDBを使ったユニットテストをしようとすると、デフォルトだと動かないようです。 正確にはEmbeddedDataSourceBeanFactoryPostProcessor(ログだと長すぎるのでbeddedDataSourceBeanFactoryPostProcessorとして表示される)やEm…