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

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

ただいまの
回答率

90.48%

  • Java

    14154questions

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

  • SQL

    2490questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • Oracle Database 11g

    198questions

    Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

DAOからDBへアクセスする方法についての質問です

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,158

anna10

score 41

DAOによるDBへのアクセス方法についての質問です。

開発環境は、

OS:Windows7
ブラウザ:IE
eclipce:3.6
Tomcat:7.0
DB:Oracle11g・SQLPlus

となります。

画像の一覧画面にて表示されている情報は、DBに登録してあるものとなっています。
ここにて存在してある検索テキストボックスにて「あいまい検索を行いたい」というのが今回の流れです。
例えば、「ク」と入力すれば、ダークソウルとジュラシック・パーク、この2つが表示されるように、
前後での検索一致を盛り込みたいと考えています。

画面はjspで作成しています。


画像の検索テキストボックス部分のソースです。
<form name = "form_serchList" method ="post" action ="BookSrv" > 
    検索ワード<input type = "text" name = "serchWord"> 
<input type = "hidden" name = "serch" value = "serch"> 
<input type="submit" value="検索" onclick="return serch();"> 
</form>

①検索テキストボックスにて値を受け取ります。「ク」と入力され、
検索ボタンが押されたとします。


servletの一部分です。

// 一覧/検索画面の検索を押した際の処理 
}else if("serch".equals(serch)){ 

    // 「ク」を受け取ります
    String serchWord = request.getParameter("serchWord"); 

    // ②受け取った「ク」と接続オブジェクトを引数に渡します。DAOに飛びます
    List<BookBean>list_ = bd.selectOrSerch(con_,serchWord); 

    // ⑤ DAOにて「ク」が含まれるDB内の全情報を取得
    request.setAttribute("BOOK_LIST",list_); 

    //遷移先を一覧/検索画面にする 
    address = LIST_ADDRESS;



③DAOでDBに格納してあるデータを取り出します。select処理です。

/** 
* ジャンル名による絞り込みの結果を取得するメソッド 
* 現在はあいまい検索による結果を取得するメソッド 
* @param con 接続オブジェクト 
* @return genreSerch クライアントの全入力情報 
**/ 
public List<BookBean> selectOrSerch(Connection con,String genreSerch) throws Exception{ 

    List<BookBean> list = new ArrayList<BookBean>(); 

    // 現在は使用していないインスタンスです
    CharOperator co = new CharOperator(); 

    try{ 

        //ジャンル検索で全てを選択または一覧検索画面に遷移した場合 
        if("all".equals(genreSerch)){ 

            ps_ = con.prepareStatement(SELECTBOOK_QUERY); 



        } 

        /** 
         * 上の記述は関係ありません。
         * あいまい検索を行った場合 
         */ 
        else{ 
            
            /**
             * プリペアーステートメントにSQL文をセット。SERCHNAME_QUERYの内容はは次に記述します
             * SERCHNAME_QUERYはstaticインポートにより直接使用しています
             */
            ps_ = con.prepareStatement(SERCHNAME_QUERY); 
            
            // 「ク」をバインドします
            ps_.setString(1,genreSerch); 

        } 

        // SQL文の発行
        rs_ = ps_.executeQuery(); 

        // レコードの最終行になるまで
        while(rs_.next()){ 

            BookBean bb = new BookBean(); 

            //レコード1件分のデータをBeanに格納する 
            bb.setId(rs_.getInt("ID")); 
            bb.setGenre(rs_.getString("GENRE")); 
            bb.setName(rs_.getString("BOOK")); 
            bb.setReleaseDay(rs_.getString("SALE_DATE")); 
            bb.setPopularity(rs_.getInt("FAVORITE")); 
            bb.setStock(rs_.getString("STOCK")); 
            bb.setComment(rs_.getString("COM")); 

            //Beanに格納した1件のレコードをListへ追加する 
            list.add(bb); 

        } 

    }catch(Exception e){ 
        throw e; 

    }finally{ 

        try{ 

            // クローズ処理
            if(rs_ != null)    rs_.close(); 
            if(ps_ != null)    ps_.close(); 

        }catch (SQLException e){ 
             throw e; 
        } 

    } 

    //全入力情報を返す ④servletに戻ります
    return list; 

}

以上が全体的なざっくりとした流れになります。検索はSQLがDBに登録してあるデータに対して行うので、
肝はSERCHNAME_QUERYの部分だと思うのです。以降が質問内容となります。

あいまい検索というものがよく分かっていなかったので、一度SQLPlus内で

select name from item(テーブル名です) where name like '%ク%' order by id;と実行すると、

ダークソウル
ジュラシック・パーク

と表示されたので、これを元にSQL文を作成してみました

package servlet; 

/** 
* サーブレットで用いる定数クラス 
**/ 

public interface Constants { 

    /** 
     * あいまい検索を行うSQL文 
     */ 
    public static final String SERCHNAME_QUERY = "SELECT NAME FROM ITEM WHERE NAME LIKE '%?%' ORDER BY ID"; 

}


としてみたのですが、「行検索が無効」というエラーが出てしまいます。只?に入力された文字をバインドさせればいいのでは?
と思ったのですが違うようです。別クラスにて、LIKE以降にappendで足していく、という処理も考えてみました。

package operator;

/**
 * 文字操作を行うクラス
 **/
public class CharOperator {

    /**
     * 検索SQL文SERCHNAME_QUERYを受け取り、検索情報を追加するメソッド
     * @param str 受け取ったSQL文SERCHNAME_QUERY
     * @return 内容を追加したSQL文SERCHNAME_QUERY
     */
    public String serchlike(String str){
        
        // StringBuilderのインスタンス化
        StringBuilder sb = new StringBuilder();
        
        // SQL文をシーケンスに追加
        sb.append(str);
        
        sb.append(" ");
        sb.append("'");
        sb.append("%");
        sb.append("?");
        sb.append("%");
        sb.append("'");
        
        return toString();
    }
}

しかしここで継ぎ足す意味があまり、というか全く感じられず、
こちらは現在お蔵入りです。

文章が長くなってしまい申し訳ないのですが、DAOで問い合わせる場合のSERCHNAME_QUERYの記述方法を
どなたか教えて頂けないでしょうか?よろしくお願い致します。

【追記】
大変申し訳ないのですが、私が前提条件を失念しておりました。
というのも、あいまい検索を掛けるテーブルはITEMですが、もう1つGENREというテーブルがあり、この2つを
紐付けた上で全体の情報をSELECT処理により表示していました。


CREATE TABLE GENRE(
ID    NUMBER(2),
NAME    VARCHAR(20) NOT NULL,
Primary Key(ID)
);

CREATE TABLE ITEM(
ID    NUMBER(5),
GENRE_ID    NUMBER(2),
NAME    VARCHAR(50) NOT NULL,
SALE_DATE    DATE NOT NULL,
FAVORITE    NUMBER(1) NOT NULL,
STORK    CHAR(1) NOT NULL,
COM    VARCHAR(200),
Primary Key(ID),
FOREIGN Key(GENRE_ID) REFERENCES GENRE(ID)
);

テーブルITEMの外部キーがテーブルGENREのIDとなります。

最初は既に情報が登録されているテーブルITEMのNAMEにのみ検索を掛けて、条件にあったものを持って来ればよい、と
考えていましたが、ジャンルを登録した後の、全ての情報取得は以下のSQLで実行していました。

//書籍情報をselect処理により取得するSQL文
public static final String SELECTBOOK_QUERY =

"SELECT TO_NUMBER(ni.ID) ID,ng.NAME GENRE,ni.NAME BOOK,TO_CHAR(ni.SALE_DATE,'yyyy/mm/dd') SALE_DATE,ni.FAVORITE FAVORITE,ni.STOCK STOCK,ni.COM COM" +
"FROM ITEM ni,GENRE ng WHERE ni.GENRE_ID = ng.ID ORDER BY ni.ID ";

両方のテーブルを結合し、登録されているジャンルとテーブルITEMの内容を、テーブルITEMのID順に並べるという処理内容です。

教えて頂いたSQLを実行した所DAOのIDを持ってくる所で直ぐに例外に入ったので、
恐らく前の自分の考えが間違っていた為だと思われます。回答して頂いたのに申し訳ないです。

なので、正しい質問としては、「上記のSQLを基にしたSERCHNAME_QUERY」の記述方法、になります。本当にすみません。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

SERCHNAME_QUERY = "SELECT NAME FROM ITEM WHERE NAME LIKE ? ORDER BY ID"

にして、

 ps_.setString(1,"%" + genreSerch + "%");  

ですね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/04/11 14:51

    回答誠にありがとう御座います。LIKE以降のワイルドカードまでSQLの中で作らなくてはならないのかな?と思っていたので勉強になりました。もしお時間が許すのであれば、もう1つの方の質問にも回答して頂けないでしょうか。厚かましく申し訳ありません。

    キャンセル

  • 2015/04/13 08:59

    もうひとつの質問にもとりくんでみます。10日夜から、急ぎのミッションが来てしまったので、明後日くらいまで余裕がないのですが、それで良ければ。

    キャンセル

  • 2015/04/13 19:28

    返信ありがとう御座います。こちらの問題ですが、何とか解決致しました。度々の返信、大変感謝致します。本当にありがとう御座いました。

    キャンセル

0

あるいは
SERCHNAME_QUERY = "SELECT NAME FROM ITEM WHERE NAME LIKE '%'||?||'%' ORDER BY ID"; 
でもいけそうな気がします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/04/10 12:52

    文字列の連結は、RDBMS毎に違いますけどね。 ;-)

    キャンセル

  • 2015/04/10 14:10

    確かにそうですね。
    Oracleという指定があったので、それに準じた記述にしていました。

    キャンセル

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

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    14154questions

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

  • SQL

    2490questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • Oracle Database 11g

    198questions

    Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。