Database/JDBC/Tomcat/Eclipse (Debian11.4.0)
2022/7/30
RDBMS
JavaBeansからデータベースに接続して、電話番号と部屋名が検索できる電話番号簿をつくる。
RDBMS(Relational DataBase Management System)には選択肢があるが、PostgreSQL13.7を使う。
準備
JavaBeansとデータベースはJDBC接続する。JDBCドライバがTomcat(catalina)にインストールされていることを確認する。
postgresql.jar(postgresql-jdbc4.jar)があればOK
postgresql.jarがない場合はコピー(またはダウンロード)する。
ls ~/app/tomcat10/lib/postgresql*
#cp /usr/share/java/postgresql.jar ~/app/tomcat10/lib/
#wget -O app/tomcat10/lib/postgresql-42.4.0.jar https://jdbc.postgresql.org/download/postgresql-42.4.0.jar
データベースにはすでにつぎのテーブルが用意ができているものとする。
同名のテーブルがあるときはテーブルを作り直そう。
テーブル名:sample |
tel | room |
6447 | 高橋研究室 |
6547 | 情報通信実験室 |
テーブル名:sample |
colum | type | 制約 | その他 |
tel | INTEGER | PRIMARY KEY | 内線番号は4桁(1000〜9999) |
room | TEXT | NOT NULL | |
#データベースに接続
psql データベース名
#テーブル新規作成
CREATE TABLE sample(tel INTEGER PRIMARY KEY, room TEXT NOT NULL);
#データを挿入
INSERT INTO sample(tel,room) VALUES (6447,'高橋研究室'),(6547,'情報通信実験室');
SELECT * FROM sample;
方針
-
「電話番号で検索」と「部屋で検索」は処理が違う。
扱っているリクエストパラメータがちがうのでそれぞれに対応したサーブレットに処理をさせる。
(1つのサーブレットで処理で処理できないわけではない)
-
表示する結果は似たものとなるので、jspは1つでよいだろう。
- MyBeansはRDBMSと通信して電話番号や部屋を取得する。
Servlet1,Servlet2でリクエストパラメータをBeansへ渡した後、データベースへの問合せを行う。
データベースからの返事をもとに、電話番号と部屋を表形式にまとめる。
index.htmlを修正
検索ボタンを押した時、別々のサーブレットに処理をさせたい。index.htmlを修正しよう。

Myservlet1.java,Myservlet2.javaをつくる
さきほどのMyservlet.javaを参考にサーブレットMyservlet1.java,Myservlet2.javaをつくる。
Myservlet1は「電話番号から検索」を担当する。Myservlet2は「部屋から検索」を担当する。
Myservlet1.java,Myservlet2.javaはほぼ同じ内容なので、間違えないようにタイプしてほしい。
Myservlet1.java | Myservlet2.java |
package myapp;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Myservlet1 extends HttpServlet {
private static final long serialVersionUID = 20220730L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
MyBeans mybeans = new MyBeans();
mybeans.setTel(req.getParameter("tel"));
mybeans.setSubmit(req.getParameter("submit"));
try {
mybeans.query1();
} catch (Exception ex) {
throw new ServletException(ex);
}
//MyBeansクラスをリクエスト属性にセット
req.setAttribute("MyBeans", mybeans);
//つづきはmyjsp.jspへ
this.getServletContext().getRequestDispatcher("/myjsp.jsp").forward(req, resp);
}
} |
package myapp;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Myservlet2 extends HttpServlet {
private static final long serialVersionUID = 20220730L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
MyBeans mybeans = new MyBeans();
mybeans.setRoom(req.getParameter("room"));
mybeans.setSubmit(req.getParameter("submit"));
try {
mybeans.query2();
} catch (Exception ex) {
throw new ServletException(ex);
}
//MyBeansクラスをリクエスト属性にセット
req.setAttribute("MyBeans", mybeans);
//つづきはmyjsp.jspへ
this.getServletContext().getRequestDispatcher("/myjsp.jsp").forward(req, resp);
}
} |
web.xmlを修正
サーブレットが増えたのでweb.xmlを修正する。
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>myservlet20220728</servlet-name>
<servlet-class>myapp.Myservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet20220728</servlet-name>
<url-pattern>/Myservlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>myservlet202207301</servlet-name>
<servlet-class>myapp.Myservlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet202207301</servlet-name>
<url-pattern>/Myservlet1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>myservlet202207302</servlet-name>
<servlet-class>myapp.Myservlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet202207302</servlet-name>
<url-pattern>/Myservlet2</url-pattern>
</servlet-mapping>
</web-app>
myjsp.jspを修正
ほとんど中身がないように見えるが、大事な部分はMyBeansがつくるのでこれでよい。
<%@ page contentType="text/html; charset=utf-8" %>
<jsp:useBean id="MyBeans" class="myapp.MyBeans" scope="request" />
<html>
<head>
<title>myjsp</title>
</head>
<body>
<h1>電話番号・部屋</h1>
<jsp:getProperty name="MyBeans" property="table" />
</body>
</html>
MyBeansを修正
RDBMSと通信するためにいくつかのプロパティとメソッドを追加する。
すこしはプログラムらしくなった気がする。
MyBeansにアレコレ突っ込んだけど、本当はRDBMSに関する部分(RDBMSクラス)とMyBeans固有の部分(MyBeansクラス)に分けたい。
package myapp;
import java.sql.*;
public class MyBeans {
String sql="";
Connection con=null;
Statement st=null ;
ResultSet rs=null;
final String lf="\n";
String table;
Integer tel;
String room,submit;
(途中省略)
// --- ここから追記 ---
public void query1() {//電話番号から部屋を検索
sql="SELECT tel,room FROM sample WHERE tel=" + tel + ";";
execquery();
}
public void query2() {//部屋から電話番号を検索
sql="SELECT tel,room FROM sample WHERE room='" + room + "';";
execquery();
}
private void execquery() {
String url = "jdbc:postgresql://192.168.xx.xx:5432/db19000";
String username = "19000";
String password = "xxxxxxxx";
try {
Class.forName("org.postgresql.Driver");
con = DriverManager.getConnection(url, username, password);
st = con.createStatement();
rs = st.executeQuery(sql);
table="<table border='1'>";
table+="<tr><th>電話番号</th><th>部屋</th></tr>" + lf;
String msg="<tr><td colspan='2'>該当しませんでした</td></tr>";
while (rs.next()) {
msg="<tr>";
msg+= "<td>" + rs.getInt("tel") + "</td>";
msg+= "<td>" + rs.getString("room").trim() + "</td></tr>" + lf;
}
table+= msg +"</table>" + lf;
rs.close(); st.close(); con.close();
} catch (Exception ex) {
table="DB error:" + lf + ex.toString();
System.out.println("DB error:"+lf+ex.toString() + lf + sql);
}
}
}
動作確認
電話番号で検索、部屋で検索どちらも同じように見えるが(MyBeans.execquery()は共通だし、表示はmyjsp.jspだ)、よく見ると違いがある。
アドレスバーを見ると「電話番号で検索」はMyservlet1で処理したことがわかる。 | |
アドレスバーを見ると「部屋で検索」はMyservlet2で処理したことがわかる。 |
 | |  |
おまけで「知らない電話番号」を検索したときの処理も加えた。

いつまでも「知らない電話番号」のままでは不便だ。
つぎは電話番号を登録してみよう。