Java Eclipseで動的 WebプロジェクトでMySQL接続

MySQL 5.7.19が早くもリリースされていたようですが、わたしが使っているのは5.7.18のようです。 

EclipseのDBViewerでデータベースの作成

まずは、Eclipseで「DBViewer」のパースペクティブを開きます。

「ウィンドウ(W)」「パースペクティブ(R)」>「パースペクティブを開く(O)」>「その他(O)...」を選択。

f:id:ts0818:20170801194038j:plain

「DBViewer」を選択し、「OK」。

f:id:ts0818:20170801194033j:plain

パースペクティブ「DBViewer」になりました。

f:id:ts0818:20170801194030j:plain

「DBViewer」が選択された状態になっています。

f:id:ts0818:20170801194027j:plain

「ウィンドウ(W)」>「ビューの表示(V)」>「SQL 実行・ビュー」を選択して、SQL 実行・ビュー」を表示させます。(「SQL 実行・ビュー」が見つからない場合は、「その他(O)...」にあるかもです。)

f:id:ts0818:20170801194023j:plain

右下にSQL 実行・ビュー」が表示されます。

f:id:ts0818:20170801194845j:plain

ここにSQL文が記述できます。

f:id:ts0818:20170801194842j:plain

記述したら、f:id:ts0818:20170801194830j:plainボタンで実行できます。

f:id:ts0818:20170801194832j:plain

で、エラー!

f:id:ts0818:20170801195252j:plain

『There is no Data Base definition information. 』 で翻訳にかけたところ、『データベースベースの定義情報はありません。』とのこと。

致し方ないので、「DBツリー・ビュー」の「DBViewerPlugin」を選択し右クリックし、「登録(A)」を選択。

f:id:ts0818:20170801204830j:plain

「データベース定義名」を入力し、「ファイルの追加(F)」をクリック。

f:id:ts0818:20170801204827j:plain

