2016-04-11 3 views
1

私はREST APIを作成しています。すべてのリソースに対して1つのサービスクラスを定義しました。Javaでデータアクセスクラスを設計する

私はPersonリソースを持っています。これが私がデータベースとやり取りする方法です。

public class TeacherService { 


    public static List<Person> getAll() throws SQLException{ 

     //define the query string and objects 



     try{ 

       DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 
       connection = (Connection) DriverManager.getConnection(ConnectDb.CONN_STRING, ConnectDb.USERNAME, ConnectDb.PASSWORD); 
       statement = (PreparedStatement) connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, 
         ResultSet.CONCUR_READ_ONLY); 
       resultSet = statement.executeQuery(query); 

       //process results 

      }catch (SQLException e) { 
       System.err.println(e); 

      }finally{ 

       //close all shit 
      } 

     return list; 
    } 

    public static Person getById(int id) throws SQLException{ 
     //repeat 
    } 

    public static void addPerson(Person person) throws SQLException { 

     //repeat 
    } 

    public static void upateTeacher(Person person) throws SQLException { 


     //repeat 
    } 

    public static void deleteTeacher(int id) throws SQLException { 


      //repeat   
    } 


} 

したがって、すべてのケースと結果セット処理ロジックで異なるクエリを除いて、すべてのものはほぼ同じです。 これは多くのレベルでDRYに違反するだけでなく、維持するのが非常に扱いにくいようです。それを行う良い方法はありますか?

+0

私は新しい接続を開くことに対してお勧めします - クエリを実行している> - >接続、照会するたびに閉じます。開閉はオーバーヘッドの*ロット*を作り、かなり遅くなる。代わりに、新しいTeacherServiceオブジェクトを作成するときに接続を開き、TeacherServiceオブジェクトを閉じる/停止/破棄するまで接続を開いたままにしておきます。接続を再使用してください。あなたはPreparedStatementで同じことをすることができます(つまり、開いている接続上でそれらをすべて準備し、作成したオブジェクトへの参照を保持して、迅速な再利用を可能にします)。 – SnakeDoc

+0

結果セットとステートメントがすべて異なるので、コードスニペットをいくつか用意してください。どちらを閉じるかは問題です。 – Zeus

答えて

1

ここでは、どのように動くかの例を示します。この例は完璧ではありませんが、適切な経路に設定する必要があります。

基本的には、共通の共有接続を開いた後ですべてのステートメントを登録します。すべての作業を行い、次にshutdown()メソッドを呼び出してすべてを終了します。

public class MyDataAccessObject { 

    private final String getAllPersonsQuery = "SELECT persons FROM personTable"; 
    private PreparedStatement psGetAllPersonsQuery; 

    private final String addPersonQuery = "INSERT INTO personTable (personName) VALUES (?)"; // ? is a placeholder. Using PreparedStatement and ?'s, adds more safety and performance. 
    private PreparedStatement psAddPersonQuery; 

    private Connection conn; 

    private final String connectionString; 
    private final String username; 
    private final String password; 

    public MyDataAccessObject(String connectionString, String username, String password) { 
     this.connectionString = connectionString; 
     this.username = username; 
     this.password = password; 
    } 

    public void init() throws SQLException { 
     conn = DriverManager.getConnection(connectionString, username, password); // no longer required to register driver if using modern JDBC drivers. 
     psGetAllPersonsQuery = conn.prepareStatement(getAllPersonsQuery); 
     psAddPersonQuery = conn.prepareStatement(addPersonQuery); // we register these now, so it's fast to use later. 
    } 

    public void shutdown() throws SQLException { 
     if (conn != null) { 
      conn.close(); // this will close everything used ontop of this connection, including PreparedStatement's, and ResultSets, if still open. 
     } 
    } 

    public List<Person> getAllPersons() throws SQLException { 
     if (conn == null) { 
      // try to re-open connection 
      init(); 
     } 
     ResultSet rs = psGetAllPersonsQuery.execute(); 
     List<Person> list = new ArrayList<Person>(); 
     while (rs.next()) { 
      list.add(new Person(rs.getString(1))); // not sure how your data is setup, this is returning the first (1) column from the resultset 
     } 
     if (rs != null) { 
      rs.close(); 
     } 
     return list; 
    } // don't close the prepareStatement! 

    public void addPerson(Person person) throws SQLException { 
     if (conn == null) { 
      // try to re-open connection 
      init(); 
     } 
     psAddPersonQuery.setString(1, person.getName()); // or however you're storing the data. The 1 is saying replace the first ? with whatever data you specify after the comma. 
     psAddPersonQuery.executeUpdate(); // executeUpdate() returns an int, which says how many rows were modified. Since you're inserting here, we probably don't care. 
    } // don't close the prepareStatement! 

} 

あなたは好きで、それを使用します。

MyDataAccessObject mdao = new MyDataAccessObject(connectionString, username, password); 
mdao.init(); // now you're ready 

List<Person> list = mdao.getAllPersons(); 
// do stuff with your list 

.... 
mdao.addPerson(someNewPerson); 
// .... 

// now you're done running, so close it down 
mdao.shutdown(); 
+0

ありがとう、これは素晴らしいです。 – Zeus

関連する問題