享元模式---学习笔记

这篇博文,是对于享元模式的综合应用,如果你还不了解享元模式,那请先google一下。

案例:用享元模式来实现一个数据库连接池

抽象享元类:数据库连接池

public interface DbConnectionPool {
    //1产生连接池,初始化连接池
	public void initConnPool() throws SQLException;

	//2设定打开或者关闭连接池
	public void setConnWitch(String onOrOff) throws SQLException;
	
	//3设定连接池中存放连接的数目
	public void setMaxConns(int numConnections) throws Exception;
	
	//4从连接池中获取连接
	public Connection getConnection() throws SQLException;
	
	//5将连接返回给连接池
	public void returnConnection() throws SQLException;
	
	//6销毁连接池
	public void destroyConnPool() throws SQLException;
}

享元实现类:数据库连接池实现类

public class DbConnectionPoolImp implements DbConnectionPool {
    private String DB_DRIVER="com.mysql.jdbc.Driver";
    private String DB_USER="root";
    private String DB_PASSWORD="";
    private String DATASRC_URL="jdbc:mysql";
    final static int defaultMaxConnection=10;
    private List freeConnections;
    private Map busyConnections;
    private int maxConnection;
    
    //构造函数1
    public DbConnectionPoolImp(int numConnections){
    	maxConnection=numConnections;
    	freeConnections=null;
    	busyConnections=null;
    }
    public DbConnectionPoolImp(){
    	maxConnection=defaultMaxConnection;
    	freeConnections=null;
    	busyConnections=null;
    }
    //构造函数2
	public void initConnPool() throws SQLException {
		try {
            freeConnections=new ArrayList(maxConnection);
            busyConnections=new HashMap(maxConnection);
            //创建连接
            Class.forName(DB_DRIVER);
            for(int i=0;i<maxConnection;i++){
            	Connection connection = 
            			DriverManager.getConnection(DATASRC_URL, DB_USER, DB_PASSWORD);
            	freeConnections.add(connection);
            }
            
		} catch (Exception e) {
			//如果有异常,说明初始化任务失败!一定要将所有连接置空!
			freeConnections=null;
			busyConnections=null;
			throw new SQLException(e);
		}
	}
    //设置连接池开关
	public void setConnWitch(String onOrOff) throws SQLException {
		try {
			if("ON".equalsIgnoreCase(onOrOff)){
				initConnPool();
			}else if("OFF".equalsIgnoreCase(onOrOff)){
			    destroyConnPool();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	//设置连接池最大连接数
	public void setMaxConns(int numConnections) throws  Exception{
		if(numConnections<=0){
			throw new Exception("你传进来的大小有问题!亲!");
		}
		maxConnection=numConnections;
	}
    //从连接池中得到连接!
	public synchronized Connection getConnection() throws SQLException {
		
		if (freeConnections == null)
			throw new SQLException("连接池还没有被创立");
	    try {		
	    	if(freeConnections.size()==0)
	    	   wait();
		} catch (Exception e) {
			e.printStackTrace();
		}
	    //作者:获取空闲连接池
	    Connection conn=(Connection) freeConnections.get(0);
	    freeConnections.remove(0);
	    busyConnections.put(Thread.currentThread(), conn);
		return conn;
		
	}

	//将空闲的连接返回到List freeConnections,方便管理
	public synchronized void returnConnection() throws SQLException {
        Connection conn=(Connection) busyConnections.get(Thread.currentThread());
        if(conn==null){
        	throw new SQLException("没有发现繁忙池中有连接");
        }
        busyConnections.remove(Thread.currentThread());
        //讲已经返回的连接重新放回空闲池中
        freeConnections.add(conn);
        notify();
	}
	
	//销毁连接池
	public void destroyConnPool() throws SQLException {
           if(busyConnections!=null){
        	   Set set=busyConnections.entrySet();
        	   Iterator iterator =set.iterator();
        	   while(iterator.hasNext()){
        		  Map.Entry entry=(Entry) iterator.next();
        		  Connection conn=(Connection) entry.getValue();
        		  conn.close();
        	   }
        	   //最后千万记得弄他为空!
        	   busyConnections=null;
           }
           if(freeConnections!=null){
        	  for (int i = 0; i < freeConnections.size(); i++) {
				Connection conn=(Connection) freeConnections.get(i);
				conn.close();
			  }
        	  freeConnections=null;
           }
	}
}

享元工厂类:对数据库连接池管理

public class DbConnectionManager {
    private static DbConnectionManager instance = new DbConnectionManager();
    
    //存放所有的连接池,其中有mysql连接池,oracle连接池,sql server连接池等等!
    private static Map connPool=new HashMap();
    
    //返回唯一的实例
    public static synchronized  DbConnectionManager getInstance(){
    	return instance;
    }
    //防止其他对象创建
    private DbConnectionManager(){}
    
    
    //初始化连接池管理器
    public void init(int nunberMax) throws Exception{
    	createPools(nunberMax);
    }
    
    /*
     * 根据名称从Map中获取连接!!!注意,不是获取连接池
     */
    public Connection getConnection(String name){
    	Connection conn=null;
        try {
			DbConnectionPool pool = (DbConnectionPool) connPool.get(name);
			if(pool!=null){
				conn=pool.getConnection();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}    		
        return conn;
    }
    //将连接返回给连接池
    /**
     * 这个方法明显有问题!传入的参数conn根本用不到
     * @param name 连接池名字
     * @param conn 连接
     */
    public static void returnConnection(String name,Connection conn){
    	try {
			DbConnectionPool pool=(DbConnectionPool) connPool.get(name);
			if(pool!=null){
				pool.returnConnection();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    
    
    //关闭所有连接
    public static void release(){
    	try {
			Set set=connPool.entrySet();
			Iterator iterator =set.iterator();
			
			//遍历所有的连接池!
			while(iterator.hasNext()){
				Map.Entry entry=(Entry) iterator.next();
				DbConnectionPool pool=(DbConnectionPool) entry.getValue();
				//关闭连接池
				pool.setConnWitch("OFF");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    
    //创建连接池
    public static void  createPools(int numberMax) throws Exception{
    	DbConnectionPool pool=new DbConnectionPoolImp();
    	pool.setMaxConns(numberMax);
    	try {
    		//表示创建连接池
			pool.setConnWitch("on");
			//将创建后的连接池放在Map中,进行统一的管理
			connPool.put("mysql",pool);
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
     
}
成事在人,某事在天,大家加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值