JAVA操作データベースとデザインパターンアプリケーションのエレガントな説明

JAVA操作データベースとデザインパターンアプリケーションのエレガントな説明

1. JDBCを使用して、ビジネス層でデータベースを直接操作します-最も単純で最も直接的な操作

1)データベースのURL、ユーザー名、パスワードはコードにハードコードされています

Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
     String url="jdbc:oracle:thin:@localhost:1521:orcl";
     String user="scott";
     String password="tiger";
     Connection conn= DriverManager.getConnection(url,user,password);  
     Statement stmt=conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
     String sql="select * from test";
     ResultSet rs=stmt.executeQuery(sql);

2)ファサードモードとコマンドモードを採用し、DBUtilクラスを使用してJDBC操作をカプセル化します。データベースのURL、ユーザー名、パスワードを構成ファイル(xml、プロパティ、iniなど)に配置できます。この方法は、小さなプログラムで広く使用されています。

2. DAO(データアクセサーオブジェクト)モード-疎結合の始まりDAO =データ+アクセサー+ドメインオブジェクト

たとえば、User class-domain object(javabean)

UserDAOクラスアクセサーは、メソッドgetUser(int id)を提供し、save(User user)にはJDBC操作が含まれます。これら2つのクラスは、データ操作を完了するためにビジネスロジックで使用されます。

ファクトリモードを使用すると、異なるデータベース接続間の移植が容易になります。

3.データベースリソース管理モード

  • 3.1データベース接続プールテクノロジー

リソースの再利用、接続の頻繁な作成と解放を回避すると、パフォーマンスのオーバーヘッドが大きくなり、システムの応答速度が速くなります。

JDBCのリソースオブジェクトインターフェイス(Connection、Statement、ResultSet)の一部を実装することにより、デコレータデザインパターンを使用して、PooledConnection、PooledStatement、およびPooledResultSetの3つの論理リソースオブジェクトを生成できます。

最も単純なデータベース接続プールの実装の1つ:

public class ConnectionPool {

        private static Vector pools;
        private final int POOL_MAXSIZE = 25;
        /**
         * 获取数据库连接
         * 如果当前池中有可用连接,则将池中最后一个返回;若没有,则创建一个新的返回
         */
        public synchronized Connection getConnection() {
               Connection conn = null;
               if (pools == null) {
                      pools = new Vector();
               }

               if (pools.isEmpty()) {
                      conn = createConnection();
               } else {
                      int last_idx = pools.size() - 1;
                      conn = (Connection) pools.get(last_idx);
                      pools.remove(last_idx);
               }

               return conn;
        }

        /**
         * 将使用完毕的数据库连接放回池中
         * 若池中连接已经超过阈值,则关闭该连接;否则放回池中下次再使用
         */
        public synchronized void releaseConnection(Connection conn) {
               if (pools.size() >= POOL_MAXSIZE)
                      try {
                             conn.close();
                      } catch (SQLException e) {
                             // TODO自动生成 catch 块
                             e.printStackTrace();
                      } else
                      pools.add(conn);
        }

        public static Connection createConnection() {
               Connection conn = null;
               try {
                      Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
                      String url = "jdbc:oracle:thin:@localhost:1521:orcl";
                      String user = "scott";
                      String password = "tiger";
                      conn = DriverManager.getConnection(url, user, password);
               } catch (InstantiationException e) {
                      // TODO自动生成 catch 块
                      e.printStackTrace();
               } catch (IllegalAccessException e) {
                      // TODO自动生成 catch 块
                      e.printStackTrace();
               } catch (ClassNotFoundException e) {
                      // TODO自动生成 catch 块
                      e.printStackTrace();
               } catch (SQLException e) {
                      // TODO自动生成 catch 块
                      e.printStackTrace();
               }

               return conn;
        }
}

注:getConnection()メソッドによって取得されたConnectionを使用すると、プログラマーはconn.close()メソッドを呼び出してデータベース接続を閉じることに慣れているため、上記のデータベース接続メカニズムは役に立ちません。conn.close()メソッドを呼び出すときにreleaseConnection()メソッドを呼び出す方法は?これが鍵です。ここでは、プロキシモードとJavaリフレクションメカニズムを使用します。

public synchronized Connection getConnection() {
               Connection conn = null;
               if (pools == null) {
                      pools = new Vector();
               }

               if (pools.isEmpty()) {
                      conn = createConnection();
               } else {
                      int last_idx = pools.size() - 1;
                      conn = (Connection) pools.get(last_idx);
                      pools.remove(last_idx);
               }

         ConnectionHandler handler=new ConnectionHandler(this);
               return handler.bind(con);
        }

public class ConnectionHandler implements InvocationHandler {
      private Connection conn;
      private ConnectionPool pool;

      public ConnectionHandler(ConnectionPool pool){
             this.pool=pool;
      }

      /**
       * 将动态代理绑定到指定Connection
       * @param conn
       * @return
       */
      public Connection bind(Connection conn){
             this.conn=conn;
Connection proxyConn=(Connection)Proxy.newProxyInstance(
conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this);
           return proxyConn;
      }

