脱!プログラミング入門

このブログではプログラミング入門後にさらに能力を伸ばすための援助ができるようにしたいです

JavaでDAOパターンを使ってみる

 他の記事JavaからSqliteのデータベースに接続して簡単なデータの取得の例を書きました.この記事ではプログラムからデータベースを操作しやすくするための工夫について書いていきたいと思います.その工夫というのがDAOパターンです.

DAOパターンについて

 DAOパターンというのはデータベースへの操作(SELECT,INSERT,UPDATE,DELETE)をテーブルごとに記述するというプログラムの書き方のパターンのことを言います.テーブルごとにクラスを用意し,そのクラスに操作を行うメソッドを書いておくことでとあるテーブルに対して操作を行いたい時に,メソッドを呼び出すだけでテーブルに対する操作を行うことができるようになります.図に表すと以下のようになります.

f:id:esc_prog_begginer:20190930015852p:plain
DAOパターンを使った図
テーブルごとにDAOを書くという手間は大きいですが,呼び出す側のプログラムがスッキリします.

JavaでDAOパターンを実装

 それでは実際にDAOパターンを用いたプログラムの例を書いていきたいと思います.今回書くプログラムは以前の記事の例を引き続き用いたいと思います.まずは,PROFILEテーブルのデータ構造をJavaのクラスで表現したものを作ります.これはDTO(Data Transfer Object)と呼ばれるものになります.例を次に示します.

public class Profile {
    private int id;
    private String firstName;
    private String lastName;
    private String gender;

    public Profile(int id, String firstName, String lastName, String gender) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
    }

    public int getId() {
        return this.id;
    }
    public String getFirstName() {
        return this.firstName;
    }
    public String getLastName() {
        return this.lastName;
    }
    public String getGender() {
        return this.gender;
    }

    public String toString() {
        return "id: " + this.id + ", first-name: " + this.firstName + ", last-name: " + this.lastName
                + ", gender: " + this.gender;
    }
}

次にDAOパターンのクラスを示します.今回はPROFILEテーブルのデータを全て取ってくるという操作だけ書いています.

import java.util.List;
import java.util.ArrayList;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ProfileDAO {
    private final Connection conn;

    public ProfileDAO(Connection conn) {
        this.conn = conn;
    }

    public List<Profile> getAll() {
        List<Profile> data = new ArrayList<Profile>();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            String sql = "select * from PROFILE";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();

            while(rs.next()) {
                int id = rs.getInt("id");
                String firstName = rs.getString("first_name");
                String lastName = rs.getString("last_name");
                String gender = rs.getString("gender");
                Profile prf = new Profile(id, firstName, lastName, gender);
                data.add(prf);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(pstmt != null) {
                    pstmt.close();
                }
                if(rs != null) {
                    rs.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return data;
    }
}

次に記述した操作を試すためのMainクラスを示します.

import java.util.List;
import java.util.Iterator;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        Connection conn = null;

        try {
            Class.forName("org.sqlite.JDBC");

            conn = DriverManager.getConnection("jdbc:sqlite:sample.db");
            ProfileDAO profileDAO = new ProfileDAO(conn);

            List<Profile> profileData = profileDAO.getAll();

            for(Iterator it = profileData.iterator(); it.hasNext(); ) {
                System.out.println(it.next());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

Mainクラスを見ていただくと,何も工夫しない場合よりもプログラムがかなりスッキリしています.

終わりに

 今回はDAOパターンを使ってデータベースを操作する例を書きました.Mainクラスがかなりスッキリしたことがわかると思います.このDAOパターンですが,扱うテーブルの数が大きくなると,作成する必要があるクラスやメソッドが増えるためかなり大変になります.テーブルの構造に変更が生じるとなるとDAOやDTOのクラスの変更が手に負えない状態になります.DAOパターンはテーブル数があまり多くないときに使うといいかもしれません.