ウエブアプリケーション 2015 第11回 JSP その3

http://www0.info.kanagawa-u.ac.jp/~kaiya/wa/
dotcampus ショートコード 179067
ウエブアプリケーション 2015
第11回 JSP その3
2014/13/3
海谷 治彦
1
目次
• ウエブサーバーとDBが連携する必要性
• SQLの復習 (データベースの授業の復習)
• mysql の使い方
• ウエブアプリで扱うデータの初期設定に,直接,mysql
へアクセスすることも多い.
• mysql と tomcat6の接続
• JSPからのsqlの利用
• というか,Javaからのsql操作
• 今回の演習
2
DBとの連携の必要性
• ウエブブラウザ側では多量なデータは保持できない.
• 多くのアプリでは永続的にデータを保持する必要があ
る.
• googleの保持する多量の検索元データ
• 買物サイトの保持する商品や取引の情報
• dotcampusが保持するレポートや授業コンテンツの情報
• 一昔前は,OSのファイルシステムに,ウエブサーバー
が直接にアクセスしデータを利用していた.
• 今はパフォーマンス,セキュリティ,ポータビリティ等の
観点から,データベース管理システム(DBMS)とウエブ
サーバーが連携をとるのが普通になった.
3
復習
ウエブアプリが便利な例 2/2
他マシンの
あるデータ内
を検索したい
巨大な
データ
検索も他マシン
に任せましょう!
検索依頼
検索結果のみ
受信
検索処理
巨大な
データ
4
SQL自体について
• データベースの種類は沢山あるが,現在では,RDB (Relational
Data Base)が主流である.
• SQLはRDBを操作するための言語である.
• RDBを管理するためのソフトウェアである DBMS (Data Base
Management System) も何種類かの実装があるが,本講義では
mysql を使う.
• 講義資料でも若干の混乱があるが,
• DB (Data base) 実際のコンテンツを含むデータ
• DBMS DBを管理するためのソフト
という用語分けをする.
表(Table)
の例
• 通常,一つのDBMSは複数のDBを管理する.
• RDBでは,一つのDBに複数の表(Table)が含まれ,この表が,
具体的な操作対象となる.
5
mysqlの利用法とSQL構文
• ウエブアプリ運用の準備のため,DBMSを直接操
作する必要が出てくる,例えば,
• データベースを事前に作っておく.
• 手動で不要なデータ削除等を行う.
• バックアップをとる,等
• ここでは,mysqlコマンドを用いて,このような準備
を行うための解説を行う.
• 加えて,SQLの典型的な構文についても復習する.
6
基本的な二つのツール
• 双方,コマンドラインのツールである.
• GUIのツールもあるかもしれないが,本講義では
扱わない.
• 基本,OSの管理者ユーザーで実行してよい.
• mysqladmin
• mysql server (DBMS)を管理するためのソフト.
• 本講義ではmysqlにおける管理者(root)のパスワード設
定くらいにしか使わない.
• mysql
• mysql server を操作するためのツール.
• mysql固有の命令もあるが,基本,一般的なSQL命令
を受け付ける.
7
mysql内でのユーザー管理
• mysqlでは,動作するOSのユーザー管理とは関係
なく,独自のユーザー管理が行われている.
• 通常のOS同様,管理者(root)で何でもできるが,
実運用はrootで行うのは好ましくない.
• 各アプリケーション用のユーザーを作成し,ユー
ザー毎に,必要最低限の権限を与えるのがよい.
• ユーザー毎に使えるデータベースを準備するのが,一
番,シンプルでしょう.
• mysqlでの管理者 = root (UNIX系OSと同じ名前)
• 一般ユーザー 16文字以下の英数文字
8
新規ユーザーの登録と確認
• rootのパスワードはpasuwadoになっているとする.
• 以下の例ではsaekiさんでパスワードはjindai
• 青字の部分は解説.
• 下記ではsaekiに特段権限が与えられてないので,新しいDBもtableも
作れない.
• ただし,testというDBに対しては操作ができる.
root@Linuxから接続する 別に一般@Linuxからでもよい
# mysql -uroot -ppasuwado
mysqlのプロンプトになる
mysql> CREATE USER 'saeki'@'localhost'; コレでユーザーsaekiができる
以下でsaekiのパスワードを設定,PASSWORD()は暗号化関数.
mysql> SET PASSWORD FOR 'saeki'@'localhost' = PASSWORD('jindai');
mysql> select user,host from mysql.user; コレで既登録ユーザーを列挙できる
mysql> exit とりあえずmysqlから抜ける
9
rootでデータベースを用意
• 一般ユーザーに全権限を与えるのはヤなので,とりあえず,
とあるデータベース限定の権限を与える.
• そのため,rootで権限を与えるためのDBを作っておく.
• ついでに,既存のDBを閲覧.
root@Linuxから接続する 別に一般@Linuxからでもよい
# mysql -uroot -ppasuwado
mysql> show databases;
データベースを表示 デフォで information_schema mysql test の3つがある.
mysql> show tables from mysql;
データベースに含まれるテーブルが列挙される 上記はmysql中のもの
mysql> create database test2;
とりあえずtest2というDBを作った.
mysql>exit; とりあえあず抜ける
10
DBアクセス許可を一般ユーザーに
• さきほど作ったDB test2 に対して saeki がアクセス
できるように,設定を行います.
• これも mysqlのrootで行う.
root@Linuxから接続する 別に一般@Linuxからでもよい
# mysql -uroot -ppasuwado
mysql> grant all privileges on test2.* to 'saeki'@'localhost' identified by 'jindai';
データベース test2に対するフルアクセスをsaekiに許可した.
mysql> exit; とりあえず抜ける
saekiでmysqlに入り直す
# mysql -usaeki -pjindai
mysql> use test2; 使うDBをtest2に設定
mysql> create table twonum (a integer, b integer);
適当なテーブル twonum を作成できることを確認した.
mysql> exit; とりあえず抜ける
これで,
ユーザー saeki が,
データベース test2 を
操作できるように
お膳立てできた.
11
SQLの主な命令
• CREATE TABLE
• SELECT
• INSERT
• UPDATE
• DELETE
• SHOW DATABASES, SHOW TABLES, DROP
• その他,色々ありますが,データベースの授業を
思い出してください.
12
mysqlで使える主なデータ型
• INT, FLOAT, DOUBLE 整数 実数
• CHAR(数値) 固定長文字列,数値は文字数,0~
255
• VARCHAR(数値) 可変長文字列,数値は最近は
文字数,216 バイトまで.
• TEXT 216 -1 の可変長文字列
• 他はデータベースの授業を思い出して.
13
CREATE TABLE
• データを保持するためのテーブルを作成.
• 下記の例のように 表中のフィールド名と型を列挙
してテーブルを定義.
• 構造体っぽいよね.
saekiでmysqlに入り直す
# mysql -usaeki -pjindai
mysql> use test2; 使うDBをtest2に設定
mysql> create table NameScore (name text, score int);
mysql> exit; とりあえず抜ける
14
INSERT
• あるテーブルにデータを追加する操作.
• 下記の例通り.
• コレはおそらくJavaから操作することのほうが多い
ので,直接,mysqlツールで実行することは少ない
だろう.
saekiでmysqlに入り直す
# mysql -usaeki -pjindai
mysql> use test2; 使うDBをtest2に設定
mysql> insert into NameScore values('ohnishi', 90);
mysql> exit; とりあえず抜ける
15
UPDATE
• あるテーブルにデータを更新する操作.
• 下記の例通り.
• コレもおそらくJavaから操作することのほうが多い
ので,直接,mysqlツールで実行することは少ない
だろう.
saekiでmysqlに入り直す
# mysql -usaeki -pjindai
mysql> use test2; 使うDBをtest2に設定
下記では,name が kato さんの score を,75に更新している.
mysql> update NameScore set score = 75 where name = 'kato';
mysql> exit; とりあえず抜ける
16
DELETE
• あるテーブルにデータを削除する操作.
• 下記の例通り.
• コレもおそらくJavaから操作することのほうが多い
ので,直接,mysqlツールで実行することは少ない
だろう.
saekiでmysqlに入り直す
# mysql -usaeki -pjindai
mysql> use test2; 使うDBをtest2に設定
下記では,name が kato さんのデータを削除している.
mysql> delete from NameScore where name = 'kato';
mysql> exit; とりあえず抜ける
17
SELECT
• あるテーブルにデータを列挙する命令.
• 下記の例通り.
• コレもおそらくJavaから操作することのほうが多い
が,mysqlツールで確認する機会は多いかも.
saekiでmysqlに入り直す
# mysql -usaeki -pjindai
mysql> use test2; 使うDBをtest2に設定
mysql> select * from NameScore;
mysql> exit; とりあえず抜ける
18
SHOW, DROP
• show databases アクセス可能なデータベースを列挙.
• show tables あるDBにあるテーブルを列挙する.
• drop テーブルを削除する.
19
tomcat6とmysqlの連携
• 次頁の(毎度の)図にあるように,tomcat6とmysqlも
プロセス間通信を行っている.
• tomcat側は3306番ポートで外部プログラムと通信
を行う.
• tomcat6側は JDBC という接続用クラスを介して,
mysqlと通信を行う.
• JDBCの設定を変えれば,ウエブアプリの方の変更無し
で,DBMSは他のもの(例えば postgresSQL等)に置き
換え可能.
20
復習++
セットアップしてほしい構成
Lenovo : クライアント
3306ポートで,
外部からの接続を
待っている.
Firefox等 : ウエブブラウザ
HTTP
CentOS 6.5 : サーバー
JDBCに関するク
ラスが間に入り,
通信を一般化.
JSP(Java)側から
は,DBMSの種類
によらないAPIを
用いてDBMSに接
続が可能.
apache 2.2 : ウエブサーバー
MySQL 5.1 : データベース
PHP 5.3 : モジュール
Tomcat6 : アプリケーションサーバー
JVM : モジュール
21
mysql接続設定
• アプリケーション毎に設定する.
• この授業の場合,/var/lib/tomcat6/webapps/の下のそれ
ぞれのフォルダが個別のアプリとなっている.
• 設定ファイルは,アプリの下の
• META-INF/context.xml
というファイルに設定を書く.内容は後述.
• 通信のためのJDBCクラス群は,この授業の場合,
• /usr/share/java/tomcat6/mysql-connector-java.jar
においた.
22
content.xml (青字は解説)
<Context>
<Resource
name = "jdbc/test1" test1 は使うデータベースの名前にする
auth = "Container" データベースアクセスではこのまま
type = "javax.sql.DataSource" 同上
maxActive = "100" 事前に用意する接続箇所数
maxIdle
= "30" 待機時に最低維持する接続数
maxWait = "100000" 接続に対する最大待ち時間 (ミリ秒)
username = "kaiya" 接続のためのユーザー名
password = "nanikakotoba" 上記パスワード
driverClassName = "com.mysql.jdbc.Driver" 接続使うクラス
url = "jdbc:mysql://127.0.0.1:3306/test1" 接続するデータベース
/>
操作対象の
</Context> DBMSが動くマシンが他なら,このアドレスを
変える.上記は同じマシンで動作する設定
DBの名前
23
JSP(Java)からのSQLの利用
• java.sql, javax.sql, javax.naming パッケージに含ま
れるクラス群を利用する.
• 接続と切断
• 情報の照会 (query)
• 情報の更新
• メタデータの取得 (参考)
24
接続と切断
• 基本,以下の様式.ただし,test1 は扱うデータベース
の名前.
• mysqlに接続するためのユーザー名等は前述のように
ファイル context.xml に書いておく.
<%@ page import="javax.sql.*,javax.naming.*,java.sql.*" %>
Context context = new InitialContext(); // javax.context.Naming
// javax.sql.DataSource
DataSource ds=(DataSource)context.lookup("java:comp/env/jdbc/test1");
// java.sql.Connection
Connection db= ds.getConnection();
// この辺でdbに対して処理を行う,具体例は後述
db.close();
25
結果が返るSQL実行 (select)
• java.sql.Statement型のクラスをつかい照会を行う.
• 結果は,java.sql.ResultSet 型として受け取れる.
• Iteratorっぽい振る舞いをする型.
• 以下,典型的なコードの例.(importは略)
• 最初に配布した kaiyaj/db2.jsp 中.
// dbは DataSource.getConnection() で取得したもの
Statement stmt = db.createStatement();
ResultSet rs = stmt.executeQuery("select * from nameage");
while(rs.next()){
out.println(rs.getString("name")); // nameはフィールド名
out.println(rs.getString("age")); // ageもフィールド名
}
26
結果の無いSQL実行
• insert, update, delete等は実行の成否は返るが,
データを取得するものでは無い.
• そのようなSQL命令は java.sql.PrepareStatement型
のオブジェクトを用いて実行する.
• 以下,典型的な例.
• 最初に配布した kaiyaj/db2.jsp 中の一部
// dbは DataSource.getConnection() で取得したもの
String insert="insert into nameage values(?,?)";
PreparedStatement ps=db.prepareStatement(insert);
ps.setString(1,"Eric");
ps.setInt(2,55);
int result=ps.executeUpdate();
27
プレースホルダについて
• PreparedStatementを作成する際に使うSQL命令中
の ? はプレースホルダと呼ばれる.
• お察しの通り,後から setString()等のを使って ? の
部分に実際の値を設定できる.
• ノリは printf文の % に近い感じ.
// dbは DataSource.getConnection() で取得したもの
String insert="insert into nameage values(?,?)";
PreparedStatement ps=db.prepareStatement(insert);
ps.setString(1,"Eric");
ps.setInt(2,55);
int result=ps.executeUpdate();
28
メタデータ (参考)
• Javaを通してデータベース自体に関する各種の情報を以下
のように取得できる.
• 最初に配布した kaiyaj/db1.jsp の中
• java.sql.DatabaseMetaData型で情報を取得できる.取得で
きるデータはこのインタフェースのマニュアルを参照.
// dbは DataSource.getConnection() で取得したもの
DatabaseMetaData metadata = db.getMetaData();
out.println("DatabaseProductName: " + metadata.getDatabaseProductName());
out.println("DatabaseProductVersion: " + metadata.getDatabaseProductVersion());
out.println("DriverName: " + metadata.getDriverName());
out.println("DriverVersion: " + metadata.getDriverVersion());
out.println("URL: " + metadata.getURL());
out.println("UserName: " + metadata.getUserName());
29
例外処理
• 前述の例題について,例外処理は書かなかった.
• 実際には,APIのマニュアルを見て,例外処理を
対処するのが望ましい.
• 例えば,
• DataSource.getConnection() メソッドは SQLExceptionと
いう例外を投げる.
• prepareStatement, executeUpdate 等も同様.
• 実践的なJavaプログラミングにおいては,必ず,
APIマニュアルを参照しながら行ってほしい.
30
本日の演習
• dotcampusに出してください.
• 問題もdotcampusのほうを参照.
• 今回も締切は来週とします.
• そろそろインストも落ち着いてきたと思いますが,問題
の規模も微妙に大きくなってきたので.
• 本日は以上
31