# サーブレットでDBの利用
## 環境
今回はMySQL(xampp)を使います
サーブレットの作成はエクリプスを使用
## 参考資料
ゼロからわかる-サーブレット&JSP超入門
### DBへの接続方法
Xamppのコントローラを管理者権限で実行し、ApacheとMySQLを起動します

次に(Windowsの)コマンドプロンプトを起動しmysql.exeがあるフォルダに移動します
デフォルトだとxampp>mysql>binの中にあると思います


うつコマンドは「cd フォルダの絶対パス」です
そして移動したら今度は「mysql -u root -p
」とうってデフォルトのままだとパスワードは設定されてないのでそのままエンターを押すとWelcome to the MariaDB monitor.・・・と出ると思います
これでDBにアクセスすることが可能です。
ここからDBを作成したり参照したりすることができますがXAMPPのコントロールパネルからMYSQLのAdminからPHPMyAdminにアクセスをしても見ることができます。
まぁどちらのアクセス方法でもいいのでDBに次のデータを追加します。
```
CREATE DATABASE sns;
USE sns;
CREATE TABLE users(
userId int(11) PRIMARY KEY AUTO_INCREMENT,
loginId varchar(32) UNIQUE,
password varchar(32),
userName varchar(64),
icon varchar(128),
profile varchar(128)
);
CREATE TABLE shouts(
shoutsId int(11) PRIMARY KEY AUTO_INCREMENT,
userName varchar(32),
icon varchar(64),
date datetime,
writing varchar(256)
);
INSERT INTO users(loginId,password,userName,icon,profile) VALUES('yamada','pass1','山田 太郎','icon-user','はじめまして');
INSERT INTO users(loginId,password,userName,icon,profile) VALUES('suzuki','pass2','鈴木 花子','icon-user-female','東京都在住です');
INSERT INTO users(loginId,password,userName,icon,profile) VALUES('itou','pass3','伊藤 恵','icon-bell','趣味は読書');
```
今回はPHPMyAdminから実行していきます

まずはアクセスした画面上部にこのようなバーがあるのでSQLを選択し、先ほどのSQL文を張り付けて右下にある実行を押します

また、PHPMyAdminにアクセスできない場合はxamppのポート番号を変えている可能性が高いのでアクセスする際のURLにポート番号を付けたす必要があります
自分はポート番号を180で使用しているため、ローカルホストのアドレスの後にポート番号の180が入っています
http://localhost:180/phpmyadmin/
正常にSQL文が実行されるとこのように作成されます

### サーブレットの作成&編集
まずエクリプスを起動し、右上にあるパースペクティブを開くからJavaEEを選ぶ。

### 新規プロジェクトの作成
エクリプスの左上のファイルから「新規」→動的Webプロジェクトを選択

次にプロジェクト名を付ける画面に遷移するのでここで好きなプロジェクト名を入力する

プロジェクト名以外はデフォルトのまま「次へ」を押します。
この画面↓もデフォルトのままでOK‼

また「次へ」を押します。
↓今回はアノテーションを使うのでxmlは使いません

ここまできたら完了を押してしばらく待つだけです。
作成が終わると↓のような階層構造になっています。

上記のは次の作成手順で使うものを使いまわしているだけなので名前とかは関係ないです。今回はプロジェクト名やコンテキストルート(アクセスする際のURLが変わるだけです)はお好きなのをつけてください
また今回使うのはDBAccess.javaを使用します
```
package section9_2;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class DBAccess
*/
@WebServlet("/da")
public class DBAccess extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public DBAccess() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 文字化け対策
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// HTML 出力準備
PrintWriter out = response.getWriter();
// データベース接続に必要な情報
final String DSN = "jdbc:mysql://localhost:3306/sns?useSSL=false";
final String USER = "root";
final String PASSWORD = null;
// データベース接続情報管理
Connection conn = null;
// SQL 情報管理
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
PreparedStatement pstmt3 = null;
// SELECT 文の実行結果管理
ResultSet rset1 = null;
ResultSet rset2 = null;
out.println("<html lang='ja'>");
out.println("<head>");
out.println("<title>データベースの連携</title>");
out.println("</head>");
out.println("<body>");
try {
// JDBC ドライバのロード
Class.forName("com.mysql.jdbc.Driver");
// データベース接続
conn = DriverManager.getConnection(DSN, USER, PASSWORD);
// SQL 文(検索)の作成と実行
String sql = "SELECT * FROM users WHERE userId=?";
pstmt1 = conn.prepareStatement(sql);
pstmt1.setInt(1, 1);
rset1 = pstmt1.executeQuery();
out.println("<p>1件検索</p>");
out.println("<pre>");
// 検索結果があるか
if (rset1.next()) {
out.print(rset1.getString(2) + ":");
out.print(rset1.getString(3) + ":");
out.print(rset1.getString(4) + ":");
out.print(rset1.getString(5) + ":");
out.println(rset1.getString(6));
}
out.println("</pre>");
out.println("<hr>");
// SQL 文(挿入)の作成と実行
sql = "INSERT INTO users(loginId,password,userName,icon,profile) VALUES(?,?,?,?,?)";
pstmt2 = conn.prepareStatement(sql);
pstmt2.setString(1, "tanaka");
pstmt2.setString(2, "pass4");
pstmt2.setString(3, "田中 純次");
pstmt2.setString(4, "icon-user");
pstmt2.setString(5, "こんにちは");
pstmt2.executeUpdate();
// SQL 文(検索)の作成と実行
sql = "SELECT * FROM users";
pstmt3 = conn.prepareStatement(sql);
rset2 = pstmt3.executeQuery();
out.println("<p>全件検索</p>");
out.println("<pre>");
// 問合せ結果の行数分繰り返し
while(rset2.next()) {
out.print(rset2.getString(2) + ":");
out.print(rset2.getString(3) + ":");
out.print(rset2.getString(4) + ":");
out.print(rset2.getString(5) + ":");
out.println(rset2.getString(6));
}
out.println("</pre>");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
} finally {
try {
rset1.close();
} catch (SQLException e) { }
try {
rset2.close();
} catch (SQLException e) { }
try {
pstmt1.close();
} catch (SQLException e) { }
try {
pstmt2.close();
} catch (SQLException e) { }
try {
pstmt3.close();
} catch (SQLException e) { }
try {
conn.close();
} catch (SQLException e) { }
}
out.println("</body>");
out.println("</html>");
}
/**
* @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);
}
}
```
パッケージなどは適宜かえてください
また、パスワードを設定していない場合は""だけだとエラーになる可能性が高いのでnullにするのをおすすめします
これでサーバにこのプロジェクトを追加して実行すると動くようになります
最初は全件表示されますが、2回目以降は既に田中さんを新しく追加しているので、エラーを吐きます。なのでその際はINSERTの部分をコメントアウトしましょう