MySQLをインストールしたときにインストールされているJDBCドライバを選択。自分の場合は、『C:¥Program Files (x86MySQL¥Connector.J 5.1¥mysql-connector-java-5.1.41-bin.jar』 のファイルを選択。

f:id:ts0818:20170801204822j:plain

「次へ(N)>」を選択。

f:id:ts0818:20170801204819j:plain

JDBC Driver(J):」から「com.mysql.jdbc.Driver」を選択。

f:id:ts0818:20170801204814j:plain

「OK」を選択。 

f:id:ts0818:20170801205538j:plain

「接続文字列(S)」の入力を求められたら、

f:id:ts0818:20170801205535j:plain

jdbc:mysql://localhost:3306/使用したいデータベース名」を入力(今回は『webdb』)。「接続ユーザ」「接続パスワード」は両方ともデフォルトの『root』を使ってます。

f:id:ts0818:20170801205530j:plain

「テスト接続(T)」をクリックして、「接続に成功しました」と表示されればOK。(何回か接続に失敗とかなったので、DBViewerちょっと安定してない気が...)。

「次へ(N)>」をクリック。

f:id:ts0818:20170801205527j:plain

何も変更せず、「完了(F)」をクリック。

f:id:ts0818:20170801205523j:plain

 「DB ツリー・ビュー」に「webdb」が表示されました。 

f:id:ts0818:20170801210325j:plain

「DB ツリー・ビュー」の「webdb」を選択し、右クリックで「接続(C)」をクリック。

f:id:ts0818:20170801210315j:plain

SQL 実行・ビュー」で、

USE webdb;

を入力し、f:id:ts0818:20170801194830j:plain をクリック。

f:id:ts0818:20170801210311j:plain

SQL 実行・ビュー」で、

create table member(
id int,
name VARCHAR(100),
pass VARCHAR(100)
);

を入力し、f:id:ts0818:20170801194830j:plain をクリック。

f:id:ts0818:20170801211036j:plain

「DB ツリー・ビュー」の「webdb」>「TABLE」 を選択し、右クリックし「更新(F)」をクリック。

f:id:ts0818:20170801211033j:plain

「DB ツリー・ビュー」の「webdb」>「TABLE」の中に『member』テーブルが作成れていればOK。 

f:id:ts0818:20170801211030j:plain

 

動的 Web プロジェクトからMySQLデータベースに接続

パースペクティブを「Java」 に切り替えて、「ファイル(F)」>「新規(N)」>「その他(O)...」をクリック。

f:id:ts0818:20170801213114j:plain

「Web」>「動的 Web プロジェクト」を選択し、「次へ(N)>」をクリック。

f:id:ts0818:20170801213110j:plain

「プロジェクト名(M):」を入力し「完了(F)」。

f:id:ts0818:20170801213107j:plain

プロジェクトの中の「src」を選択した状態で、右クリックし「新規(W)」>「パッケージ」を選択。

f:id:ts0818:20170801213104j:plain

「名前(M):」を「model」とし「完了(F)」。

f:id:ts0818:20170801213100j:plain

同じ流れで、「dao」「servlet」のパッケージを作成。

f:id:ts0818:20170801213637j:plain

「model」 パッケージを選択した状態で、「新規(W)」>「クラス」を選択。

f:id:ts0818:20170801214106j:plain

「名前(M):」を入力し、「完了(F)」をクリック。

f:id:ts0818:20170801214103j:plain

同じ流れで、クラスを作成していきます。

f:id:ts0818:20170801222205j:plain

次に、「sevlet」パッケージを選択した状態で、右クリックし、「新規(W)」>「その他(O)...」を選択。

f:id:ts0818:20170801215106j:plain

「Web」>「サーブレット」を選択し、「次へ(N)>」をクリック。

f:id:ts0818:20170801215601j:plain

「クラス名(M)」を入力し、「完了(F)」。

f:id:ts0818:20170801215557j:plain

javaファイル関連のファイルができたので、次はjspファイルを作成していきます。

f:id:ts0818:20170801215554j:plain

プロジェクトの中の「WebContent」>「WEB-INF」 を選択した状態で、「新規(W)」>「フォルダー」を選択。

f:id:ts0818:20170801220704j:plain

「フォルダー名(N)」を入力し、「完了(F)」をクリック。

f:id:ts0818:20170801220700j:plain

作成されたフォルダを選択した状態で、「新規(W)」>「その他(O)...」を選択。

f:id:ts0818:20170801220657j:plain

「Web」>「JSP ファイル」を選択し、「次へ(N)>」をクリック。

f:id:ts0818:20170801220654j:plain

「ファイル名(M)」を入力し、「完了(F)」をクリック。

f:id:ts0818:20170801220651j:plain

同じ流れで、jspファイルを2つ作成します。(全部で3つのjspファイルを作ります。)

f:id:ts0818:20170801221940j:plain

ファイルを編集していきます。

daoパッケージ

ConnectionManager.java

package dao;

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

public class ConnectionManager {

	// URL・ユーザ名・パスワードの設定
	private final static String URL = "jdbc:mysql://localhost:3306/webdb?useSSL=false";
	private final static String USER = "root";
	private final static String PASSWORD = "root";
	// コネクションオブジェクト
	private Connection connection = null;

	 // このクラスに唯一のインスタンス
	private static ConnectionManager instance = new ConnectionManager();

	/*
	 * static初期化子
	 */
	static {
		// JDBCドライバのロード
		String drv = "com.mysql.jdbc.Driver";
		try {
			Class.forName(drv);
		} catch (ClassNotFoundException e) {
			System.out.println("ドライバがありません" + e.getMessage());
		}
	}

	/**
	 * コンストラクタ
	 */
	private ConnectionManager() {	}
	/*
	 * インスタンス取得メソッド
	 */
	public static ConnectionManager getInstance() { return instance; }

	/**
	 * DBの接続	 *
	 * @return コネクション
	 * @throws Exception
	 */
	public synchronized Connection getConnection() throws DAOException {
		// 	コネクションの確立
		try {
			connection = DriverManager.getConnection(URL, USER, PASSWORD);
		} catch (SQLException e) {
			connection = null;
			throw new DAOException("[conect]異常", e);
		}
		return connection;
	}

	/**
	 * DBの切断
	 */
	public void closeConnection() throws DAOException{
		try {
			if (connection != null) { 	connection.close(); }
		} catch (SQLException e) {
			throw new DAOException("[closeConnection]異常", e);
		} finally {
			connection = null;
		}
	}
}

DAOException.java

/*
 * JDBCSample02
 * DAOException.java
 */

package dao;

/**
 * データアクセスオブジェクト例外
 */
public class DAOException extends Exception {
	/**
	 * @param str
	 * @param th
	 */
	public DAOException(String str, Throwable th) {
		super(str, th);
	}
}

MemberDao.java

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import model.User;

public class MemberDao {

	private Connection con = null; 	// コネクションオブジェクト
	private Statement stmt = null; 	// ステートメントオブジェクト
	private ConnectionManager cm; // コネクションマネージャー

	// Connectionの取得
	private void getConnection() throws DAOException{
		if ( this.con != null ){ return; 	}
		cm = ConnectionManager.getInstance();
		con = cm.getConnection(); // データベースへの接続の取得
	}

	// Statementの取得
	private void createStmt() throws DAOException{
		if ( this.stmt != null){ 	return; }
		try {
			stmt =con.createStatement();
		} catch (SQLException e) {  // SQLに関する例外処理
			throw new DAOException("[createStmt]異常", e);
		}
	}

	// データを追加
	public int insertMember(User user) throws DAOException {
		getConnection();
		int count = 0;
		String sql = "INSERT INTO member (id, name, pass) VALUES(?, ?, ?)";
		int id = Integer.parseInt(user.getId());
		String name = user.getName();
		String pass = user.getPass();

		try(PreparedStatement pstmt = con.prepareStatement(sql)) {
			pstmt.setInt(1, id);
			pstmt.setString(2, name);
			pstmt.setString(3, pass);
			count += pstmt.executeUpdate();
		} catch(SQLException e) {
			throw new DAOException("[UserDAO#insertMember]異常", e);
		} finally {
			close();
		}
		return count;
	}

	private void close() throws DAOException {
		try {
			if (stmt != null) { stmt.close(); }
		} catch (SQLException e) {
			throw new DAOException("[closeStatement]異常", e);
		} finally {
			this.stmt = null;
			this.cm = null;
		}
	}
}

modelパッケージ

User.java

package model;

import java.io.Serializable;

public class User implements Serializable {

	//フィールド
	private String id;
	private String name;
	private String pass;

	public User(){}
	public User(String id, String name, String pass){
		this.id = id;
		this.name = name;
		this.pass = pass;
	}

	//アクセッサ
	public String getId() {
		return id;
	}
	public String getName() {
		return name;
	}
	public String getPass() {
		return pass;
	}
}

RegisterUserLogic.java

package model;

import dao.DAOException;
import dao.MemberDao;

public class RegisterUserLogic {
  MemberDao memberDao = new MemberDao();
	public boolean exute(User user){
		boolean registCheck = false;
		//登録処理
		try {
			memberDao.insertMember(user);
			registCheck = true;
		} catch (DAOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
		return registCheck;
	}
}

servletパッケージ

RegisterUser.java

package servlet;

import java.io.IOException;

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

import model.RegisterUserLogic;
import model.User;

/**
 * Servlet implementation class RegisterUser
 */
@WebServlet("/RegisterUser")
public class RegisterUser extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public RegisterUser() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		// TODO Auto-generated method stub
//		response.getWriter().append("Served at: ").append(request.getContextPath());

		//フォワード先
		String forwardPath = null;

		//サーブレットクラスの動作を決定する「action」の値を
		//リクエストパラメータから取得
		String action = request.getParameter("action");

		//「登録の開始」をリクエストされたときの処理
		if(action == null){
			//フォワード先を設定
			forwardPath = "/WEB-INF/jsp/registerForm.jsp";
		}
		//登録確認画面から「登録実行」をリクエストされたときの処理
		else if(action.equals("done")){
			//セッションスコープに保存された登録ユーザを
			HttpSession session = request.getSession();
			User registerUser = (User)session.getAttribute("registerUser");

			//登録処理の呼び出し
			RegisterUserLogic logic = new RegisterUserLogic();
			logic.exute(registerUser);

			//不要となったセッションスコープ内のインスタンスを削除
			session.removeAttribute("registerUser");

			//登録後のフォワード先を設定
			forwardPath = "/WEB-INF/jsp/registerDone.jsp";

		}

		// 設定されたフォワード先を設定
		RequestDispatcher dispatcher = request.getRequestDispatcher(forwardPath);
		dispatcher.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		// TODO Auto-generated method stub
//		doGet(request, response);

		//リクエストパラメータの取得
		request.setCharacterEncoding("UTF-8");
		String id = request.getParameter("id");
		String name = request.getParameter("name");
		String pass = request.getParameter("pass");

		//登録するユーザの情報を設定
		User registerUser = new User(id, name, pass);

		//セッションスコープに登録ユーザを保存
		HttpSession session = request.getSession();
		session.setAttribute("registerUser", registerUser);

		//フォワード
		RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/registerConfirm.jsp");
		dispatcher.forward(request, response);
	}
}

