zoukankan      html  css  js  c++  java
  • 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; } }


       

  • 相关阅读:
    数组的应用:一。冒泡排序二。折半查找!二维数组的学习。
    break与continue,while 循环和一维数组的学习及作业
    for循环的应用:迭代法和穷举法
    循环
    称体重
    js js弹出框、对话框、提示框、弹窗总结
    windows 服务器开设端口
    SQL Server 数据库分离与附加(图文教程)
    ASP.NET MVC5 PagedList分页示例
    mvc 连接数据库但单复值得问题
  • 原文地址:https://www.cnblogs.com/danghuijian/p/4400807.html
Copyright © 2011-2022 走看看