JSP & Servlet-8日目(MySQLとの連携)

JSP&Servlet

いよいよMySQLと連携させて、標準的なCRUDアプリを作成してみよう。
[実行例]
●スタート画面

●フォームに入力する

●登録ボタンを押すと、登録しましたというメッセージが表示されるとともに下部にリストアップ。

●同様の作業を繰り返し3件ほど登録する。

●更新ボタンを押すとその情報がフォームに表示され、編集モードとなる(図はpro3の更新を押した)

●値段を8000円に変更して、更新ボタンを押した。

●削除を押すと確認のダイアログ(今回はpro1の削除ボタンを押した)

●okを押すと項目が削除される。

[作成]
1.MySQLでデータベース[product]を作成する。

CREATE DATABASE product
DEFAULT CHARACTER SET utf8;

2.データベースproductに[products]テーブルを作成する。

CREATE TABLE products(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
price INT,
updated DATETIME
);

3.https://dev.mysql.com/downloads/connector/j/にアクセスして、MySQLのJDBCをダウンロードする。(バージョンは5.1.47推奨2021年追記)

遷移したら「No thanks, just start my download.」をクリック

4.エクリプス。新規動的Webプロジェクトを選択し「joytas8」を作成する。
5.WEB-INFフォルダにあるlibフォルダに先程ダウンロードしたJDBCをコピペで貼り付ける。

6.context.xmlを以下のように編集。

<?xml version="1.0" encoding="UTF-8" ?>
<Context>
  <Resource
      name="jdbc/jsp"
      auth="Container"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/product"
      connectionProperties="<span>autoReconnect=true;verifyServerCertificate=false;useSSL=false;requireSSL=false;useUnicode=true;characterEncoding=UTF-8;</span>"
      username="root"
      validationQuery="select 1"/&amp;amp;amp;gt;
 &amp;amp;amp;lt;/Context&amp;amp;amp;gt;

上はrootユーザー、パスワードなしが前提だが、ユーザー、パスワードを設定している場合は以下

&amp;amp;amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;amp;amp;gt;
&amp;amp;amp;lt;Context&amp;amp;amp;gt;
  &amp;amp;amp;lt;Resource
      name="jdbc/jsp"
      auth="Container"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/product"
      connectionProperties="autoReconnect=true;verifyServerCertificate=false;useSSL=false;requireSSL=false"
      username="ユーザーネーム"
      password="パスワード"
      validationQuery="select 1"/&amp;amp;amp;gt;
 &amp;amp;amp;lt;/Context&amp;amp;amp;gt;

7.作成したcontext.xmlをMETA-INFの直下に配置

8.modelの作成。modelパッケージにProductクラスを以下のように作成
●model.Product.java


package model;
import java.io.Serializable;

