検索

キーワード


【Java】Webアプリケーションからデータベースへの接続

  • 公開日:2020-10-30 11:59:08
  • 最終更新日:2020-11-16 22:11:05
【Java】Webアプリケーションからデータベースへの接続

こんにちは。エンジニアの新田です!

ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。

今回は、Javaサーブレットからデータベースに接続する方法を紹介します。

Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!

関連記事:【Java】JDBCとは? 【データベース】PostgreSQLをWindowsにインストール 【データベース】データベースとテーブルの作成(PostgreSQL) 【Java】Webアプリケーションでのコネクションプーリング


Javaからのデータベース接続とJDBC

Webアプリケーションを構築するにあたり、データベースの存在は必須ではなく、通常のファイルなどにデータを保存する事も可能です。

しかし、実際にはデータベースを利用した方が効率的に多くのデータを扱える場合が多く、一般的なWebアプリケーションの多くがデータベースを利用しています。

この記事では、Javaからデータベースに接続する基本的な手順について説明します。



JDBCとは

JDBCとは、Javaからデータベースを利用するためのJava標準APIです。

JDBCを利用することにより、接続先のデータベースに依存することなく、データベースを利用するJavaプログラムを作成することが可能になります。

Oracle, PostgreSQL, MySQL など、ほとんどのメジャーなデータベースにはJDBCドライバが用意されており、JDBC経由でのJavaからの接続が可能になっています。

この記事では、データベースとしてPostgreSQLを用意して接続する場合の手順を紹介します。


【Java】JDBCとは?

【データベース】PostgreSQLをWindowsにインストール

【データベース】データベースとテーブルの作成(PostgreSQL)




Javaプログラムからの基本的なデータベース接続手順

Javaプログラムからデータベースを操作する場合、以下の手順を踏む必要があります。

  1. JDBC ドライバのロード
  2. データベースサーバへの接続を確立
  3. SQL 文の実行
  4. SQL 文実行結果の取出し
  5. データベースサーバへの接続を切断

これらの手順について説明していきますが、先にこの手順を組み込んだサンプルコードを紹介します。

PostgreSQLに作成したmemberテーブルを参照し、全てのデータを表示するプログラムです。

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

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

public class DBConnectSample extends HttpServlet
{

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		Connection conn = null;

		response.setContentType("text/html; charset=Windows-31J");
		PrintWriter out = response.getWriter();
		out.println("<html><head></head><body>");
		out.println("<table border=’true’>");
		out.println("<tr><th>id</th><th>氏名</th><th>年齢</th><th>メールアドレス</th></tr>");

		try {
			Class.forName("org.postgresql.Driver"); // JDBC ドライバのロード
			String url = "jdbc:postgresql://localhost:5432/devdb01"; // 接続先URL
			String user = "devuser01"; //ユーザ名
			String password = "devuser01"; // パスワード

			conn = DriverManager.getConnection(url, user, password); // 接続の確立

			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery("SELECT * FROM member"); // SQL文の実行

			while (rs.next()) { // SQL実行結果の取り出し
				out.print("<tr>");
				out.print("<td>"+rs.getString("id")+"</td>");
				out.print("<td>"+rs.getString("name") + "</td>");
				out.print("<td>"+rs.getString("age") + "</td>");
				out.print("<td>"+rs.getString("email") + "</td>");
				out.print("</tr>");
			}
		}
		catch (ClassNotFoundException e) {
			out.println("クラスが見つかりません。");
		}
		catch (SQLException e) {
			out.println("データベース操作中にエラーがありました。");
			e.printStackTrace();
		}
		finally {
			try {
				if (conn != null)
					conn.close(); // 接続の切断
			}
			catch (SQLException e) {}
		}

		out.println("</table>");
		out.println("</body></html>");
		out.close();
	}
}


実行結果

JDBCを使ってデータベースを操作するプログラムの実行結果



JDBC ドライバのロード

JDBC を利用する場合、通常はJDBCドライバを動的(プログラム実行時)にロードします。クラスを動的にロードする場合は「Class.forName(String className)」を使用します。

PostgreSQLの場合、動的にロードするJDBCドライバクラス名は"org.postgresql.Driver"になりますので、以下のように記述します。

Class.forName("org.postgresql.Driver");

これで、JDBC ドライバがロード・登録され、利用可能な状態になります。

このメソッドは対応するクラスを見付けられなかった場合、ClassNotFoundExceptionが発生しますのでcatchブロックで対象の例外を処理する必要があります。




データベースサーバへの接続を確立

データベースサーバとの通信を確立するためには、

DriverManager.getConnection(String url, String user, String password)」を使用します。

第1引数には、接続のためのURLを記述します。

URL表記は、データベースを利用するためのJDBCドライバの種類とデータベースのある場所を示しています。