jspファイル

registerForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ユーザー登録</title>
</head>

<body>
<form action="/Web/RegisterUser" method="post">
ログインID:<input type="text" name="id">
パスワード:<input type="text" name="pass"><br>
名前:<input type="text" name="name"><br>
<br>
<input type="submit" value="確認">
</form>

</body>
</html>

registerConfirm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ page import="model.User" %>
<%User registerUser = (User) session.getAttribute("registerUser");%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ユーザー登録</title>
</head>

<body>
<p>下記のユーザーを登録します。</p>

<p>
ログインID:<%= registerUser.getId()%><br>
名前:<%= registerUser.getName()%><br>
</p>
<br>
<a href="/Web/RegisterUser">戻る</a>
<a href="/Web/RegisterUser?action=done">登録</a>
</body>
</html>

registerDone.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ユーザー登録</title>
</head>
<body>
<p>登録完了しました。</p>
<br>
<a href="/Web/RegisterUser">戻る</a>
</body>
</html>

ファイルの編集が終わったら、「パッケージ・エクスプローラー」でプロジェクトを選択した状態で、右クリックし、「実行(R)」>「実行の構成」をクリック。

f:id:ts0818:20170801232343j:plain

「クラスパス」タブを選択し、「ブートストラップ・エントリー」を選択し、「外部JARの追加(X)...」をクリック。

