いよいよ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をダウンロードする。
遷移したら「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" 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" username="ユーザーネーム" password="パスワード" 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> var forms=document.getElementsByClassName("form-control"); var alerts=document.getElementsByClassName("alert"); for(var i=0;i<forms.length;i++){ forms[i].addEventListener("focus",function(){ for(var 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.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 && 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
コメント