Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

サーブレットでDAO使用時、データベースにアクセスできません。

ログイン忘れていました。失礼しました。再喝させていただきました。

初めて質問させていただきます、java3ヶ月の初心者です。
現在、とある教本と参考書とネット上の情報で勉強させていただいております。4日経過のままエラーの原因がわからず、先程エクリプスの再インストールをし再度各設定の確認をし実行しましたが、やはりうまくいきませんでした。ソースは教本(2010年発行)のコピーして使用しております。変更を加えた場所は各サーブレットにアノテーションの記述をしたことのみです。データベースのユーザ名、パスワードは教本と同じにしております。なお、この教本のなかのソースinsertRecord.java※最後に載せております。を実行しデータベースに書き込むことはできたので接続は問題ないよう思われます。今の自分ではこれ以上問題を解決できないと思い質問させていただきました。

実行環境とバージョン
tomcat7.0.26
mysql5.5.22
eclipse3.7
jdk1.7.0_04
mysql-connector-java-5.1.18
動的Webモジュールヴァージョン 3.0でプロジェクト作成しております。
os:windows7

以下、長くなりますがソースです。実行時のエラーはコンソールにConnect.Errorと表示される状態です。

searchForm.jsp(ここから起動。'number'をサーブレットに渡しています)

<%@ page contentType="text/html; charset=Windows-31J" %>
<HTML>
<HEAD>
<TITLE>検索フォーム</TITLE>
<BASE href="http://localhost:8080/jspAndServlet/">
</HEAD>
<BODY>
  <FORM action="DAOExerciseServlet" method="POST">
    <TABLE border="1">
      <TR>
        <TD align="right">number</TD>
        <TD><INPUT type="text" name="number">
      </TR>
      <TR>
         <TD colspan="2" align="center"><INPUT type="submit" value="検索開始"></TD>
      </TR>
    </TABLE>
  </FORM>
</BODY>
</HTML>


DAOExerciseServlet.java(サーブレット)

package chap11_database.sec03;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name= "DAOExerciseServlet", urlPatterns = { "/DAOExerciseServlet"})
public class DAOExerciseServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        doPost(request, response);
    }

    /**
     * リクエストを処理するメソッド
     * 指定社員番号に対応する社員情報を検索します
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        // 移動先のページ
        String nextPage = null;

        /* 検索処理 */
        String number = request.getParameter("number");
        if (number != null) {
          // 数値以外が入力された場合のためにtry〜catchで囲みます
          try {
            // 入力された値を数値に変換
            int id = Integer.parseInt(request.getParameter("number"));

            // DAOを使って社員情報を獲得
            EmployeeDAO dao = new EmployeeDAO();
            Employee employee = dao.findEmployeeById(id);

            // 社員情報をrequestスコープにセット
            request.setAttribute("employee", employee);

            // 検索結果表示画面へ
            nextPage = "/view/chap11_database/sec03/result.jsp";

          } catch (Exception e) {
            // 数値以外が入力された場合は検索画面へ
            nextPage = "/view/chap11_database/sec03/searchForm.jsp";
          }
        } else {
          // パラメータnumberが与えられなければ検索画面へ
          nextPage = "/view/chap11_database/sec03/searchForm.jsp";
        }

        /* 指定ページにフォワード */
        ServletContext context = getServletContext();
        RequestDispatcher rd = context.getRequestDispatcher(nextPage);
        rd.forward(request, response);
    }
}

Employee.java(examdbの employeeテーブル と departmentテーブル のTransfer Objectクラス)

package chap11_database.sec03;

public class Employee {
  /** 社員情報を保持するフィールド変数 **/
  // 社員番号
  private int number;
  // 名前
  private String name;
  // 年齢
  private int age;
  // 部署ID
  private int depId;
  // 部署名
  private String depName;

  /** コンストラクタ **/
  public Employee(int number, String name, int age, int depId, String depName) {
    this.number = number;
    this.name = name;
    this.age = age;
    this.depId = depId;
    this.depName = depName;
  }

  /** コンストラクタ(引数なし)**/
  public Employee() {
  }

  /** 各フィールド変数の読み取り、書き込み用メソッド **/
  public int getNumber() {
    return number;
  }
  public void setNumber(int number) {
    this.number = number;
  }

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }

  public int getDepId() {
    return depId;
  }
  public void setDepId(int depId) {
    this.depId = depId;
  }

  public String getDepName() {
    return depName;
  }
  public void setDepName(String depName) {
    this.depName = depName;
  }

}




