いよいよ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="autoReconnect=true;verifyServerCertificate=false;useSSL=false;requireSSL=false;useUnicode=true;characterEncoding=UTF-8;"
username="root"
validationQuery="select 1"/>
</Context>
上はrootユーザー、パスワードなしが前提だが、ユーザー、パスワードを設定している場合は以下
<?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="autoReconnect=true;verifyServerCertificate=false;useSSL=false;requireSSL=false;useUnicode=true;characterEncoding=UTF-8;"
username="root"
password="root"
validationQuery="select 1"/>
</Context>
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<Product> findAll(){
List<Product> productList=new ArrayList<>();
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
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="model.*,java.util.*"%>
<%
List<Product> list=(List<Product>)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");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<title>Joytas8</title>
</head>
<body>
<div class="container" style="margin-top:20px;">
<% if(err !=null){%>
<div class="alert alert-danger" role="alert">
<%=err %>
</div>
<%} %>
<% if(msg !=null){%>
<div class="alert alert-success" role="alert">
<%=msg %>
</div>
<%} %>
<p><%=title %></p>
<form action="/joytas8/main" method="post" >
<div class="form-group">
<label for="name">製品名:</label>
<input type="text" id="name" name="name" class="form-control" style="width:200px;" value="<%=name%>">
</div>
<div class="form-group">
<label for="price">価格:</label>
<input type="number" id="price" name="price" class="form-control" style="width:200px;" value="<%=price%>">
</div>
<%if(!id.isEmpty()) {%>
<input type="hidden" name="id" value="<%=id %>">
<%} %>
<button type="submit" class="btn btn-primary"><%=id.isEmpty()?"登録":"更新" %></button>
</form>
<%if(list != null && list.size()>0){%>
<table class="table table-striped mt-4">
<tr><th>製品名</th><th>価格</th><th>更新日</th><th></th></tr>
<%for(Product p:list) {%>
<tr><th><%=p.getName() %></th><td><%=String.format("%,3d円",p.getPrice()) %></td><td><%=p.getUpdated() %></td>
<td>
<a href="/joytas8/main?action=update&id=<%=String.valueOf(p.getId()) %>" class="btn btn-primary">更新</a>
<a href="/joytas8/main?action=delete&id=<%=String.valueOf(p.getId()) %>" class="btn btn-danger" onclick="return confirm('削除してよろしいですか?');">削除</a>
</td>
</tr>
<%} %>
</table>
<%} %>
</div>
<script>
const forms=document.getElementsByClassName("form-control");
const alerts=document.getElementsByClassName("alert");
for(let i=0;i<forms.length;i++){
forms[i].addEventListener("focus",()=>{
for(let j=0;j<alerts.length;j++){
alerts[j].style.display="none";
}
});
}
</script>
</body>
</html>
11.controllerの作成。以下のようなフォルダ構成とし、Main.java(Servlet)を作成する。
●controller.Main.java
package controller;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
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 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 && action.equals("delete")){
dao.deleteOne(Integer.parseInt(request.getParameter("id")));
request.setAttribute("msg", "1件削除しました。");
}else if(action != null && action.equals("update")){
Product product=dao.findOne(Integer.parseInt(request.getParameter("id")));
request.setAttribute("product", product);
request.setAttribute("title", "項目を編集してください。");
}
List<Product> 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
コメント