JAVA中操作数据库方式与设计模式的应用

1.   在业务层使用JDBC直接操作数据库-最简单,最直接的操作
紧耦合方式,黑暗中的痛苦

1)数据库url,username,password写死在代码中
  

Java代码 复制代码
  1. Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();   
  2.      String url="jdbc:oracle:thin:@localhost:1521:orcl";   
  3.      String user="scott";   
  4.      String password="tiger";   
  5.      Connection conn= DriverManager.getConnection(url,user,password);    
  6.      Statement stmt=conn.createStatement(  
  7. ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);   
  8.      String sql="select * from test";   
  9.      ResultSet rs=stmt.executeQuery(sql);   
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)采用Facade和Command模式,使用DBUtil类封装JDBC操作;
      数据库url,username,password可以放在配置文件中(如xml,properties,ini等)。
      这种方法在小程序中应用较多。

2.DAO(Data Accessor Object)模式-松耦合的开始
DAO = data + accessor + domain object

例如User类-domain object (javabean)
UserDAO类-accessor ,提供的方法getUser(int id),save(User user)内包含了JDBC操作
在业务逻辑中使用这两个类来完成数据操作。

使用Factory模式可以方便不同数据库连接之间的移植。

3.数据库资源管理模式
3.1 数据库连接池技术
资源重用,避免频繁创建,释放连接引起大大量性能开销;
更快的系统响应速度;

通 过实现JDBC的部分资源对象接口( Connection, Statement, ResultSet ),可以使用Decorator设计模式分别产生三种逻辑资源对象: PooledConnection, PooledStatement和 PooledResultSet。


一个最简单地数据库连接池实现:

Java代码 复制代码
  1. public class ConnectionPool {   
  2.   
  3.        private static Vector pools;   
  4.        private final int POOL_MAXSIZE = 25;   
  5.        /**
  6.          * 获取数据库连接
  7.          * 如果当前池中有可用连接,则将池中最后一个返回;若没有,则创建一个新的返回
  8.          */   
  9.        public synchronized Connection getConnection() {   
  10.                Connection conn = null;   
  11.               if (pools == null) {   
  12.                       pools = new Vector();   
  13.                }   
  14.   
  15.               if (pools.isEmpty()) {   
  16.                       conn = createConnection();   
  17.                } else {   
  18.                      int last_idx = pools.size() - 1;   
  19.                       conn = (Connection) pools.get(last_idx);   
  20.                       pools.remove(last_idx);   
  21.                }   
  22.   
  23.               return conn;   
  24.         }   
  25.   
  26.        /**
  27.          * 将使用完毕的数据库连接放回池中
  28.          * 若池中连接已经超过阈值,则关闭该连接;否则放回池中下次再使用
  29.          */   
  30.        public synchronized void releaseConnection(Connection conn) {   
  31.               if (pools.size() >= POOL_MAXSIZE)   
  32.                      try {   
  33.                              conn.close();   
  34.                       } catch (SQLException e) {   
  35.                             // TODO自动生成 catch 块   
  36.                              e.printStackTrace();   
  37.                       } else   
  38.                       pools.add(conn);   
  39.         }   
  40.   
  41.        public static Connection createConnection() {   
  42.                Connection conn = null;   
  43.               try {   
  44.                       Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();   
  45.                       String url = "jdbc:oracle:thin:@localhost:1521:orcl";   
  46.                       String user = "scott";   
  47.                       String password = "tiger";   
  48.                       conn = DriverManager.getConnection(url, user, password);   
  49.                } catch (InstantiationException e) {   
  50.                      // TODO自动生成 catch 块   
  51.                       e.printStackTrace();   
  52.                } catch (IllegalAccessException e) {   
  53.                      // TODO自动生成 catch 块   
  54.                       e.printStackTrace();   
  55.                } catch (ClassNotFoundException e) {   
  56.                      // TODO自动生成 catch 块   
  57.                       e.printStackTrace();   
  58.                } catch (SQLException e) {   
  59.                      // TODO自动生成 catch 块   
  60.                       e.printStackTrace();   
  61.                }   
  62.               return conn;   
  63.         }   
  64. }   
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()方法?这是关键。这里,我们使用Proxy模式和java反射 机制。

Java代码 复制代码
  1.    
  2. public synchronized Connection getConnection() {   
  3.                Connection conn = null;   
  4.               if (pools == null) {   
  5.                       pools = new Vector();   
  6.                }   
  7.   
  8.               if (pools.isEmpty()) {   
  9.                       conn = createConnection();   
  10.                } else {   
  11.                      int last_idx = pools.size() - 1;   
  12.                       conn = (Connection) pools.get(last_idx);   
  13.                       pools.remove(last_idx);   
  14.                }   
  15.           
  16.          ConnectionHandler handler=new ConnectionHandler(this);   
  17.               return handler.bind(con);   
  18.         }   
  19.   
  20. public class ConnectionHandler implements InvocationHandler {   
  21.      private Connection conn;   
  22.      private ConnectionPool pool;   
  23.        
  24.      public ConnectionHandler(ConnectionPool pool){   
  25.             this.pool=pool;   
  26.       }   
  27.        
  28.      /**
  29.        * 将动态代理绑定到指定Connection
  30.        * @param conn
  31.        * @return
  32.        */   
  33.      public Connection bind(Connection conn){   
  34.             this.conn=conn;   
  35. Connection proxyConn=(Connection)Proxy.newProxyInstance(   
  36. conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this);   
  37.           return proxyConn;   
  38.       }   
  39.        
  40.        /* (非 Javadoc)
  41.          * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
  42.          */   
  43.        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  44.               // TODO自动生成方法存根   
  45.                Object obj=null;   
  46.               if("close".equals(method.getName())){   
  47.                      this.pool.releaseConnection(this.conn);   
  48.                }   
  49.               else{   
  50.                       obj=method.invoke(this.conn, args);   
  51.                }   
  52.                 
  53.               return obj;   
  54.         }   
  55. }   
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; } }


   

posted on 2009-01-07 10:04  dhj  阅读(223)  评论(0编辑  收藏  举报

导航