Comments
Description
Transcript
ウエブアプリケーション 第11回 JSP その3
http://www0.info.kanagawa-u.ac.jp/~kaiya/wa/ dotcampus ショートコード 178926 ウエブアプリケーション 第11回 JSP その3 2016/11/24 海谷 治彦 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は略) • 最初に配布した tomcat01/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型 のオブジェクトを用いて実行する. • 以下,典型的な例. • 最初に配布した tomcat01/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を通してデータベース自体に関する各種の情報を以下 のように取得できる. • 最初に配布した tomcat01/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 演習11: 注意事項 • 次頁で指定するJSPのプログラムを作成してください. • 提供したファイル群(in wa11poem.zip)を改造して作成してください. • 今回は12/10までにやってみてください. • 締切後も提出可能な状態にはなっていますが,遅提出の扱いと なります. • 提出しないよりはマシです. • 提出先は dotcampusです. • ファイルの名は変更せず,全てのjspファイルをzipでまとめて, poem.zip として提出してください. • かならず,自分以外(友人等)のブラウザからアクセス確認を行っ てください. • 今回も JavaScriptは使わないでください. 31 演習11: 問題 • 以下の状態遷移図にそったページ遷移を行うjspページ群を提供したテンプ レートを修正することで完成せよ. • 各状態がページに対応している. • 以下の遷移以外の方法でJSPページに到達できないようにすること.(login.jsp 以外) • login.jspで入力した name と email の値が,他の全てのページで表示されるこ と.(提供したファイル群ではダミーが表示されるようになっている.) • logout.jsp で session は破棄されること. • http://サーバーのアドレス/tomcat/poem/login.jsp からアクセスできるのが望ま しい. poem1 login menu poem2 logout 左記は,詩の閲覧サービス で3つの詩が閲覧できます. 別に詩の中身を自分のヤ ツにかきかえてもよいです よ. poem3 32 以上 33