JSPでデータベースを利用する（Eclipse）

##概要
JSPの学習をしていて、DBに接続しようとしたときに発生した例外やエラーへの対処法をまとめてみました。また、学習するにあたり、なかなかいいサンプルコードを見つけることができなかったので、最後には簡単なサンプルも記載しています。

##環境
Tomcat 8.5
Eclipse IDE for Java EE Developers
mysql-connector-java-8.0.13

##問題の解決方法

###データベースに接続できない 
"No suitable driver found"という例外が発生し、データベースに接続できず、どうやったら解決できるものかと色々検索した結果、TomcatのlibフォルダーにJDBC driver（mysql-connector-java-8.0.13.jar）を入れていないことがわかりました。EclipseでJava Build Pathに追加しただけで、Tomcatの方には追加していませんでした。案外簡単なミスのように思われるかもしれませんが、初学者の私は解決策を見つけるのに苦労しました...。
（参考：[https://stackoverflow.com/questions/1911253/](https://stackoverflow.com/questions/1911253/)（英語））

###timezoneに関するエラーへの対処
原因はわかりませんが、Windowsでテストした際に、"The server time zone value '◇◇◇◇◇' is unrecognized or represents more than one time zone."（◇の部分は明らかな文字化け）というエラーが発生しました。その場合はencodingとserverTimezoneを設定することで回避できるようです。
（参考：[https://www.nakamuri.info](https://www.nakamuri.info/mw/index.php/Mysql-connector-java_%E3%81%AE%E3%83%90%E3%82%B0%E3%81%A7_Java%E3%81%8B%E3%82%89MySQL%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84)）

```java

con = DriverManager.getConnection(
      "jdbc:mysql://localhost:3306/test_db?characterEncoding=" +
      "UTF-8&serverTimezone=JST", 
      "ユーザ名", "パスワード");
```

##コード
データベースに名前を追加するだけの簡単なプログラム。本来は入力値をエスケープさせた方がよいのでしょうが、ここでは簡略化のため、そのまま利用しています。

```html:index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Database Test</title>
</head>
<body>
  <form method="POST" action="add_name.jsp">
	  <label for="name">名前: </label>
	  <input type="text" name="name">
	  <input type="submit" value="送信">
  </form>
</body>
</html>
```

```jsp:add_name.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    import="java.sql.*"%>
<%
request.setCharacterEncoding("UTF-8");
// データベースに接続
Connection connect = DriverManager.getConnection(
                     "jdbc:mysql://localhost:3306/sample_db?" +
		             "UTF-8&serverTimezone=JST",
	                 "root", "root");

PreparedStatement ps = connect.prepareStatement
    ("INSERT INTO names (name) values (?)");

String name = request.getParameter("name");
ps.setString(1, request.getParameter("name"));
ps.executeUpdate();

connect.close();
ps.close();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Database Test</title>
</head>
<body>
<p><%=name %>さんを追加しました。</p>
<a href="index.jsp">戻る</a>
</body>
</html>
```
#追記
この記事を投稿した後、参考書等をしっかり読んでみたところ、データベースへの接続にはDataSourceクラスのオブジェクトを利用するのが一般的だとわかりました。
この方法を利用するためには、まずcontext.xmlでデータソースの情報を定義します。
ここではsample_dbというデータベースにnamesというテーブルが存在すると仮定します。

```xml

<Context displayName="JSP Samples" docBase="jspSample"
  path="/jspSample" reloadable="true">
  <Resource name="jdbc/sample" auth="Container"
    type="javax.sql.DataSource"
    username="root" password=""
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost/sample_db?characterEncoding=utf-8&amp;serverTimezone=JST"
    maxActive="4" maxWait="5000" maxIdle="2"
    validationQuery="SELECT count(*) FROM names" />
</Context>
```
そして、jspファイルのほうで、以下のように変更します。

```java

// データベースにDriverManagerを使って接続する場合
Connection connect = DriverManager.getConnection(
                     "jdbc:mysql://localhost:3306/sample_db?" +
                     "UTF-8&serverTimezone=JST",
                     "root", "root");
//　上記のコードをDataSourceを利用する以下のコードに書き換える
Context context = new InitialContext();
DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/sample");
Connection db = ds.getConnection();
```
DataSourceクラスを用いることで、コネクションプーリングを利用することとなり、接続にかかる処理が省電力化できるそうです。（参考書：[JSP & サーブレット入門教室] (http://amzn.asia/d/eyBxlmn))