Java学習ノート3:Dbuilsの汎用データベースメソッド解析

5267 ワード

Dbutilsの汎用データベースメソッドには、2つあります.1つは、削除・変更のためのUpdateメソッド、1つはクエリーのためのQueryメソッドです.
その汎用性の考え方に基づいてupdateメソッドとqueryメソッドの下位実装を解析する.
Dbutilsの2つの方法に基づいて考えてみましょう.
1.insert into bank values(null,?,?)などのプレースホルダ(?)を持つデータベース文を入力します.
2.汎用型のパラメータが入力され、入力されたパラメータの個数が可変である.
Update(添削):
//      
    /*
    * @param sql      sql  
    * @param args     ,...               ,args         
    * */
    public void update(String sql,Object ... args) throws SQLException {

        Connection conn = null;
        PreparedStatement ps = null;


        try {
            conn = JDBCutil02.getConn();
            ps = conn.prepareStatement(sql);

            for (int i=0;i

(Object...name)(可変パラメータ)により任意の数のパラメータを入力でき、Objectタイプは任意のタイプのパラメータを受け入れることができる.
次にforループによりargs配列を巡回し,PrepareStatementのsetObjectメソッドによりプレースホルダに値を付与する.
しかし、入力したパラメータの個数がプレースホルダと異なると、遍歴回数に問題があり、エラーが発生するという危険があります.
このリスクを解決するためにパラメータメタデータParameterMetaDataを使用します をクリックして、パラメータSQLの疑問符数を取得し、プレースホルダの数を計算することで、遍歴回数が正しくないという問題を解消します.
最適化されたUpdate:
 /*
       :       
    *     update  ,          ,       
    *         ParameterMetaData             
    * */
    public void update02(String sql,Object ... args) throws SQLException {

        Connection conn = null;
        PreparedStatement ps = null;


        try {
            conn = JDBCutil02.getConn();
            ps = conn.prepareStatement(sql);

            //   
            //        ,   
            ParameterMetaData metaData = ps.getParameterMetaData();
            int count = metaData.getParameterCount();

            for (int i=0;i

Queryの下位実装はやや複雑で、最初の2つの問題はupdateと同様にプレースホルダの数とパラメータが少し異なる場合、クエリ文は結果セットを返し、データベースが返す結果セットはカプセル化する必要があり、カプセル化された結果セットを返す必要があるため、queryのポイントは次のとおりです.
データ取得とデータパッケージ
解決方法:具体的にどのオブジェクトにカプセル化するか分からないため、結果セットを呼び出し者に渡して自分でカプセル化することを選択します.
  • まず、汎用インタフェース(ResultSet Handler)を宣言し、戻り値が汎用(T)、パラメータがResultSetのメソッド(T Handle(ResultSet rs))、すなわち汎用メソッドを定義する.またqueryも汎用メソッドとして定義され,戻り値はTである.
  • は、次いで、(public T query(String sql,ResultSet Handler handler,Object…args))
  • というResultSet Handlerインタフェースパラメータをquery汎用メソッドに追加する.
  • は、次いで、queryでパラメータhandlerのhandleメソッドを呼び出してデータをカプセル化し、カプセル化されたデータ(T t=(T)handler.Handle(rs);)を取得し、最後にカプセル化されたデータを返す.

  • 使用方法:
  • 匿名実装クラスによるインスタンス化 queryのResultSetHandlerインタフェースパラメータ(実装クラスへの参照を指し、インタフェースのアップコンバートに相当)は、handleメソッドで結果セット(rs)をカプセル化し、カプセル化されたデータオブジェクトタイプが呼び出し者によってインタフェースをインスタンス化したときに伝達されるhandleメソッドを実装する.(new ResultSetHandler(){})のように、最後にカプセル化されたデータオブジェクトタイプが返されます.

  • 具体的なコード:
    ResultSetHandlerインタフェース:
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public interface ResultSetHandler {
        /*
        *           。  
        * */
        T Handle(ResultSet rs);
    }
    

    Queryメソッド:
    /*  
               
        select * from aa
        select * from aa where id =?
        select * from aa where name=? and gender=?
           :    ,             。               ,      
            :             ,    ResultSetHandler   ,      handle  。
          query       ResultSetHandler    ,              handle  ,               。
    
        */
        public  T query(String sql,ResultSetHandler handler,Object ... args){
            Connection conn = null;
            PreparedStatement ps = null;
    
            try {
                conn = JDBCutil02.getConn();
                ps = conn.prepareStatement(sql);
    
                //   
                //        ,   
                ParameterMetaData metaData = ps.getParameterMetaData();
                int count = metaData.getParameterCount();
    
                for (int i=0;i

    Queryメソッドの呼び出し:
    /*
    * ResultSetHandler       
    * ResultSetHandler handle = new A();A      ,             ,        ,          。
    * */
    
       @Test
       public void testQuery(){
           Bank bank = query("select * from bank where id = ?", new ResultSetHandler() {
    
               @Override
               public Bank Handle(ResultSet rs) {
                   try {
                       Bank bank = new Bank();
                       while (rs.next()){
                           String name = rs.getString("name");
                           double money = rs.getDouble("money");
    
                           bank.setName(name);
                           bank.setMoney(money);
                       }
                       return bank;
                   } catch (SQLException e) {
                       e.printStackTrace();
                   }
                   return null;
               }
           },3);
    
           System.out.println(bank);
       }

    まとめ
    基本的にはDbuilsフレームワークのupdateとqueryメソッドの解析であり、updateメソッドは実行するだけで簡単である.
    queryメソッドのポイントは,主にデータのパッケージングにおいて,汎用型のパッケージングデータをどのように実現し,汎用型のデータを返すかである.
    汎用型の方式では,呼び出し者にデータをカプセル化するオブジェクトタイプを指定させ,匿名実装クラスを用いてqueryメソッドを呼び出す際にカプセル化メソッドを定義するか,継承ポートを予め作成したクラスをパラメータとして伝達するかにかかわらず,データカプセル化の作業を呼び出し者に任せる.
    核心思想は,我々が確定できないデータパッケージ,データオブジェクトタイプを呼び出し者に渡して処理し,汎用的な方法を定義する目的を達成することである.