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

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

ただいまの
回答率

90.52%

  • Java

    13753questions

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

  • Struts 2

    130questions

    Apache Struts 2は、Apache Strutsプロジェクトにて開発されているオープンソースのJavaベースのWebアプリケーションフレームワークです。Sturts1に比べ、設定ファイルの削減、依存性の注入、POJO等の改善がなされています。

既に登録されている情報と全く同じ情報の登録を無効化したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 209

Tatsuo_Iriyama

score 26

[前提]
言語:Java
フレームワーク:struts2

ショッピングサイトの宛先登録を製作中。

[問題]
タイトルにもあるように、入力した宛先情報が既に登録されている場合、その登録を無効化、要するに登録出来ないようにしたいのですが、うまくいかなくて詰まっています。

public List<String> doubleCheck(AddressDTO addressDTO) throws SQLException {

        DBConnector db = new DBConnector();
        Connection con = db.getConnection();
        List<String> errorMsg = new ArrayList<String>();

        String sql = "select count(id) as count from destination_info where user_id=? and family_name=? and first_name=? and family_name_kana=? and first_name_kana=? and email=? and tel_number=? postal_code=? user_address=?";

        try {
            PreparedStatement ps = con.prepareStatement(sql);

            ps.setString(1,addressDTO.getUserId());
            ps.setString(2,addressDTO.getFamilyName());
            ps.setString(3,addressDTO.getFirstName());
            ps.setString(4,addressDTO.getFamilyNameKana());
            ps.setString(5,addressDTO.getFirstNameKana());
            ps.setString(6,addressDTO.getEmail());
            ps.setString(7,addressDTO.getTelNumber());
            ps.setString(8,addressDTO.getPostalCode());
            ps.setString(9,addressDTO.getAddr11());

            ResultSet rs = ps.executeQuery();

            if(rs.getInt("count") > 0) {
                errorMsg.add("こちらの宛先は既に登録されています");
            }

        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            con.close();
        }

        return errorMsg;

    }

AddressDTOのコード

public class AddressDTO {

    private int addressId;
    private String userId;
    private String familyName;
    private String firstName;
    private String familyNameKana;
    private String firstNameKana;
    private String postalCode;//郵便番号
    private String addr11;//住所
    private String telNumber;
    private String email;

    public int getAddressId() {
        return addressId;
    }

