前回、PosgreSQLのデータベース接続にJDBCドライバを使ってますが、引き続きJDBCドライバを利用していきます。JDBC(Java DataBase Connectivity)と呼ばれるクラス群も使っていく感じですかね。
DAO(Data Access Object)
データベースの接続、切断、SQLの発行など、データベースへのアクセスを専門に扱うクラスを作ってしまって、データベース関連はすべて任せてしまう考え方みたいです。
- データベース処理をDAOクラスに一括できる
- テーブル構成の変更による影響を小さくできる
1.データベース処理をDAOクラスに一括できる
他のクラスでデータベースとのやり取りが必要になったら、DAOクラスを使えば済むようです。
2.テーブル構成の変更による影響を小さくできる
データベースへアクセスしているのはDAOクラスだけになるので、データベースのテーブル構成が変更になっても、影響を受けるのはDAOクラスだけになるようなイメージですかね。(後述するDTOにも影響は出る気はするのですが....)
DTO(Data Transfer Object)
DAOクラスで取得してきたデータを保持するクラスがDTOクラスのようです。DTOクラスの構成は、
- テーブルのカラムに対応したフィールド
- フィールドのgetterとsetter
のようです。DTOクラスでデータを保持するメリットは、データベースへのアクセスを減らせることにあるようです。
一度、DAOクラスでデータベースから取得したデータを使い回す場合は、2度目からはDAOクラスでデータベースへのアクセスを経由せずに、DTOクラスのインスタンスから直接利用すればよくなります。
データベースへのアクセスは時間がかかるため、できる限りデータベースへのアクセスを減らすことが望ましいようです。

DAOとDTOを利用してデータベースへアクセス
テーブルのカラム名とデータ型に合わせて、DTOクラスにフィールドとgetterやsetterを作成します。

テーブルのカラム名とデータ型の確認。

⇩ SQLのデータ型とJavaのデータ型の対応は下記を参考にしました
package sqltest;
import java.sql.Date;
/**
* Ordersテーブル用DTOクラス
* @author ts0818
*
*/
public class OrdersDTO {
/**
* フィールド変数
*/
private int order_id;
private Date order_date;
private String client;
private int order_count;
/**
* getter order_id
* @return int order_id
*/
public int getOrder_id() {
return order_id;
}
/**
* setter order_id
* @param int order_id
*/
public void setOrder_id(int order_id) {
this.order_id = order_id;
}
/**
* getter order_date
* @return Date order_date
*/
public Date getOrder_date() {
return order_date;
}
/**
* setter order_date
* @param Date order_date
*/
public void setOrder_date(Date order_date) {
this.order_date = order_date;
}
/**
* getter client
* @return String client
*/
public String getClient() {
return client;
}
/**
* setter client
* @param String client
*/
public void setClient(String client) {
this.client = client;
}
/**
* getter order_count
* @return int order_count
*/
public int getOrder_count() {
return order_count;
}
/**
* setter order_count
* @param int order_count
*/
public void setOrder_count(int order_count) {
this.order_count = order_count;
}
}
続いてDAOクラス
package sqltest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* Ordersテーブル用のDAOクラス
* @author ts0818
*
*/
public class OrdersDAO {
public List<OrdersDTO> findAll() {
// DTOクラスのインスタンス格納用
List<OrdersDTO> ordersDTO = new ArrayList<>();
// JDBCドライバ読み込み
try {
// PostgreSQLドライバの読み込み
Class.forName("org.postgresql.Driver");
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
// データベースへの接続
try(Connection conn = DriverManager.getConnection(
"jdbc:postgresql:java_postgre",
"postgres",
"ts0818"
);) {
// sql文を実行するためのオブジェクト生成
Statement stmt = conn.createStatement();
// SELECT文の発行
String sql = "SELECT * FROM orders";
// sql文の実行結果を取得(データベースからの値)
ResultSet rset = stmt.executeQuery(sql);
// データベースから取得した値がある間、
while(rset.next()) {
// OrdersDTOクラスのインスタンスを生成
OrdersDTO dto = new OrdersDTO();
// カラムorder_idの値をフィールドorder_idにセット
dto.setOrder_id(rset.getInt("order_id"));
// カラムorder_dateの値をフィールドorder_dateにセット
dto.setOrder_date(rset.getDate("order_date"));
// カラムclientの値をフィールドclientにセット
dto.setClient(rset.getString("client"));
// カラムorder_countの値をフィールドorder_countにセット
dto.setOrder_count(rset.getInt("order_count"));
// インスタンスをListに格納
ordersDTO.add(dto);
// while文で次のレコードの処理へ?
}
} catch(SQLException e) {
e.printStackTrace();
}
// DTOクラスのインスタンスのListを返す
return ordersDTO;
}
}
最後に実行クラス
package sqltest; import java.util.List; public class OrdersMain { public static void main(String[] args) { // DAOクラスのインスタンスの生成 OrdersDAO dao = new OrdersDAO(); // findAll()メソッドの戻り値OrdersDTOクラスのインスタンスが格納されたList List<ordersDTO> orders = dao.findAll(); // Listの中のOrdersDTOクラスのインスタンスをループで処理 for(OrdersDTO order: orders) { System.out.println("order_id:" + order.getOrder_id()); System.out.println("order_date:" + order.getOrder_date()); System.out.println("client:" + order.getClient()); System.out.println("order_count:" + order.getOrder_count()); } } }
とりあえず、java_postgreデータベースからordersテーブルの値は取ってこれたようです。

これって、テーブルの数だけDAOクラスとDTOクラス作るってことになるのかな?
う~ん、想像を絶する感じですね。
今回はこのへんで。