DAOパターンとは?ServletとJDBC開発で重要な設計パターンを初心者向けに徹底解説
新人
「Servletでデータベースにアクセスするプログラムを書いていたんですが、DAOパターンっていう言葉を見かけました。これは何なんですか?」
先輩
「DAOパターンは、データベース処理を専用のクラスにまとめる設計方法のことです。Servletの中にSQLを書かずに、データベース処理を分離するために使われます。」
新人
「データベース処理を分けると、何かメリットがあるんですか?」
先輩
「大きなメリットがあります。プログラムの見通しがよくなり、保守や機能追加がとても簡単になります。特にServletとJDBCを使ったWebアプリ開発では、DAOパターンはとてもよく使われています。」
新人
「なるほど。Servletのプログラムを整理するための仕組みなんですね。詳しく知りたいです。」
先輩
「それでは、DAOパターンとは何か、なぜServlet開発で重要なのか、そしてDAOパターンの基本構成まで順番に解説していきます。」
1. DAOパターンとは?データベース処理を分離する設計パターン
DAOパターンとは、データベースへのアクセス処理を専用のクラスにまとめる設計方法のことです。DAOはData Access Objectの略で、日本語ではデータアクセスオブジェクトと呼ばれます。
JavaのWebアプリケーション開発では、ServletとJDBCを使ってデータベースにアクセスすることがよくあります。しかし、Servletの中にSQL文やデータベース処理を書いてしまうと、プログラムが複雑になりやすくなります。
そこで使われるのがDAOパターンです。DAOパターンでは、データベースに関する処理をDAOクラスという専用クラスにまとめます。そしてServletはDAOクラスを呼び出すだけにすることで、プログラムの役割をきれいに分けることができます。
例えば、ネット通販サイトを想像してみてください。商品情報をデータベースから取得する処理があるとします。もしServletの中に直接SQLを書くと、商品検索処理や画面表示処理とデータベース処理が混ざってしまいます。
DAOパターンを使うと、商品情報を取得する処理は商品DAOクラスにまとめることができます。Servletは商品DAOクラスを呼び出すだけなので、プログラムがとても分かりやすくなります。
このように、DAOパターンはデータベース処理を整理し、Webアプリケーションの構造をきれいに保つために使われる重要な設計パターンです。特にJavaのServlet開発やJDBCプログラミングでは、基本的な設計方法として広く利用されています。
2. なぜServlet開発でDAOパターンが使われるのか
Servletでデータベース処理を書くとき、初心者の多くはServletの中に直接SQLを書いてしまいます。確かに小さなプログラムであればそれでも動作します。しかし、アプリケーションが大きくなると大きな問題が発生します。
まず、プログラムが非常に読みにくくなります。Servletの中には、リクエスト処理、画面制御、入力値処理、そしてデータベース処理がすべて書かれることになります。その結果、一つのクラスが巨大になり、どこに何が書かれているのか分かりにくくなります。
次に、修正や機能追加が難しくなります。例えばデータベース構造が変更された場合、すべてのServletのSQLを修正しなければならない可能性があります。これは非常に大変な作業です。
DAOパターンを使うと、この問題を解決できます。データベース処理をDAOクラスにまとめておけば、SQLの修正はDAOクラスだけで済みます。ServletはDAOを呼び出すだけなので、影響範囲が小さくなります。
さらにDAOパターンを使うことで、プログラムの役割分担が明確になります。Servletはリクエスト処理を担当し、DAOはデータベース処理を担当します。このように責任を分離することで、プログラムの構造が整理されます。
JavaのWebアプリケーション開発では、このような設計をレイヤー構造と呼びます。画面処理、業務処理、データベース処理を分けることで、大規模なシステムでも管理しやすくなります。
そのため、ServletとJDBCを使ったWebアプリ開発では、DAOパターンはほぼ必須と言えるほど重要な設計手法になっています。
3. DAOパターンの基本構成
DAOパターンは主に三つのクラスで構成されます。それがDAOクラス、DTOクラス、そして呼び出し側のクラスです。呼び出し側はServletやServiceクラスになることが多いです。
まずDAOクラスは、データベース処理を担当するクラスです。SQLの実行やデータ取得など、データベースに関係する処理はすべてこのクラスにまとめます。例えばユーザー情報を扱う場合はUserDAOのようなクラスを作ります。
次にDTOクラスです。DTOはData Transfer Objectの略で、データをまとめて運ぶためのクラスです。データベースから取得した情報をJavaオブジェクトとして扱うために使います。例えばユーザーIDや名前などの情報を一つのオブジェクトにまとめます。
そして最後が呼び出し側のクラスです。ServletなどのクラスはDAOを呼び出してデータを取得します。データベース処理はDAOに任せるため、Servletはシンプルな処理だけを書くことができます。
この三つの役割を分けることで、プログラムの構造がとても整理されます。特にJavaのWebシステム開発では、この構成は非常に重要です。
まずはDTOクラスの例を見てみましょう。DTOはデータを保存するだけのシンプルなクラスです。
public class UserDTO {
private int id;
private String name;
private String email;
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
次にDAOクラスの例です。このクラスではデータベースにアクセスしてユーザー情報を取得します。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class UserDAO {
public UserDTO findUser(int id) throws Exception {
UserDTO user = new UserDTO();
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sampledb",
"root",
"password"
);
String sql = "SELECT id, name, email FROM users WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
}
rs.close();
ps.close();
conn.close();
return user;
}
}
このようにDAOクラスにデータベース処理をまとめることで、Servletはデータ取得の詳細を意識する必要がなくなります。結果としてプログラムの可読性が高くなり、修正や保守がとても簡単になります。
JavaのServletとJDBCを使ったWebアプリケーション開発では、このDAOパターンを理解しておくことがとても重要です。Webシステム開発の基本設計として、多くの企業システムでも採用されている設計方法です。
4. DTOクラスの役割と作成方法
前の章ではDAOパターンの基本構成として、DAOクラス、DTOクラス、そして呼び出し側のクラスという三つの役割があることを説明しました。ここからは、その中でもまずDTOクラスについて詳しく見ていきます。
DTOとはデータトランスファーオブジェクトの略であり、データをまとめて受け渡しするためのクラスのことです。データベースから取得した情報を一つのオブジェクトとして扱うために利用されます。
例えばユーザー情報をデータベースから取得する場合を考えてみましょう。ユーザーにはユーザー番号、名前、メールアドレスなどの情報があります。これらをそれぞれ別々の変数で扱うと、プログラムがとても複雑になります。
そこでDTOクラスを利用します。ユーザーの情報を一つのクラスにまとめて定義しておくことで、ユーザー情報を一つのオブジェクトとして扱うことができるようになります。
このようにすることで、データベースから取得した情報を整理しやすくなり、プログラム全体の可読性が高くなります。また複数のデータをまとめて受け渡しできるため、処理の流れも分かりやすくなります。
DTOクラスは基本的にデータを保持するためだけのシンプルなクラスです。そのため特別な処理を書くことはほとんどありません。一般的にはフィールド変数とゲッターメソッド、セッターメソッドだけを持つ構造になります。このような構造のクラスはJavaBeanと呼ばれることもあります。
それではユーザー情報を保持するDTOクラスの作成例を見てみましょう。ここではユーザー番号、名前、メールアドレス、年齢という情報を保持するクラスを作成します。
public class UserDTO {
private int id;
private String name;
private String email;
private int age;
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
このようにDTOクラスはとてもシンプルな構造になります。フィールド変数にデータを保存し、ゲッターメソッドで値を取得し、セッターメソッドで値を設定するだけです。
データベースからデータを取得したときは、このDTOクラスのオブジェクトを作成し、そのオブジェクトに値をセットします。そしてそのオブジェクトをServletなどに返すことで、データを安全に受け渡しすることができます。
DTOクラスを使うことで、データのまとまりをオブジェクトとして扱えるようになります。その結果、プログラム構造が整理され、Webアプリケーション全体の設計が分かりやすくなります。
5. DAOクラスの役割と実装方法
次にDAOクラスについて詳しく解説します。DAOクラスはデータベース処理を専門に担当するクラスです。データベースへの接続、SQLの実行、検索結果の取得などの処理をこのクラスにまとめます。
Webアプリケーションではデータベース操作が頻繁に発生します。もしServletの中にすべてのSQL処理を書いてしまうと、プログラムが非常に長くなり、どこで何をしているのか分かりにくくなります。
そのためDAOクラスを作成し、データベース処理をこのクラスに集約します。ServletはDAOクラスのメソッドを呼び出すだけにすることで、処理の役割を明確に分離することができます。
DAOクラスでは主に次のような処理を行います。まずデータベースへ接続します。その次にSQL文を準備し、パラメータを設定します。そしてSQLを実行して結果を取得します。最後に取得したデータをDTOに格納して呼び出し側へ返します。
それではユーザー情報をデータベースから取得するDAOクラスの例を見てみましょう。ここではユーザー一覧を取得するメソッドを実装しています。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class UserDAO {
public List<UserDTO> findAllUsers() throws Exception {
List<UserDTO> userList = new ArrayList<>();
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sampledb",
"root",
"password"
);
String sql = "SELECT id, name, email, age FROM users";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
UserDTO user = new UserDTO();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
user.setAge(rs.getInt("age"));
userList.add(user);
}
rs.close();
ps.close();
conn.close();
return userList;
}
}
このようにDAOクラスではSQLを実行し、取得したデータをDTOオブジェクトに格納します。そのDTOをリストなどにまとめて呼び出し側に返すことで、データを整理された形で扱うことができます。
DAOクラスを作成しておくことで、データベース処理を一箇所にまとめることができます。その結果、SQLの修正やデータベース構造の変更が発生した場合でも、DAOクラスだけを修正すればよくなります。
このような構造は保守性の高いプログラムを作るうえでとても重要です。実際の企業システムでもDAOクラスを利用してデータベース処理を分離する設計が広く採用されています。
6. Servletなどの呼び出し側からDAOを利用する基本的な流れ
ここまででDTOクラスとDAOクラスの役割について理解できました。最後にServletなどの呼び出し側のクラスからDAOを利用する基本的な流れを解説します。
WebアプリケーションではServletがユーザーからのリクエストを受け取り、必要な処理を実行します。データベースの情報が必要な場合は、ServletからDAOクラスを呼び出してデータを取得します。
基本的な処理の流れはとてもシンプルです。まずServletの中でDAOクラスのオブジェクトを作成します。次にDAOのメソッドを呼び出してデータベースから情報を取得します。そして取得したDTOオブジェクトを使って画面表示などの処理を行います。
このように役割を分離することで、Servletは画面制御やリクエスト処理だけに集中できるようになります。一方でDAOはデータベース処理に専念できるため、プログラムの責任範囲が明確になります。
それではServletからDAOを呼び出してユーザー情報を取得する簡単な例を見てみましょう。
import java.io.IOException;
import java.util.List;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/userList")
public class UserListServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
UserDAO dao = new UserDAO();
List<UserDTO> users = dao.findAllUsers();
request.setAttribute("users", users);
request.getRequestDispatcher("/userList.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
このServletではDAOクラスのメソッドを呼び出してユーザー一覧を取得しています。そして取得したデータをリクエスト属性に格納し、画面表示用のページへ渡しています。
このような構造にすることで、Servletのコードはとてもシンプルになります。データベース処理の詳細をServletが意識する必要はなくなり、コードの見通しがよくなります。
またDAOクラスを複数のServletから共通利用できるようになるため、同じデータベース処理を何度も書く必要がなくなります。その結果、コードの重複を防ぐことができ、保守性の高いWebアプリケーションを構築できるようになります。
7. DAOパターンを導入するメリット
DAOパターンを導入すると、JavaのWebアプリケーション開発において多くのメリットがあります。特に重要なのが、保守性の向上と再利用性の向上です。これらは長期間運用されるシステムにおいて非常に重要な要素になります。
まず保守性について説明します。保守性とは、プログラムの修正や機能追加を行いやすいかどうかという観点のことです。システム開発では、一度作って終わりではなく、その後も機能追加や仕様変更が頻繁に発生します。そのため、修正しやすい構造でプログラムを作っておくことがとても重要です。
DAOパターンを利用していない場合、Servletの中にSQL文が直接書かれていることがあります。このような状態では、データベースの構造が変更されたときに、複数のServletをすべて修正しなければならなくなります。
しかしDAOパターンを導入している場合は、データベース処理がDAOクラスにまとめられているため、修正はDAOクラスだけで済みます。これにより修正作業の範囲が小さくなり、プログラムの管理がとても楽になります。
次に再利用性についてです。再利用性とは、一度作成した処理を他の場所でも使えるようにすることを意味します。DAOクラスはデータベース処理をまとめたクラスなので、複数のServletから共通して利用することができます。
例えばユーザー情報を取得する処理がある場合、ユーザー一覧画面、ユーザー詳細画面、管理画面など、さまざまな場所で同じデータベース処理を使うことがあります。このような場合、DAOクラスに処理をまとめておけば、同じメソッドを呼び出すだけでデータ取得が可能になります。
またDAOパターンを導入すると、プログラムの役割が明確になります。Servletはリクエスト処理や画面制御を担当し、DAOはデータベース処理を担当します。このように責任範囲を分けることで、プログラム構造が整理されます。
さらにチーム開発でも大きなメリットがあります。画面担当の開発者はServletや画面処理を担当し、データベース担当の開発者はDAOクラスを担当するなど、役割分担がしやすくなります。その結果、開発効率が向上し、品質の高いシステムを作りやすくなります。
このようにDAOパターンは、保守性、再利用性、可読性、開発効率の向上など、多くのメリットを持つ設計パターンです。JavaのServletとJDBCを使ったWebアプリケーション開発では、基本的な設計手法として広く利用されています。