前回、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クラス作るってことになるのかな?
う~ん、想像を絶する感じですね。
今回はこのへんで。