1

データベースへの接続を確立したサーブレット クラスが 1 つありMySQLます。これは私のメソッドのコードですdoGet()

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
           //Class.forName("com.mysql.jdbc.Driver");    
        con = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","rspl123#");
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    System.out.println(con);
    response.getWriter().write(request.getParameter("q"));

}

上記のコードでは、サーブレットが初めて呼び出されたときに例外がスローされNo suitable driver foundます。しかし、2回目以降は実行され、接続が正常に確立されます。

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/test
at java.sql.DriverManager.getConnection(DriverManager.java:602)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
at controller.FetchSuggestion.doGet(FetchSuggestion.java:44)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)

null
com.mysql.jdbc.JDBC4Connection@1b83048
com.mysql.jdbc.JDBC4Connection@1455d1c
com.mysql.jdbc.JDBC4Connection@1f51e5c

からコメントを削除すると、上記のコードは正常に機能しますClass.forName()が、最初はコメントなしでは機能せず、2 回目以降は接続を確立できません。参考までに: クラスパスには既に MySQL JAVA コネクタがあります。

MySQL Java コネクタ バージョン: 5.1.10
JDK: 1.6
IDE: MyEclipse for Spring

4

2 に答える 2

2

mysql-connector.jarまず、クラスパスに を含める必要があります。jar は次の場所からダウンロードできます。

次に、次のステートメントを使用してデータ ソース接続を構成できます。

  // This will load the MySQL driver, each DB has its own driver
  try
  {
  Class.forName("com.mysql.jdbc.Driver");
  }
  catch(ClassNotFoundException e)
  {
  e.printStackTrace();
  }

  // Now you can setup the connection with the DB
   Connection connection=null;
   try {
    connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/database","username", "password");
 } 
 catch (SQLException e) 
 {
    System.out.println("Connection Failed..!");
    e.printStackTrace();
}

の登録DriverClassNameは重要なステップです。スキップしないでください。

編集:私はあなたの問題を見つけたと思います。分析は次のとおりです。

  • アプリケーションが動作した理由Class.forNameは、このドライバをロードするように に明確に依頼したDriverManagerためです。
  • アプリケーションが初めて機能しなかった理由は、使用するドライバーを指定しなかったためです。

2 番目の点について詳しく説明します。

アプリケーションがなくても動作するはずだというあなたの言うことは絶対に正しいです。しかし、ああああ...キャッチがあります。Class.forName

  • を指定しないClass.forName場合、DriverManager は見つけられる限り多くのドライバーを読み込もうとし、特定の接続要求に対して、各ドライバーに順番にターゲット URL への接続を試みます。

これは、アプリケーションに複数のドライバーが含まれている可能性があることを意味します。DriverManager はこれらのドライバーを検出し、データベースへの接続を確立しようとしました最初に見つかったドライバーが正しくないため、接続は null でした。しかし、待ってください、DriverManager は smartです。データベースに接続できなかったことを認識しているため、見つかった他のドライバーを使用します。そしてすぐに、接続が確立されます。

参照を確認してください: Driver Interface。ドキュメントに記載されています。

それが役に立てば幸い。:)

于 2013-10-01T11:13:55.303 に答える
1

のソース コードjava.sql.DriverManagerを見ると、「最初の」ドライバー (つまり、明示的に読み込まれていないドライバー) を読み込むためのコードが、ドライバーを取得しようとする最初の試みによってトリガーされることがわかります。別のスレッドがドライバーを取得しようとすると、initialize()メソッドは進行中の初期化を待機せず、すぐに戻ります。

static void initialize() {
    if (initialized) {
        return;
    }
    initialized = true;
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
}

したがって、それは競合状態です。2 番目のスレッドはドライバーを見つけずに初期化をスキップしますが、初期化を行わないと時間がかからないため、最初のスレッドの前に確実に完了します。そのため、最初の試行は失敗したように見えますが、2 回目です。

于 2013-10-01T11:35:31.927 に答える