龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

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

时间:2009-12-23 15:42来源:未知 作者:admin 点击:
分享到:
1. 在业务层使用JDBC直接操作数据库-最简单,最直接的操作 1)数据库url,username,passWord写死在代码中 Class.forName("Oracle.jdbc.driver.OracleDriver").newInstance(); String url="jdbc:oracle:thin:@localhost:152

  1. 在业务层使用JDBC直接操作数据库-最简单,最直接的操作
  
  1)数据库url,username,passWord写死在代码中
  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。
  
  
  一个最简单地数据库连接池实现:
  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反射机制。
  
  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("

  
  

精彩图集

赞助商链接