参考InsertRecord.java(実行後、問題なくデータベースに書き込みされているのを確認しております。)

package chap11_database.sec02;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class InsertRecord {

    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/examdb"
              + "?useUnicode=true&characterEncoding=utf8";
        String user = "root";
        String password = "mysql";

        int[] departmentId = { 1, 2, 3};
        String[] departmentName = { "経理部", "開発部", "営業部" };
        String[] departmentManager = { "大野 智", "相葉 雅紀", "松本 潤" };

        int[] employeeNumber = { 1, 2, 3, 4, 5};
        String[] employeeName = { "大野 智", "櫻井 翔", "相葉 雅紀", "二宮 和也", "松本 潤" };
        int[] employeeAge = { 25, 30, 35, 40, 18 };
        int[] employeeDepartmentId = { 1, 1, 2, 2, 3 };

        // employeeテーブルデータ追加用SQL
        String insertEmployeeSql = "insert into  employee "
                + "(number, name, age, dep_id) values (?, ?, ?, ?);";

        // departmentテーブルデータ追加用SQL
        String insertDepartmentSql = "insert into  department "
                + "(dep_id, dep_name, dep_manager) values (?, ?, ?);";

        Connection con = null;
        try {
            // JDBCドライバをロード
            // JDBC4.0に対応しているドライバ使用のためコメントアウト
            // Class.forName("com.mysql.jdbc.Driver");

            // データベースに接続
            con = DriverManager.getConnection(url, user, password);

            // departmentテーブルデータ追加用SQL実行
            PreparedStatement departmentStmt = con.prepareStatement(insertDepartmentSql);
            for (int i=0; i < departmentName.length; i++) {
                departmentStmt.setInt(1, departmentId[i]);
                departmentStmt.setString(2, departmentName[i]);
                departmentStmt.setString(3, departmentManager[i]);
                departmentStmt.executeUpdate(); // 引数が無いのが注意
            }

            // employeeテーブルデータ追加用SQL実行
            PreparedStatement employeeStmt = con.prepareStatement(insertEmployeeSql);
            for (int i=0; i < employeeName.length; i++) {
                employeeStmt.setInt(1, employeeNumber[i]);
                employeeStmt.setString(2, employeeName[i]);
                employeeStmt.setInt(3, employeeAge[i]);
                employeeStmt.setInt(4, employeeDepartmentId[i]);
                employeeStmt.executeUpdate(); // 引数が無いのが注意
            }

            System.out.println("データの追加に成功しました。");

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // コネクション切断
            if (con != null) try {con.close();} catch (Exception ex) {}
        }
    }
}

文字数の都合上、result.jspとsqlファイルは割愛させて頂きました。
長い質問になってしまいました。どうぞよろしくお願いたします。

13

回答

101744

閲覧

13件の回答

評価

0

質問すること自体は良いが、ガイドラインを読んでどういう書き方が良いかを把握
してからにしよう。
「データベースにアクセスできません。」では、状況が全く分からない。
質問する場合には、自分が欲しい結果と今の結果、だけではなく、エラーや具体的
に出ているものなど、目に見えている情報も可能な限り載せよう。

表面的には同じでも、原因は様々という場合がある。
状況を細かく書くことで、とくに同じ経験がある人が、実行したりソースを読んだ
りすることなく、原因を特定できる可能性がある。

ソースだけだと、閲覧する側が環境を用意し、実行し、ソースを読むことを期待し
ている。
回答しようという側ができるだけ時間を使わないで済むようにした形にするのも、
良い質問だ。

評価

0

自分は初学者だから、どこをどう省いていいのか考えなくてよい、完全に甘えていました。以後、「良い書き方」を意識して質問させていただきます。$さん、貴重なご意見ありがとうございました。

評価

0

$さんからのご指摘を受け追記させていただきます。

現在、searchForm.jspからnumber(半角英数字1,2,3等)を入力してもコンソールにConnect Errorと表示されるのみで望んだ結果を得ることができません。なお、望む結果は

ID 名前 部署 年齢
1 大野智 経理部 25
2 櫻井 ・・・・以下略・・

です。
$さんのご指摘とおりソースばかりでお時間かけてしまい申しわけございません。ご教授いただければと思います。たいへん不足な点が多々あるかと思いますが、精進を心がけていきますのでどうぞよろしくお願いたします。