        /* (非 Javadoc)
         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
         *

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               // TODO自动生成方法存根
               Object obj=null;
               if("close".equals(method.getName())){
                      this.pool.releaseConnection(this.conn);
               }
               else{
                      obj=method.invoke(this.conn, args);
               }

               return obj;
        }
}

実際のプロジェクトでは、データベース接続プールメカニズムを最初から設計する必要はありません。C3P0、dbcp、Proxoolなどの成熟したオープンソースプロジェクトが優れた実装を提供します。一般的に、Apache dbcpの使用をお勧めします。基本的な使用例:

DataSource ds = null;
    try{

      Context initCtx = new InitialContext();
      Context envCtx = (Context) initCtx.lookup("java:comp/env");
      ds = (DataSource)envCtx.lookup("jdbc/myoracle");
         if(ds!=null){
                 out.println("Connection is OK!");
                 Connection cn=ds.getConnection();
                 if(cn!=null){
                         out.println("cn is Ok!");
                 Statement stmt = cn.createStatement();
                  ResultSet rst = stmt.executeQuery("select * from BOOK");
                 out.println("<p>rst is Ok!" + rst.next());
                 while(rst.next()){
                         out.println("<P>BOOK_CODE:" + rst.getString(1));
                   }
                         cn.close();
                 }else{
                         out.println("rst Fail!");
                 }
         }
         else
                 out.println("Fail!");
            }catch(Exception ne){ out.println(ne);
          }
  • 3.2ステートメントプール

通常のプリコンパイル済みコード:

String strSQL=”select name from items where id=?”;
PreparedStatement ps=conn.prepareStatement(strSQL);
ps.setString(1, “2”);
ResultSet rs=ps.executeQuery();

ただし、PreparedStatementは特定の接続に関連付けられています。接続が閉じられると、関連するPreparedStatementも閉じられます。PreparedStatementバッファー・プールを作成するために、invokeメソッドでSQLステートメントを使用して、プールに使用可能なインスタンスがあるかどうかを判別できます。

  • 永続層の設計とO / Rマッピングテクノロジー

1)Hernate:新製品の開発に適しており、クローズドデザインのHibernateは、xml / javaリフレクションテクノロジーなどを使用して、java pojoオブジェクトをデータベーステーブルにマッピングすることにより、2003年にJbossに引き継がれました。3.0は、ストアドプロシージャと手書きSQLのサポートを提供し、それ自体がhql言語を提供します。開発に必要な書類:

hibernate配置文件: hibernate.cfg.xml 或 hibernate.properties
hibernate 映射文件: a.hbm.xml
pojo类源文件: a.java  

导出表与表之间的关系:
a. 从java对象到hbm文件:xdoclet
b. 从hbm文件到java对象:hibernate extension
c. 从数据库到hbm文件:middlegen
d. 从hbm文件到数据库:SchemaExport
  • 2)Iatis:レガシーシステムの変換と既存のデータベースの再利用に適しており、柔軟性が高い3)Apache OJB:標準の完全サポートに利点がある4)EJB:クラスターサーバーに適しており、パフォーマンスが同じではない人々はとても悪いと批判しました5)JDO(javaデータオブジェクト)

Propertiesオブジェクトを設定してJDOPersistenceManagerFactory(JDBC接続プールのDataSourceに相当)を取得してから、PersistenceManagerオブジェクト(JDBCのConnectionオブジェクトに相当)を取得すると、このPersistenceManagerオブジェクトを使用して追加、更新、オブジェクトを削除してクエリします。JDOQLはJDOのクエリ言語であり、SQLに少し似ていますが、Javaの構文に準拠しています。

  • オープンソースフレームワークに基づくStruts + Spring + Hibernate実装スキーム

例:これは、3層アーキテクチャのWebアプリケーションです。ビジネスエージェントはアクションを介して呼び出され、DAOクラスはアクションを介して呼び出されます。次のフローチャートは、MyUsersがどのように機能するかを示しています。番号は、Webレイヤー(UserAction)から中間レイヤー(UserManager)、データレイヤー(UserDAO)、そしてその逆のプロセスのシーケンスを示しています。SpringはAOPであり、UserManagerとUserDAOはどちらもインターフェイスです。

  • 1)Webレイヤー(UserAction):中間レイヤーのインターフェイスメソッドを呼び出し、UserManagerを属性として挿入します。

人気のあるStrutsフレームワークを使用すると、多くの人がそれを却下しますが、このテクノロジーは業界でより一般的に使用され、基本的な機能を満たし、トレーニングと学習のコストを削減できます。

  • 2)中間層(UserManager):UserDAOを属性として挿入します。その実装は、主にデータ層インターフェースのいくつかのメソッドを呼び出すことであり、トランザクション制御にあります。これはSpringフレームワークを使用して実装され、IOCとAOPはそれと同義であり、完全な機能と非常に優れたアーキテクチャを備えています。
  • 3)データレイヤー(UserDAO):実装クラスはHibernateDaoSupportクラスを継承します。このクラスでは、getHibernateTemplate()の一部のメソッドを呼び出して特定のデータ操作を実行できます。

O / RマッピングにHibernateを使用すると、さまざまな兆候から、HibernateがEJB3.0のベータ版であることがわかります。

おすすめ

転載: blog.csdn.net/doubututou/article/details/111627138