f:id:ts0818:20170801232337j:plain

『C:¥Program Files (x86MySQL¥Connector.J 5.1¥mysql-connector-java-5.1.41-bin.jar』を選択。(JDBCドライバの追加ができればOK)

f:id:ts0818:20170801232340j:plain

http://localhost:8080/プロジェクト名/サーブレット』にアクセスでエラー!(ここでは、『http://localhost:8080/Web/RegisterUser』にアクセスしてます。)

f:id:ts0818:20170801232331j:plain

Eclipseのサーバー(『ローカルホストのTomcat v×.× サーバー』)をダブルクリック。

f:id:ts0818:20170801232333j:plain

左下の「モジュール」タブを選択し、「Webモジュールの追加...」をクリック。

f:id:ts0818:20170801233536j:plain

「モジュール(M):」から、プロジェクト(今回は『Web』というプロジェクト)を選択し、「OK」をクリック。ファイルを保存します。

f:id:ts0818:20170801233533j:plain

「サーバー」を再起動します。

f:id:ts0818:20170801233529j:plain

再び、ブラウザでhttp://localhost:8080/Web/RegisterUser』にアクセス。RegisterUser.javaサーブレットで、doGet()メソッドが実行され、registerForm.jspが表示されてます。

f:id:ts0818:20170801233521j:plain

入力し、『確認』ボタンをクリック。

f:id:ts0818:20170801233518j:plain

RegisterUser.javaサーブレットで、doPost()メソッドが実行され、registerConfirm.jspが表示されました。「登録」のリンクをクリック。リンクのパラメーターにactionが付いてます。

f:id:ts0818:20170801234232j:plain

RegisterUser.javaサーブレットで、doGet()メソッドが実行され、actionの有無で判定された処理がされ、Userクラスのインスタンス(doPost()で入力された値をもとに生成されてたUserクラスのインスタンス)を引数として、RegisterUserLogic.javaのexcute()メソッドが実行され、excute()メソッド内でMemberDao.javaのinsertMember()メソッドが実行されることで、DBのmemberテーブルに入力された値が登録され、フォワードされてregisterDone.jspまで表示されました。

f:id:ts0818:20170801234229j:plain

実際にDBに登録されているか、確認。パースペクティブを「DBViewer」に切り替え、「DBツリー・ビュー」の「webdb」>「webdb」>「TABLE」>「member」をダブルクリック。入力したデータが格納されました。

f:id:ts0818:20170801234224j:plain

流れのイメージ的には、こんな感じですかね?

f:id:ts0818:20170802183635p:plain

  1. ブラウザで『http://localhost:8080/Web/RegisterUser』にアクセス
  2. RegisterUser.javaクラスのdoGet()メソッドで、registerForm.jspフォワードされる
  3. ブラウザにregisterForm.jspの内容が表示される
  4. registerForm.jspのformで『http://localhost:8080/Web/RegisterUser』にPOST送信
  5. formの入力値(requestスコープの値)をModelクラスのインスタンスに格納(registerUserとして)
  6. registerUserをsessionスコープに保存
  7. registerConfirm.jspフォワードされる
  8. ブラウザにregisterConfirm.jspの内容が表示される
  9. ブラウザで『http://localhost:8080/Web/RegisterUser』にアクセス(リンクでパラメーターaction="done"が付与)
  10. RegisterUser.javaクラスのdoGet()メソッドで、requestスコープのactionの値がdoneのときの処理が実行され、sessionスコープの値を取得
  11. sessionスコープの値を引数に、RegisterUserLogic.javaクラスのexute()メソッドを実行
  12. MemberDao.javaクラスのインスタンスを生成
  13. MemberDao.javaクラスのinsertMember()メソッドを実行
  14. 例外処理はDaoException.javaクラスに任せる
  15. ConnectionManager.javaクラスでデータベース接続、MemberDao.javaクラスのinsertMember()メソッドでSQLが実行され、データベースに入力値が登録される
  16. sessionスコープのregisterUserを破棄。
  17. registerDone.jspフォワードされる
  18. ブラウザにregisterDone.jspの内容が表示される

 

ちょっとしたformを作るのでも無茶苦茶たいへんですね。復習していかねばですね。