装饰设计模式---自定义数据源

装饰设计模是对一个已存在的类进行增强,他的实现思路是:

1 明确被装饰类的继承体系,我们写的装饰类和被装饰类同在一个体系,即同一个级别;

2 定义一个被装饰类的一个成员变量,以构造函数的形式对他进行初始化操作;

3 明确哪些是我们要对被装饰类进行增强或者改写的功能;对无需增强的功能,直接调用被传进来的被装饰对象,调用原来的方法

对于要改下的功能进行自定义即可;

4 如果需要返回一个装饰类,最好以父类的形式返回;

自定义数据源的实现思路:

1 在类加载的时候就创建一批连接,并用一个集合(由于要多次进行增删操作,使用LinkedList)存储,取的时候从集合中remove,

2给用户提供获取连接的方法,当然对于用户获取的实际连接对象,这是我们包装后的连接对象,目的是为了不让用户直接关闭连接而损失

而是当用户调用关闭连接方法的时候,我们将连接从新放回原集合中(可以看做是一个数据库连接池);

3 实现java.sql.DataSource接口的其他方法;

我们自定义一个数据源主要是要改写用户获取的连接即Connection,改下close功能,防止用户之间关闭连接;从而损失连接;

不多说直接上代码;JDBC工具类,在此之前,数据库驱动包,配置文件什么的自己配吧,这个应该很简单:

 


package cn.itcast.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public final class JDBCUtils {
 private JDBCUtils() {
 }
 private final static String url;
 private final static String user;
 private final static String password;
 private final static String driverClassName;
 static {
  try {
   InputStream inputStream = JDBCUtils.class.getClassLoader()
     .getResourceAsStream("oracle_dbconfig.properties");
   Properties props = new Properties();
   props.load(inputStream);
   url = props.getProperty("url");
   user = props.getProperty("user");
   password = props.getProperty("password");
   driverClassName = props.getProperty("driverClassName");
  } catch (Exception e) {
   // 将异常转型为初始化错误抛出, 为数据库连接都没建好,没必要进行下去了;
   throw new ExceptionInInitializerError(e);
  }
 }
 
 public static Connection getConnection() {
  try {
   Class.forName(driverClassName);
   return DriverManager.getConnection(url, user, password);
  } catch (SQLException e) {
   throw new RuntimeException(e);
  } catch (ClassNotFoundException e) {
   throw new RuntimeException(e);
  }
 }
 public static void free(ResultSet resultSet, Statement statement,
   Connection connection) {
  if (resultSet != null) {
   try {
    resultSet.close();
   } catch (SQLException e) {
    throw new RuntimeException(e);
   }
   //当关闭结果集的时候,这 做通知gc对其进行回收;
   resultSet = null;
  }
  if (statement != null) {
   try {
    statement.close();
   } catch (SQLException e) {
    throw new RuntimeException(e);
   }
   statement = null;
  }
  if (connection != null) {
   try {
    connection.close();
   } catch (SQLException e) {
    throw new RuntimeException(e);
     
   connection = null;
  }
 }
}
下面这个是包装类MyConnection,只提供关键方法

public class UpgradeMyConnection extends MyConnection {
 private Connection conn;
 private LinkedList<Connection> pool;
 public UpgradeMyConnection(Connection conn, LinkedList<Connection> pool) {
  super(conn, pool);
 }
 @Override
 public void close() throws SQLException {
  pool.addFirst(conn);
 }
}

大家也许发现了, 这里是UpgradeMyConnection,听我细细说来,这是对包装设计模式的一种该进,如果我们每次都只对被包装对象的某些方法进行增强或改写,而必须继承或者实现许多我们并不关心的方法,即直接调用被包装类对象上的方法即可.一次两次还可以接受,如果每次都得这 做,估计 得吐了, 此我们想到,可不可以这 ,我们定义一个空包装类,即对被包装类的所有方法进行空包装,直接调用被包装类的对象;
然后我们在继承这个空包装类,那么我们就爽多了,只要覆盖我们想增强或者改写的方法, 为其他方法父类已经实现了就不用在转给被包装类对象了,这省了不少事;只要空包装类估计大家肯定也能看懂的.
下面这个是我们写的数据源类,当然只覆盖了 心方法getConnection,

package cn.itcast.datasource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import cn.itcast.util.JDBCUtils;
import sun.jdbc.odbc.JdbcOdbc;

public class UpgradeDataSource implements DataSource {
 private static LinkedList<Connection> pool=new LinkedList<Connection>();
 static{
  for(int i=0;i<10;i++){
   pool.add(JDBCUtils.getConnection());
  }
 }
 private UpgradeDataSource(){
 }
 private final static DataSource dataSource=new UpgradeDataSource();
 public static DataSource getDataSource(){
  return dataSource;
 }
 
 @Override
 public synchronized Connection getConnection() throws SQLException {
  if(pool.size()>0){
//这里返回的是包装好了的connection对象,但是我们的返回值还是写java.sql.Connection
//调用者完全可以将他当做connection对象来用,只是当他调用close方法的时候,被我们拦截并处理了,不是直接关闭
//而是从新返回数据库连接 中,从而做到了数据库连接的复用.
//同时必须得考虑到并发的问题是要同步代 块解决
   UpgradeMyConnection myConnection=new UpgradeMyConnection(pool.removeFirst(), pool);
   return myConnection;
  }else
   throw new RuntimeException("服务器正忙!!!");
 }
}

总结:包装设计模式或者说装饰设计模式,核心是对被包装类的某些方法进行增强和改写,相比于直接集成被包装类有如下好处;

1 由于你是直接集成,那么原先的一些属性会丢失;

2 会使得继承体系变得非常的臃肿;

<script type="text/javascript" id="wumiiRelatedItems"> </script>
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值