今回はローカルホスト(Servlet コンテナと同一のホスト)で動作しているPostgreSQLにアクセスしますので以下のようになります。

第2引数にはユーザ名、第3引数にはパスワードを記述しますので、データベース構築時に設定したユーザーとパスワードを設定します。

String url = "jdbc:postgresql://localhost:5432/devdb01"; // 接続先URL
String user = "devuser01"; //ユーザ名
String password = "devuser01"; // パスワード

conn = DriverManager.getConnection(url, user, password); // 接続の確立

urlの形式:{JDBCドライバ名}//{接続先ホスト名}:{ポート番号}/{データベース名}


データベースへ接続が確立できた場合は戻り値としてjava.sql.Connection型のオブジェクトが返されます。

以降はこのオブジェクトを利用してデータベースを操作します。

データベースへの接続は比較的コストのかかる処理であるため、Webアプリケーションではコネクションプーリングという方法を使う事の方が多くなります。これは一度確立した接続を何度も再利用するというものです。コネクションプーリングについては別の記事で紹介します。





SQL文の実行

データベースに対してSQL文を実行するためにはjava.sql.Statementクラスのオブジェクトを用意する必要があります。

このStatementオブジェクトはConnectionオブジェクトの「createStatement()」メソッドで生成する事ができます。

次にStatementオブジェクトの「executeQuery(String sql)」メソッドを使って実行したいSQL文(Query)を渡します。

データベースではこのSQL文が実行され、結果が返却されます。

このexecuteQueryメソッドの戻り値は、java.sql.ResultSetクラスのオブジェクトです。

Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM member"); // SQL文の実行


なお、これらのデータベース操作は例外が発生する可能性があります。データベース操作に関する例外は、ほとんどの場合「SQLException」クラスに属するものなので、catchブロックでこの例外を処理しています。




SQL文実行結果の取出し

executeQueryメソッドの戻り値として返された「ResultSet」オブジェクトはクエリの実行結果を保持しています。

初期状態ではカーソル(現在行)が最初のデータの前の行を指し示していて、「next()」メソッドを呼び出すことによってカーソルを次の行に移動します。

while (rs.next()) { // SQL実行結果の取り出し

最初の「next()」メソッド呼び出しによって、先頭のデータが取得対象(現在行)になります。

また、次の行がない場合、「next()」メソッドはfalse を返します。


データの取り出しには、ResultSetオブジェクトの「getString(String columnLabel)」メソッドを使います。引数に列名を指定して呼び出すと、現在行の指定された列のデータをString型で返します。

out.print("<td>"+rs.getString("id")+"</td>");
out.print("<td>"+rs.getString("name") + "</td>");
out.print("<td>"+rs.getString("age") + "</td>");
out.print("<td>"+rs.getString("email") + "</td>");

上記のサンプルコードでは、PostgreSQLに作成したmemberテーブルに対してQueryを実行しています。

このテーブルには、id, name, age, email という列が存在していて、それぞれgetStringメソッドで値を取得していますす。


ResultSet クラスにはgetStringの他にも、「getInt(String columnLabel)」メソッドなど他の型のデータを取り出すgetterメソッドが用意されています。また、それぞれのgetterメソッドには引数に文字列で列名を指定するのではなく、列のインデックスで取得対象列を指定する「getString(int columnIndex)」メソッドなども用意されています。

詳しくは、java.sql.ResultSetクラスのJavaDocを参照してください。




接続の切断

データベースを利用する場合、接続の切断は確実に行なう必要があります。

利用しなくなった接続を残したままにしておくと、リソースが無駄に消費されてしまい、パフォーマンスの劣化が発生する場合や、最悪の場合リソース不足に陥る可能性があります。


上記のサンプルコードでは接続の切断を確実に行なうために、データベースに関する操作を全てtryブロックの中で実装し、それに対応するfinallyブロック内で接続の切断を行う「conn.close()」メソッドを実行しています。

finally {
	try {
		if (conn != null)
			conn.close(); // 接続の切断
	}
	catch (SQLException e) {}
}




今回紹介した内容は、Javaの基本的なDB接続とデータ操作方法(Query)です。

次の段階では、Webアプリケーションでのデータベース接続の効率的な管理(コネクションプーリング)や、データベースのレコード(データ)とJavaのオブジェクトをマッピングする方法(ORマッパー)などを紹介していきます。




関連記事:【Java】JDBCとは? 【データベース】PostgreSQLをWindowsにインストール 【データベース】データベースとテーブルの作成(PostgreSQL) 【Java】Webアプリケーションでのコネクションプーリング



【著者】

新田

JavaメインのWebアプリケーション開発に多く携わっています。
Javaの基本的な部分の紹介や、これまで経験したシステム開発手法、新しい技術についても紹介していこうと思います。

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様