1.新規動的プロジェクトからstockappを作成する。
2.以下から株価csvファイルをダウンロードする。


3.新規フォルダからassetsフォルダを配置し、その中にさきほどダウンロードしたcsvファイルを配置する。
4.MySQLのコネクターをWEB-INF/libフォルダ内に配置

5.MySQLで新規データベースでstockappを作成する。

CREATE DATABASE stockapp
DEFAULT CHARACTER SET utf8;

6.stockapp内にstocksテーブルを作成する。

CREATE TABLE stocks(
code varchar(10),
name varchar(255),
place varchar(100),
open varchar(30),
high varchar(30),
low varchar(30),
end varchar(30),
amount varchar(30),
sales varchar(30)
 );

7.Javaでデータベースに接続しファイルを読み込みながらインサートする。
新規クラスからutilパッケージにInsertDB.javaを以下のように作成する。
util.InsertDB.java

package util;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class InsertDB {
	public static void main(String[] args){
		try {
			FileInputStream fis = new FileInputStream("assets/stocks_2017-08-16.csv");
			InputStreamReader isr=new InputStreamReader(fis,"UTF-8");
			BufferedReader br=new BufferedReader(isr);
			//DB接続
			Class.forName("com.mysql.jdbc.Driver");
			String url="jdbc:mysql://localhost:3306/stockapp?useUnicode=true&characterEncoding=utf8";
			String user="root";
			String pass="root";
			Connection db=DriverManager.getConnection(url,user,pass);
			db.setAutoCommit(false);
			PreparedStatement ps=db.prepareStatement("INSERT INTO stocks VALUES(?,?,?,?,?,?,?,?,?)");
			String line;
			while((line=br.readLine()) !=null){
				if(line.startsWith("コード")){
					continue;
				}
				String[] vals=line.split(",",-1);
				ps.setString(1, vals[0]);
				ps.setString(2, vals[1]);
				ps.setString(3, vals[2]);
				ps.setString(4, vals[3]);
				ps.setString(5, vals[4]);
				ps.setString(6, vals[5]);
				ps.setString(7, vals[6]);
				ps.setString(8, vals[7]);
				ps.setString(9, vals[8]);
				ps.executeUpdate();
			}
			db.commit();
			db.close();
			br.close();
			System.out.println("done!");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

8.Javaアプリケーションで実行しよう。以下のようにDBにデータが挿入されれば成功だ。

9.DBにデータが入ったのでこのあとはWebアプリとして仕上げる。最初にMETA−INFフォルダ内context.xmlを以下のように作成して配置する。

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

10.modelパッケージ内にStock.javaを作成する。
model.Stock.java

package model;

import java.io.Serializable;

public class Stock implements Serializable{
	private String code,name,place,open,high,low,end,amount,sales;
	public Stock(){}
	public Stock(String code, String name, String place, String open, String high, String low, String end,
			String amount, String sales) {
		this.code = code;
		this.name = name;
		this.place = place;
		this.open = open;
		this.high = high;
		this.low = low;
		this.end = end;
		this.amount = amount;
		this.sales = sales;
	}
	public String getCode() {
		return code;
	}
	public String getName() {
		return name;
	}
	public String getPlace() {
		return place;
	}
	public String getOpen() {
		return open;
	}
	public String getHigh() {
		return high;
	}
	public String getLow() {
		return low;
	}
	public String getEnd() {
		return end;
	}
	public String getAmount() {
		return amount;
	}
	public String getSales() {
		return sales;
	}	
}

10.続いてmodelパッケージ内にStockDAOを以下のように作成
model.StockDAO.java

package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

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

public class StockDAO {
	private Connection db;
	private PreparedStatement ps;
	private ResultSet rs;
	
	private void connect() throws NamingException, SQLException{
		Context context=new InitialContext();
		DataSource ds=(DataSource)context.lookup("java:comp/env/stockapp");
		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<Stock> getList(int limit,int offset){
		List<Stock> list=new ArrayList<>();
		try {
			this.connect();
			ps=db.prepareStatement("SELECT * FROM stock LIMIT ? OFFSET ?");
			ps.setInt(1, limit);
			ps.setInt(2, offset);
			rs=ps.executeQuery();
			while(rs.next()){
				Stock stock=new Stock(
						rs.getString("code"),
						rs.getString("name"),
						rs.getString("place"),
						rs.getString("open"),
						rs.getString("high"),
						rs.getString("low"),
						rs.getString("end"),
						rs.getString("amount"),
						rs.getString("sales")
						);
				list.add(stock);
			}
		} catch (NamingException | SQLException e) {
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return list;
	}
	public List<Stock> getList(String code,int limit,int offset){
		List<Stock> list=new ArrayList<>();
		try {
			this.connect();
			ps=db.prepareStatement("SELECT * FROM stock WHERE code LIKE ? LIMIT ? OFFSET ?");
			ps.setString(1, code+"%");
			ps.setInt(2, limit);
			ps.setInt(3, offset);
			rs=ps.executeQuery();
			while(rs.next()){
				Stock stock=new Stock(
						rs.getString("code"),
						rs.getString("name"),
						rs.getString("place"),
						rs.getString("open"),
						rs.getString("high"),
						rs.getString("low"),
						rs.getString("end"),
						rs.getString("amount"),
						rs.getString("sales")
						);
				list.add(stock);
			}
		} catch (NamingException | SQLException e) {
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return list;
	}
	public int getCount(){
		int total=0;
		try {
			this.connect();
			ps=db.prepareStatement("SELECT count(*) AS total FROM stocks");
			rs=ps.executeQuery();
			if(rs.next()){
				total=rs.getInt("total");
			}
		} catch (NamingException | SQLException e) {
			
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return total;
	}
	public int getCount(String code){
		int total=0;
		try {
			this.connect();
			ps=db.prepareStatement("SELECT count(*) AS total FROM stocks WHERE code LIKE ?");
			ps.setString(1, code+"%");
			rs=ps.executeQuery();
			if(rs.next()){
				total=rs.getInt("total");
			}
		} catch (NamingException | SQLException e) {
			
			e.printStackTrace();
		}finally{
			this.disconnect();
		}
		return total;
	}	
}

11.controllerパッケージ内にIndex.javaを作成する。
controller.Index.java

package controller;

import java.io.IOException;
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 model.Stock;
import model.StockDAO;


@WebServlet("/index.html")
public class Index extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final int LIMIT=20;
       
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String page=request.getParameter("page");
		int pageNo=page==null ? 1:Integer.parseInt(page);
		String code=request.getParameter("code");
		StockDAO dao=new StockDAO();
		List<Stock> list=null;
		int total;
		if(code==null){
			total=dao.getCount();
			list=dao.getList(LIMIT, (pageNo-1)*LIMIT);
		}else{
			total=dao.getCount(code);
			list=dao.getList(code, LIMIT,(pageNo-1)*LIMIT);
			request.setAttribute("code", code);
		}
		request.setAttribute("total", total);
		request.setAttribute("page", pageNo);
		request.setAttribute("limit", LIMIT);
		request.setAttribute("list", list);
		RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/view/index.jsp");
		rd.forward(request, response);
	}
}

12.WEB-INFの中にviewフォルダを作成しその中にindex.jspを作成する。
/WEB-INF/view/index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*,model.*"%>
<%
Integer total=(Integer)request.getAttribute("total");
Integer pageNo=(Integer)request.getAttribute("page");
Integer limit=(Integer)request.getAttribute("limit");
List<Stock> list =(List<Stock>)request.getAttribute("list");
String code=(String)request.getAttribute("code");
code=code==null? "":code;
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>株価App</title>
</head>
<body>
<form action="/stockapp/" method="get">
コード:<input type="text" name="code" value="<%=code %>">
<button type="submit">検索</button>
</form>
<%if(!code.isEmpty()){ %>
<a href="/stockapp/">一覧</a>
<%} %>
<%if(list != null && list.size() >0){ %>
<p>全<%=total %>件中<%=(pageNo-1)*limit+1 %>~<%=Math.min(total,pageNo*limit) %>件表示</p>
<p>
<%if(pageNo>1){ %>
<a href="/stockapp/index.html?page=<%=pageNo-1+(code.isEmpty()?"":"&code="+code) %>">&larr;前へ</a>
<%} %>
<%if(pageNo*limit<total){ %>
<a href="/stockapp/index.html?page=<%=pageNo+1+(code.isEmpty()?"":"&code="+code) %>">次へ&rarr;</a>
<%} %>
</p>
<table border="1">
<tr>
<th>コード</th>
<th>銘柄名</th>
<th>市場</th>
<th>始値</th>
<th>高値</th>
<th>安値</th>
<th>終値</th>
<th>出来高</th>
<th>売買代金</th>
</tr>
<%for(Stock s:list){ %>
<tr>
<td><%=s.getCode() %></td>
<td><%=s.getName() %></td>
<td><%=s.getPlace() %></td>
<td><%=s.getOpen() %></td>
<td><%=s.getHigh() %></td>
<td><%=s.getLow() %></td>
<td><%=s.getEnd() %></td>
<td><%=s.getAmount() %></td>
<td><%=s.getSales() %></td>

</tr>
<%} %>
</table>
<%} %>
</body>
</html>