    public void setAddressId(int addressId) {
        this.addressId = addressId;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getFamilyName() {
        return familyName;
    }

    public void setFamilyName(String familyName) {
        this.familyName = familyName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFamilyNameKana() {
        return familyNameKana;
    }

    public void setFamilyNameKana(String familyNameKana) {
        this.familyNameKana = familyNameKana;
    }

    public String getFirstNameKana() {
        return firstNameKana;
    }

    public void setFirstNameKana(String firstNameKana) {
        this.firstNameKana = firstNameKana;
    }

    public String getPostalCode() {
        return postalCode;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    public String getAddr11() {
        return addr11;
    }

    public void setAddr11(String addr11) {
        this.addr11 = addr11;
    }

    public String getTelNumber() {
        return telNumber;
    }

    public void setTelNumber(String telNumber) {
        this.telNumber = telNumber;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

実際の登録処理コード

public class AddressRegiCompleteAction extends ActionSupport implements SessionAware{

    public Map<String,Object> session;

    public String execute() throws SQLException{

        String result = ERROR;

        AddressDTO addressDTO = new AddressDTO();

        List<String> errorMsg = new ArrayList<String>();

        addressDTO = (AddressDTO)session.get("AddressDTO");

        AddressRegiCompleteDAO addressRegiCompleteDAO = new AddressRegiCompleteDAO();

////        全く同じ内容のものが既にDBに格納されていないか判定。
        errorMsg = addressRegiCompleteDAO.doubleCheck(addressDTO);
        if(!errorMsg.isEmpty()) {
            return result;
        }

        int count = addressRegiCompleteDAO.registerAddress(addressDTO);
//        countで登録されたかの判定。
        if(count > 0) {
            session.remove("AddressDTO");
            result = SUCCESS;
        }

        return result;
    }


    public Map<String,Object> getSession(){
        return session;
    }
    public void setSession(Map<String,Object> session) {
        this.session = session;
    }

}

思い付く限りでコードを書いて見たのですが、現状、全く同じ宛先情報でも登録されてしまいます。

ご回答宜しくお願いします。
コード的に改善点(こう書いた方がいいよ)等ありましたら重ねてお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+1

ResultSet rs = ps.executeQuery();

// ここで「rs.next()」してないので、取得結果の先頭にカーソルが移動してない。

if(rs.getInt("count") > 0) {
    errorMsg.add("こちらの宛先は既に登録されています");
}

コメント返しの追記:
ResultSetの使い方を理解されてないようです。下記を参照ください。
javadrive

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/21 17:49

    if(rs.getInt("count").next() > 0 ) {
    errorMsg.add(~~~);
    }
    こんな感じですか?

    キャンセル

checkベストアンサー

0

登録部分のソースコードがなく、またAddressDTOへの設定情報も不明なため、推測で回答致します。

二重チェックが有効とならない理由としては以下が考えられます。

  • doubleCheck()に渡しているAddressDTOに設定している値正しくない
  • doubleCheck()にてExceptionが発生しており、チェックが正しく行えていない

実行しているSQLのデバッグや、以下の処理を通過していることの確認をしてみると良いと思います。
以下の処理を通っている(Exceptionが発生していない)場合、実行されているSQLの確認や、rs.getInt("count")の値の確認をするのが良いですね。

           if(rs.getInt("count") > 0) {
                errorMsg.add("こちらの宛先は既に登録されています");
            }

コード的に改善点(こう書いた方がいいよ)等ありましたら重ねてお願い致します。

今回の検証と合わせてですが、以下のExceptionのcatch句では、エラーを握りつぶしてしまっているので、適切な処理(ログ出力や、戻りの設定(Exceptionの再throwなど))を行うようにした方が良いですね。

        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            con.close();

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/21 17:52

    コード追加しました!
    あと登録を行った際、「You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'postal_code='○○○' user_address='○○○'' at line 1」
    こういうエラー文がコンソール上に表示されたのですがどういう意味を示しているのでしょうか?

    キャンセル

  • 2018/05/21 17:59

    postal_code=? と user_address=? の前に and がありません。

    キャンセル

  • 2018/05/21 19:35

    上手くいきました!ありがとうございました!
    1つ質問なんですが、コードについてご指摘いただいたんですが、あまりイメージを沸くことができず、エラーを握りつぶしているとはどういうことかもう少し噛み砕いた形で教えて頂けると嬉しいです。

    キャンセル

  • 2018/05/21 20:29

    問題切り分けにはなりましたが、実際の解決は他の回答者さまの方が参考になっていたかもですね(汗

    > エラーを握りつぶしているとはどういうことか

    try〜catch句でExceptionが発生した場合、catch句に処理が飛びます。
    そしてcatch句の処理が行われるのですが、提示いただいたソースですと、スタックトレースの出力しか行っておらず、結果的にエラーメッセージの入っていないerrorMsgがreturnされてしまいます。
    (SQL実行エラーが発生した場合に、正常動作と同じ動きをするのは好ましくないです)

    この点が、「エラーが(発生しているにも関わらず、あとで発生したことが分からないよう)握りつぶされている」と表現しました。
    対処は回答に記載した通りです。

    キャンセル

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

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

関連した質問

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

  • Java

    13753questions

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

  • Struts 2

    130questions

    Apache Struts 2は、Apache Strutsプロジェクトにて開発されているオープンソースのJavaベースのWebアプリケーションフレームワークです。Sturts1に比べ、設定ファイルの削減、依存性の注入、POJO等の改善がなされています。