public class Product implements Serializable{
	private int id;
	private String name;
	private int price;
	private String updated;
	public Product(){}
	public Product(String name,int price,String updated){
		this.name=name;
		this.price=price;
		this.updated=updated;
	}
	public Product(int id,String name,int price,String updated){
		this(name,price,updated);
		this.id=id;

	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getUpdated() {
		return updated;
	}
	public void setUpdated(String updated) {
		this.updated = updated;
	}	

}

9.DAOの作成。daoパッケージを作成し、その中にProductDAO.javaを作成する。
●dao.ProductDAO.java

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import model.Product;

public class ProductDAO {
	private Connection db;
	private PreparedStatement ps;
	private ResultSet rs;

private void getConnection() throws NamingException, SQLException{
			Context context=new InitialContext();
			DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/jsp");
			this.db=ds.getConnection();
	}
	private void disconnect(){
		try{
			if(rs != null){rs.close();}
			if(ps != null){ps.close();}
			if(db != null){db.close();}
		}catch(SQLException e){
			e.printStackTrace();
		}
	}
	public List&amp;amp;amp;lt;Product&amp;amp;amp;gt; findAll(){

		List&amp;amp;amp;lt;Product&amp;amp;amp;gt; productList=new ArrayList&amp;amp;amp;lt;&amp;amp;amp;gt;();
		try {
			this.getConnection();
			ps=db.prepareStatement("SELECT * FROM products ORDER BY id DESC");
			rs=ps.executeQuery();
			while(rs.next()){
				int id=rs.getInt("id");
				String name=rs.getString("name");
				int price=rs.getInt("price");
				SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String updated=sdf.format(rs.getTimestamp("updated"));
				Product product=new Product(id,name,price,updated);
				productList.add(product);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return productList;
	}
	public boolean insertOne(Product product){
		try {
			this.getConnection();
			ps=db.prepareStatement("INSERT INTO products(name,price,updated) VALUES(?,?,?)");
			ps.setString(1,product.getName());
			ps.setInt(2,product.getPrice());
			ps.setString(3, product.getUpdated());
			int result=ps.executeUpdate();
			if(result != 1){
				return false;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return true;
	}
	public Product findOne(int id){
		Product product=null;
		try{
			this.getConnection();
			ps=db.prepareStatement("SELECT * FROM products WHERE id=?");
			ps.setInt(1, id);
			rs=ps.executeQuery();
			if(rs.next()){
				String name=rs.getString("name");
				int price=rs.getInt("price");
				String updated=rs.getString("updated");
				product=new Product(id,name,price,updated);
			}

		}catch (SQLException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return product;
	}
	public boolean updateOne(Product product){
		try{
			this.getConnection();
			ps=db.prepareStatement("UPDATE products SET name=?,price=?,updated=? WHERE id=?");
			ps.setString(1, product.getName());
			ps.setInt(2, product.getPrice());
			ps.setString(3, product.getUpdated());
			ps.setInt(4, product.getId());
			int result=ps.executeUpdate();
			if(result != 1){
				return false;
			}
		}catch (SQLException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return true;
	}
	public boolean deleteOne(int id){

		try{
			this.getConnection();
			ps=db.prepareStatement("DELETE FROM products WHERE id=?");
			ps.setInt(1, id);
			int result=ps.executeUpdate();
			if(result != 1){
				return false;
			}
		}catch (SQLException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return true;
	}

}

10.viewの作成。以下の図のようなフォルダ構成としmain.jspを作成する。

●main.jsp

&amp;amp;amp;lt;%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="model.*,java.util.*"%&amp;amp;amp;gt;
&amp;amp;amp;lt;%
List&amp;amp;amp;lt;Product&amp;amp;amp;gt; list=(List&amp;amp;amp;lt;Product&amp;amp;amp;gt;)request.getAttribute("list");
Product product=(Product)request.getAttribute("product");
String id=product==null ? "":String.valueOf(product.getId());
String name=product == null ? "":product.getName();
String price=product == null ? "":String.valueOf(product.getPrice());
String title=(String)request.getAttribute("title");
title=title==null? "商品を登録してください。":title;
String err=(String)request.getAttribute("err");
String msg=(String)request.getAttribute("msg");
%&amp;amp;amp;gt;
&amp;amp;amp;lt;!DOCTYPE html&amp;amp;amp;gt;
&amp;amp;amp;lt;html&amp;amp;amp;gt;
&amp;amp;amp;lt;head&amp;amp;amp;gt;
&amp;amp;amp;lt;meta charset="UTF-8"/&amp;amp;amp;gt;
&amp;amp;amp;lt;meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"&amp;amp;amp;gt;
&amp;amp;amp;lt;!-- Bootstrap CSS --&amp;amp;amp;gt;
&amp;amp;amp;lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"&amp;amp;amp;gt;
&amp;amp;amp;lt;title&amp;amp;amp;gt;Joytas8&amp;amp;amp;lt;/title&amp;amp;amp;gt;
&amp;amp;amp;lt;/head&amp;amp;amp;gt;
&amp;amp;amp;lt;body&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="container" style="margin-top:20px;"&amp;amp;amp;gt;
&amp;amp;amp;lt;% if(err !=null){%&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="alert alert-danger" role="alert"&amp;amp;amp;gt;
&amp;amp;amp;lt;%=err %&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;%} %&amp;amp;amp;gt;
&amp;amp;amp;lt;% if(msg !=null){%&amp;amp;amp;gt;
&amp;amp;amp;lt;div class="alert alert-success" role="alert"&amp;amp;amp;gt;
&amp;amp;amp;lt;%=msg %&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;%} %&amp;amp;amp;gt;
&amp;amp;amp;lt;p&amp;amp;amp;gt;&amp;amp;amp;lt;%=title %&amp;amp;amp;gt;&amp;amp;amp;lt;/p&amp;amp;amp;gt;

&amp;amp;amp;lt;form action="/joytas8/main" method="post" &amp;amp;amp;gt;
  &amp;amp;amp;lt;div class="form-group"&amp;amp;amp;gt;
    &amp;amp;amp;lt;label for="name"&amp;amp;amp;gt;製品名:&amp;amp;amp;lt;/label&amp;amp;amp;gt;
    &amp;amp;amp;lt;input type="text" id="name" name="name" class="form-control" style="width:200px;" value="&amp;amp;amp;lt;%=name%&amp;amp;amp;gt;"&amp;amp;amp;gt;
  &amp;amp;amp;lt;/div&amp;amp;amp;gt;
  &amp;amp;amp;lt;div class="form-group"&amp;amp;amp;gt;
    &amp;amp;amp;lt;label for="price"&amp;amp;amp;gt;価格:&amp;amp;amp;lt;/label&amp;amp;amp;gt;
    &amp;amp;amp;lt;input type="number" id="price" name="price" class="form-control" style="width:200px;" value="&amp;amp;amp;lt;%=price%&amp;amp;amp;gt;"&amp;amp;amp;gt;
  &amp;amp;amp;lt;/div&amp;amp;amp;gt;
  &amp;amp;amp;lt;%if(!id.isEmpty()) {%&amp;amp;amp;gt;
  &amp;amp;amp;lt;input type="hidden" name="id" value="&amp;amp;amp;lt;%=id %&amp;amp;amp;gt;"&amp;amp;amp;gt;
  &amp;amp;amp;lt;%} %&amp;amp;amp;gt;
  &amp;amp;amp;lt;button type="submit" class="btn btn-primary"&amp;amp;amp;gt;&amp;amp;amp;lt;%=id.isEmpty()?"登録":"更新" %&amp;amp;amp;gt;&amp;amp;amp;lt;/button&amp;amp;amp;gt;
&amp;amp;amp;lt;/form&amp;amp;amp;gt;

&amp;amp;amp;lt;%if(list != null &amp;amp;amp;amp;&amp;amp;amp;amp; list.size()&amp;amp;amp;gt;0){%&amp;amp;amp;gt;
&amp;amp;amp;lt;table class="table table-striped mt-4"&amp;amp;amp;gt;
&amp;amp;amp;lt;tr&amp;amp;amp;gt;&amp;amp;amp;lt;th&amp;amp;amp;gt;製品名&amp;amp;amp;lt;/th&amp;amp;amp;gt;&amp;amp;amp;lt;th&amp;amp;amp;gt;価格&amp;amp;amp;lt;/th&amp;amp;amp;gt;&amp;amp;amp;lt;th&amp;amp;amp;gt;更新日&amp;amp;amp;lt;/th&amp;amp;amp;gt;&amp;amp;amp;lt;th&amp;amp;amp;gt;&amp;amp;amp;lt;/th&amp;amp;amp;gt;&amp;amp;amp;lt;/tr&amp;amp;amp;gt;
&amp;amp;amp;lt;%for(Product p:list) {%&amp;amp;amp;gt;
&amp;amp;amp;lt;tr&amp;amp;amp;gt;&amp;amp;amp;lt;th&amp;amp;amp;gt;&amp;amp;amp;lt;%=p.getName() %&amp;amp;amp;gt;&amp;amp;amp;lt;/th&amp;amp;amp;gt;&amp;amp;amp;lt;td&amp;amp;amp;gt;&amp;amp;amp;lt;%=String.format("%,3d円",p.getPrice()) %&amp;amp;amp;gt;&amp;amp;amp;lt;/td&amp;amp;amp;gt;&amp;amp;amp;lt;td&amp;amp;amp;gt;&amp;amp;amp;lt;%=p.getUpdated() %&amp;amp;amp;gt;&amp;amp;amp;lt;/td&amp;amp;amp;gt;
&amp;amp;amp;lt;td&amp;amp;amp;gt;
&amp;amp;amp;lt;a href="/joytas8/main?action=update&amp;amp;amp;amp;id=&amp;amp;amp;lt;%=String.valueOf(p.getId()) %&amp;amp;amp;gt;" class="btn btn-primary"&amp;amp;amp;gt;更新&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;a href="/joytas8/main?action=delete&amp;amp;amp;amp;id=&amp;amp;amp;lt;%=String.valueOf(p.getId()) %&amp;amp;amp;gt;" class="btn btn-danger" onclick="return confirm('削除してよろしいですか?');"&amp;amp;amp;gt;削除&amp;amp;amp;lt;/a&amp;amp;amp;gt;
&amp;amp;amp;lt;/td&amp;amp;amp;gt;
&amp;amp;amp;lt;/tr&amp;amp;amp;gt;
&amp;amp;amp;lt;%} %&amp;amp;amp;gt;
&amp;amp;amp;lt;/table&amp;amp;amp;gt;
&amp;amp;amp;lt;%} %&amp;amp;amp;gt;
&amp;amp;amp;lt;/div&amp;amp;amp;gt;
&amp;amp;amp;lt;script&amp;amp;amp;gt;
var forms=document.getElementsByClassName("form-control");
var alerts=document.getElementsByClassName("alert");
for(var i=0;i&amp;amp;amp;lt;forms.length;i++){
	forms[i].addEventListener("focus",function(){
		for(var j=0;j&amp;amp;amp;lt;alerts.length;j++){
			alerts[j].style.display="none";
		}
	});
}
&amp;amp;amp;lt;/script&amp;amp;amp;gt;
&amp;amp;amp;lt;/body&amp;amp;amp;gt;
&amp;amp;amp;lt;/html&amp;amp;amp;gt;

11.controllerの作成。以下のようなフォルダ構成とし、Main.java(Servlet)を作成する。

●controller.Main.java

package controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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 dao.ProductDAO;
import model.Product;

@WebServlet("/main")
public class Main extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ProductDAO dao=new ProductDAO();
		String action=request.getParameter("action");
		if(action != null &amp;amp;amp;amp;&amp;amp;amp;amp; action.equals("delete")){
			dao.deleteOne(Integer.parseInt(request.getParameter("id")));
			request.setAttribute("msg", "1件削除しました。");
		}else if(action != null &amp;amp;amp;amp;&amp;amp;amp;amp; action.equals("update")){
			Product product=dao.findOne(Integer.parseInt(request.getParameter("id")));
			request.setAttribute("product", product);
			request.setAttribute("title", "項目を編集してください。");
		}
		List&amp;amp;amp;lt;Product&amp;amp;amp;gt; list=dao.findAll();
		request.setAttribute("list", list);
		RequestDispatcher rd= request.getRequestDispatcher("/WEB-INF/view/main.jsp");
		rd.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String name=request.getParameter("name");
		String price=request.getParameter("price");
		if(name.isEmpty() || price.isEmpty()){
			request.setAttribute("err","未記入の項目があります!");
		}else{
			Date date=new Date();
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String updated=sdf.format(date);
			ProductDAO dao=new ProductDAO();
			String id=request.getParameter("id");
			if(id != null){
				dao.updateOne(new Product(Integer.parseInt(id),name,Integer.parseInt(price),updated));
				request.setAttribute("msg","1件更新しました。");
			}else{
				dao.insertOne(new Product(name,Integer.parseInt(price),updated));
				request.setAttribute("msg","1件登録しました。");
			}
		}
		doGet(request,response);
	}
}

12.サーバーで実行後以下のアドレスにリクエストして、実行例のようになることを確認する。
http://localhost:8080/joytas8/main

コメント

タイトルとURLをコピーしました