評価

0

すいません。12:56の回答ですがserchform.jspで入力する数字、numberが1の場合

ID 名前 部署 年齢
1 大野 経理部 25

という意味でした。よろしくお願いいたします。

評価

0

>コンソールにConnect Errorと表示されるのみ
スタックトレースは出ないの?

評価

0

ご指示ありがとうございます。デバッグビューを確認してみます。

評価

0

$さま、コンソールにてスタックトレースを確認できませんでした。serchForm.jspで「1」を入力後は Connect Errot の一行があらわれます。Connect Errotは下記のソースの------------部分のものが表示されていると思われます。はじめにお伝えしておらずお手数かけております。
EmployeeDAO.java
import略
public class EmployeeDAO {
  protected Connection createConnection() {
    try {
      Connection con = DriverManager.getConnection("jdbc:mysql略〜
      return con;
--------------------------------------------------
    } catch (SQLException e) {
      System.err.println("Connect Error.\n");
    }
--------------------------------------------------
    return null; // 接続に失敗した場合はnullを返す
  }
  protected void closeConnection(Connection con) {
    try {
      con.close();
    } catch (Exception ex) {
    }
  }
    /** SELECT文発行メソッド
   * 社員番号をもとに社員1人分のオブジェクトを取得
   **/
  public Employee findEmployeeById(int number) {
    Employee employee = null;
    Connection con = null;
以下略〜


評価

90

catchしたSQLExceltionの中身を握りつぶしちゃってるので、原因が分かりませんね。
System.err.println("Connect Error.\n");
の後で、
e.printStackTrace();
してみて下さい。

しかし、これだとコネクションが返らないから、Insertもできていないと思うんですが、どうなってんだろ?

評価

0

satomiさま、ご指示ありがとうございます。
--------------------------------------------------
しかし、これだとコネクションが返らないから、Insertもできていないと思うんですが、どうなってんだろ?
--------------------------------------------------
私の説明が至らなくて申し訳ないです。InsertRecord.java というクラス単体でjavaアプリケーションの実行でコンソールに

データの追加に成功しました。

が表示されデータベースにインサートすることができる状態ということで、本件のemployeeDAOとは直接関係ございません。データベースのテーブルなどに問題無いことをお伝えしたく、InsertRecordのことを記載させていただきましたがその旨伝えておらずお手数かけてしました。

早速 e.printStackTrace();してみたところ下記がコンソールに表示されました。少し長いですが全文載せております。

Connect Error.

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/examdb?useUnicode=true&characterEncoding=UTF-8
    at java.sql.DriverManager.getConnection(DriverManager.java:604)
    at java.sql.DriverManager.getConnection(DriverManager.java:221)
    at chap11_database.sec03.EmployeeDAO.createConnection(EmployeeDAO.java:23)
    at chap11_database.sec03.EmployeeDAO.findEmployeeById(EmployeeDAO.java:175)
    at chap11_database.sec03.DAOExerciseServlet.doPost(DAOExerciseServlet.java:40)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

評価

0

例外を握り潰してはいけない、ということを今回学んだ。

>少し長いですが全文載せております。
そこで終わってはだめだ。
新たな情報が得られたのだから、次はそれを自力で調査する
ステップを入れないといけない。
そうでないと、頼り癖がついてしまう。

評価

10

例外の内容から原因はほぼ絞れてるんだけど、自力でそこへ
辿り着くことに意味がある。
こういう積み重ねが、初心者脱出の鍵だと考えよう。

評価

0

$さま、ご教示ありがとうございます。只今、例外の内容から調査させていただいております。

satomiさま、自力で調査することへの道筋を示して下さり本当にありがとうございます。

評価

0

原因がわかり無事解決いたしました。eclipseの設定>データ管理>接続>ドライバー定義>JAR list で、WEB-INF/libに入れた mysql-connector-java-5.1.18-bin のプロパティの設定をして、それでオーケーだと勘違いしていた点が今回の原因でした。

実行の構成から、外部JARの追加で mysql-connector-java-5.1.18-bin を追加して、無事データベースに接続できることができました。

コンピュータプログラミングを勉強し始めて三ヶ月目でわからないことばかりで、質問文もうまく書けてない中、優しいお言葉を下さった$さま、解決への緒を下さったsatomiさまに感謝です。これからも精進していきたいと思います。どうもありがとうございました。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。