質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Play Framework 2

Play Framework 2はPlayのメジャーバージョンです。現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

Q&A

解決済

1回答

3647閲覧

PlayFrameworkのEbeanを利用してMySQLからデータを検索して抽出【Java】

Sfidante

総合スコア90

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Play Framework 2

Play Framework 2はPlayのメジャーバージョンです。現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

0グッド

0クリップ

投稿2016/03/31 11:42

PlayFramework2.4とJavaでデータ検索をしたいです。

現在はデータの検索はできているのですが、
ちょっとした条件の複雑さからコードが肥大化してしまいどうにかできないものかと悩んでおります。
なお、SQL文を直接埋め込むやり方も同じように複雑化してしまうのでEbeanのFindで検索したいです。

一つを例に挙げるのでアドバイスをいただきたいです。

地域を検索する際に
・都道府県で検索
・特定の東京23区で検索
・上記の東京23区以外の23区で検索
・東京23区外で検索

としています。
そしてデータベースは**「都道府県」と「市区町村」**でカラムを分けています。

上記はセレクトボックスからの値を文字列として送られ来ます。
(例:東京都、渋谷区、その他23区、その他東京都etc)

それぞれの条件分岐からの処理をコードで表すと

Java

1if(area.indexOf("区") != -1){ //”区”の文字が含まれているか否か 2 if(area.equals("その他23区")){ 3 処理1 4 }else{ 5 処理2 6 } 7}else if(area.equals("その他東京都")){ 8 処理3 9}else{ 10 処理4 11}

としています。

それをEbeanを用いると

Java

1//都道府県で検索 2.eq("prefectures", "都道府県名") 3 4//特定の23区 5.eq("prefectures", "東京都") 6.eq("city", area) 7 8//その他23区 9.eq("prefectures", "東京都") 10.ne("city" , "渋谷区").ne("city" , "新宿区")... 11 12//東京23区外 13.eq("prefectures", "東京都") 14.not(Expr.ilike("city" , "%区%"))

としています。
それぞれ条件の指定の仕方が異なっており、処理を簡略化したいのです。

何卒、皆様のお知恵を拝借したい所存です。
宜しく御願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

当回答ではコードの行数は減らないので

コードが肥大化してしまいどうにかできないものか

というご質問の意図からは外れてしまうかも知れませんが、
Strategyパターン(だと思いますw)を使用すれば、検索条件の切り替えと個々の条件の指定を分離でき、見通しのよいコードにはなると思います。

まず、以下のようにExpressionBuilderインターフェースと、その内部クラスとしてFactoryクラスを定義します。

ExpressionBuilderインターフェースはStrategyパターンにおける"Strategy"で、buildメソッドに渡されたExpressionListオブジェクトに検索条件をセットします。

FactoryクラスのgetBuilderメソッドは、引数で受け取った文字列を元に
それぞれの検索条件に対応したExpressionBuilderインターフェースの実装クラスをreturnします。

java

1public interface ExpressionBuilder { 2 3 <T> ExpressionList<T> build(ExpressionList<T> exp); 4 5 public static class Factory { 6 7 public static ExpressionBuilder getBuilder(String area) { 8 if (area.indexOf("区") != -1) { // ”区”の文字が含まれているか否か 9 if (area.equals("その他23区")) { 10 // その他23区の検索条件を生成するクラス 11 return new Other23kuExpressionBuilder(area); 12 } else { 13 // 特定の区(新宿区、渋谷区など)の検索条件を生成するクラス 14 return new Specific23kuExpressionBuilder(area); 15 } 16 } else if (area.equals("その他東京都")) { 17 // その他東京都の検索条件を生成するクラス 18 return new Not23kuExpressionBuilder(area); 19 } else { 20 // 全国の検索条件を生成するクラス 21 return new NationwideExpressionBuilder(area); 22 } 23 } 24 } 25}

getBuilderメソッドから返却しているExpressionBuilderインターフェースの実装クラスは、
例えば以下のような感じになります。

java

1/** 2 * 特定の区(新宿区、渋谷区など)の検索条件を生成するクラス 3 */ 4class Specific23kuExpressionBuilder implements ExpressionBuilder { 5 6 private final String area; 7 8 Specific23kuExpressionBuilder(String area) { 9 this.area = area; 10 } 11 12 @Override 13 public <T> ExpressionList<T> build(ExpressionList<T> exp) { 14 return exp 15 .eq("prefectures", "東京都") 16 .eq("city", area); 17 } 18 19}

ちなみに「その他23区」の検索条件は、
.ne("city" , "渋谷区").ne("city" , "新宿区")...
より
.not(Expr.in("city", ...))
に、定数として定義した「特定の23区」をinメソッドの第二引数に渡すほうが私は可読性が向上するかと思いますが、いかがでしょうか?
(EBeanは不勉強なので、同じ動作結果になるか自信はありませんが。。)

java

1class Other23kuExpressionBuilder implements ExpressionBuilder { 2 3 // 特定の23区 4 private static final String[] SPECIFIC_23KU = new String[] { 5 "渋谷区", 6 "新宿区", 7 ... 8 }; 9 10 private final String area; 11 12 Other23kuExpressionBuilder(String area) { 13 this.area = area; 14 } 15 16 @Override 17 public <T> ExpressionList<T> build(ExpressionList<T> exp) { 18 return exp 19 .eq("prefectures", "東京都") 20 .not(Expr.in("city", SPECIFIC_23KU)); 21 } 22 23}

こうしておくと、実際に検索を実行する部分はたったこれだけの行数になります。

java

1ExpressionBuilder builder = ExpressionBuilder.Factory.getBuilder("豊島区"); 2 3ExpressionList<?> exp = ebeanServer.find(...).select(...).where(); 4builder.build(exp).findList();

投稿2016/03/31 18:01

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sfidante

2016/04/01 01:49

ご回答ありがとうございます。 デザインパターンに適応させられるのですね。 ご丁寧にコードまで記載していただきありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問