MVC+RMI=同步刷新的人员管理系统

一个简单的人员管理系统,采用MVC架构以及java分布式。

视图以及控制层在客户端,模型层位于服务端。

实现功能如图





当多用户在浏览同一视图时其中任何一个人对于人员数据的修改都会导致其他用户的同一视图的同步刷新。

这一功能的实现是通过模型层调用视图层的刷新方法实现的。

系统代码如下

视图层:

package store;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface StoreView extends Remote
{
	/**注册处理用户动作的监听器*/
	public void addUserGestureListener(StoreController ctrl)throws StoreException,RemoteException;
	/**在图形界面上显示数据,参数display指定显示的数据*/
	public void showDisplay(Object display)throws StoreException,RemoteException;
	/**当模型层修改了数据库中某个人员信息时同步刷新视图层的图形界面 */
	public void handleCustomerChange(Customer cust)throws StoreException,RemoteException;
}

为了能够被模型层访问,视图层接口为远程接口。

package store;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Set;

public class StoreViewImpl extends UnicastRemoteObject implements StoreView,Serializable
{
	private transient StoreGui gui;
	private StoreModel storeModel;
	private Object display;
	private ArrayList<StoreController> storeControllers=new ArrayList<StoreController>(10);
	protected StoreViewImpl(StoreModel model) throws RemoteException 
	{
		super();
		try{
			this.storeModel=model;
			model.addChangeListener(this);
		}catch(Exception e)
		{
			System.out.println("StoreViewImpl constructor "+e);
		}
		gui=new StoreGui();
		gui.setVisible(true);
		gui.addSelectionPanelListener(selectionPanelListeners);
		gui.addCustPanelListener(custPanelListeners);
	}
	//监听图形界面上查询人员按钮
	transient ActionListener custGetHandler=new ActionListener()
	{

		public void actionPerformed(ActionEvent e)
		{
			StoreController sc;
			long custId;
			custId=gui.getCustIdOnCustPanel();
			for(int i=0;i<storeControllers.size();i++)
			{
				sc=storeControllers.get(i);
				sc.handleGetCustomer(custId);
			}
			
		}
		
	};
	//监听图形界面上添加人员按钮
	transient ActionListener custAddHandler=new ActionListener()
	{

		
		public void actionPerformed(ActionEvent e)
		{
			StoreController sc;
			for(int i=0;i<storeControllers.size();i++)
			{
				sc=storeControllers.get(i);
				sc.handleAddCustomerGesture(gui.getCustomerOnCustPanel());
			}
			
			
		}
		
	};
	//监听图形界面上删除人员按钮
	transient ActionListener custDeleteHandler=new ActionListener()
	{

		
		public void actionPerformed(ActionEvent e)
		{
			StoreController sc;
			for(int i=0;i<storeControllers.size();i++)
			{
				sc=storeControllers.get(i);
				sc.handleDeleteCustomerGesture(gui.getCustomerOnCustPanel());
			}
			
		}
		
	};
	//监听图形界面上更新人员按钮
		transient ActionListener custUpdateHandler=new ActionListener()
		{

			
			public void actionPerformed(ActionEvent e)
			{
				StoreController sc;
				for(int i=0;i<storeControllers.size();i++)
				{
					sc=storeControllers.get(i);
					sc.handleUpdateCustomerGesture(gui.getCustomerOnCustPanel());
				}
				
			}
			
		};
	//监听图形界面上人员详情信息按钮
	transient ActionListener custDetailsPageHandler=new ActionListener()
	{
		public void actionPerformed(ActionEvent e) 
		{
			StoreController sc;
			long custId;
			custId=gui.getCustIdOnCustPanel();
			if(custId==-1)
			{
				try{
					showDisplay(new Customer(-1));
				}catch(Exception e1)
				{
					e1.printStackTrace();
				}
			}
			else
			{
				for(int i=0;i<storeControllers.size();i++)
				{
					sc=storeControllers.get(i);
					sc.handleGetCustomer(custId);
				}
			}
			
		}
		
	};
	//监听图形界面上所有人员清单按钮
	transient ActionListener allCustsPageHandler=new ActionListener()
	{

		public void actionPerformed(ActionEvent e) 
		{
			StoreController sc;
			sc=storeControllers.get(0);
			sc.handleGetAllCustomer();
			
		}
		
	};
	//存储监听器
	transient ActionListener[] custPanelListeners={custGetHandler,custAddHandler,custDeleteHandler,custUpdateHandler};
	transient ActionListener[] selectionPanelListeners={custDetailsPageHandler,allCustsPageHandler};
	//注册控制器
	public void addUserGestureListener(StoreController ctrl)
			throws StoreException, RemoteException {
		
		storeControllers.add(ctrl);
	}

	//在图形界面上展示参数display指定的数据
	public void showDisplay(Object display) throws StoreException,
			RemoteException {
		
		if(!(display instanceof Exception))
		{
			this.display=display;
		}
		if(display instanceof Customer)
		{
			gui.refreshCustPanel((Customer)display);
		}
		if(display instanceof Set)
		{
			gui.refreshAllCustPanel((Set<Customer>)display);
		}
		if(display instanceof Exception)
		{
			gui.updateLog(((Exception)display).getMessage());
		}
	}

	/**刷新界面的人员信息*/
	public void handleCustomerChange(Customer cust) throws StoreException,
			RemoteException {
		long custIdOnPanel=-1;
		try{
			if(display instanceof Set)
			{
				gui.refreshAllCustPanel(storeModel.getAllCustomer());
				return;
			}
			if(display instanceof Customer)
			{
				custIdOnPanel=gui.getCustIdOnCustPanel();
				if(custIdOnPanel!=cust.getId())//只同步刷新在查询相同人员信息的视图
				{
					return;
					
				}
				gui.refreshCustPanel(cust);
			}
		}catch(Exception e)
		{
			System.out.println("StoreViewImpl processCustomer "+e);
		}
		
	}

}

Storeview的具体实现类StoreViewImpl


控制层接口以及具体实现如下

package store;

public interface StoreController 
{
	/**处理根据ID查询人员的动作*/
	public void handleGetCustomer(long id);
	/**处理添加人员的动作*/
	public void handleAddCustomerGesture(Customer cust);
	/**处理删除人员的动作*/
	public void handleDeleteCustomerGesture(Customer cust);
	/**处理更新人员的动作*/
	public void handleUpdateCustomerGesture(Customer cust);
	/**处理列出所有人员的动作*/
	public void handleGetAllCustomer();
}


package store;

import java.util.Set;

public class StoreControllerImpl implements StoreController
{
	private StoreModel storeModel;
	private StoreView storeView;
	public StoreControllerImpl(StoreModel model,StoreView view)
	{
		try{
			storeModel=model;
			storeView=view;
			view.addUserGestureListener(this);
		}catch(Exception e)
		{
			reportException(e);
		}
	}
	//报告异常信息
	private void reportException(Object o)
	{
		try{
			storeView.showDisplay(o);
		}catch(Exception e)
		{
			System.out.println("StoreControllerImpl reportException "+e);
		}
	}
	//处理根据ID查询人员的动作
	public void handleGetCustomer(long id) 
	{
		Customer cust=null;
		try{
			cust=storeModel.getCustomr(id);//调用StoreModel对象去数据库获取指定ID的人员数据
			storeView.showDisplay(cust);//通过StoreView显示数据
		}catch(Exception e)
		{
			reportException(e);
			cust=new Customer(id);
			try{
				storeView.showDisplay(cust);
			}catch(Exception ex)
			{
				reportException(ex);
			}
		}
		
	}

	//处理添加人员的动作
	public void handleAddCustomerGesture(Customer cust) 
	{
		try{
			storeModel.addCustomer(cust);
		}catch(Exception e)
		{
			reportException(e);
		}
		
	}

	//处理删除人员的动作
	public void handleDeleteCustomerGesture(Customer cust)
	{

		try{
			storeModel.deleteCustomer(cust);
		}catch(Exception e)
		{
			reportException(e);
		}
	}

	//处理更新人员的动作
	public void handleUpdateCustomerGesture(Customer cust) 
	{
		

		try{
			storeModel.updateCustomer(cust);
		}catch(Exception e)
		{
			reportException(e);
		}
	}

	
	public void handleGetAllCustomer()
	{
		Set<Customer> customers=null;
		try{
			customers=storeModel.getAllCustomer();//通过StoreModel对象获得所有人员信息
			storeView.showDisplay(customers);//通过StoreView显示数据
		}catch(Exception e)
		{
			reportException(e);
		}
		
	}

}


StoreGui

package store;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;

public class StoreGui extends JFrame
{
	/**CardLayout 对象是容器的布局管理器。
	 * 它将容器中的每个组件看作一张卡片。
	 * 一次只能看到一张卡片,容器则充当卡片的堆栈。
	 * 当容器第一次显示时,第一个添加到 CardLayout 对象的组件为可见组件。
	 * */
	private CardLayout card=new CardLayout();
	private JPanel carPanel=new JPanel();
	//包含各种按钮的选择面板上的组件
	private JPanel selPanel=new JPanel();
	private JButton custBt=new JButton("人员详细信息");
	private JButton allCustBt=new JButton("所有人员清单");
	
	//显示单个人员面板的组件
	private JPanel custPanel=new JPanel();
	private JLabel nameLb=new JLabel("姓名");
	private JLabel idLb=new JLabel("ID");
	private JLabel addrLb=new JLabel("地址");
	private JLabel ageLb=new JLabel("年龄");
	
	private JTextField nameTf=new JTextField(25);
	private JTextField idTf=new JTextField(25);
	private JTextField addrTf=new JTextField(25);
	private JTextField ageTf=new JTextField(25);
	private JButton getBt=new JButton("查询人员");
	private JButton upBt=new JButton("更新人员");
	private JButton addBt=new JButton("添加人员");
	private JButton delBt=new JButton("删除人员");
	
	//列举所有人员的面板的组件
	private JPanel allCustPanel=new JPanel();
	private JLabel allCustLb=new JLabel("所有人员清单",SwingConstants.CENTER);//居中显示
	private JTextArea allCustTa=new JTextArea();
	private JScrollPane allCustSp=new JScrollPane(allCustTa);
	
	//table头
	String[]tableHeaders={"ID","姓名","地址","年龄"};
	JTable table;
	JScrollPane tablePane;
	DefaultTableModel tableModel;
	
	//日志面板上的组件
	private JPanel logPanel=new JPanel();
	private JLabel logLb=new JLabel("操作日志",SwingConstants.CENTER);
	private JTextArea logTa=new JTextArea(9,50);
	private JScrollPane logSp=new JScrollPane(logTa);
	
	public StoreGui()
	{
		buildDisplay();
	}
	public void refreshCustPanel(Customer cust)
	{
		showCard("Customer");
		if(cust==null||cust.getId()==-1)
		{
			idTf.setText(null);
			nameTf.setText(null);
			addrTf.setText(null);
			ageTf.setText(null);
			return;
		}
		else
		{
			idTf.setText(Long.toString(cust.getId()));
			nameTf.setText(cust.getName());
			addrTf.setText(cust.getAddr());
			ageTf.setText(Integer.toString(cust.getAge()));
		}
		
	}
	public void refreshAllCustPanel(Set<Customer> custs)
	{
		showCard("All customers");
		String newData[][]=new String[custs.size()][4];
		Iterator<Customer> iter=custs.iterator();
		int i=0;
		while(iter.hasNext())
		{
			Customer cust=iter.next();
			newData[i][0]=Long.toString(cust.getId());
			newData[i][1]=cust.getName();
			newData[i][2]=cust.getAddr();
			newData[i][3]=Integer.toString(cust.getAge());
			i++;
		}
		tableModel.setDataVector(newData, tableHeaders);
	}
	//在日志面板中添加日志信息
	public void updateLog(String msg)
	{
		logTa.append(msg+"\n");
	}
	public long getCustIdOnCustPanel()
	{
		try
		{
			return Long.parseLong(idTf.getText().trim());
	
		}catch(Exception e)
		{
			updateLog(e.getMessage());
			return -1;
		}
	}
	//获得单个人员面板上用户输入的人员信息
	public Customer getCustomerOnCustPanel()
	{
		try
		{
			String custid=idTf.getText().trim();
			Long cid=custid.equals("")?0:Long.parseLong(custid);
			return new Customer(cid,
								nameTf.getText().trim(),
								addrTf.getText().trim(),
								Integer.parseInt(ageTf.getText().trim()));
		}catch(Exception e)
		{
			updateLog(e.getMessage());
			return null;
		}
	}
	private void showCard(String cardStr)
	{
		card.show(carPanel, cardStr);
	}
	/** 为选择面板中的两个按钮注册监听器*/
	public void addSelectionPanelListener(ActionListener a[])
	{
		int length=a.length;
		if(length!=2)
		{
			return;
		}
		else
		{
			custBt.addActionListener(a[0]);
			allCustBt.addActionListener(a[1]);
		}
	}
	/** 为单个人员面板中的两个按钮注册监听器*/
	public void addCustPanelListener(ActionListener a[])
	{
		int length=a.length;
		if(length!=4)
		{
			return;
		}
		else
		{
			getBt.addActionListener(a[0]);
			addBt.addActionListener(a[1]);
			delBt.addActionListener(a[2]);
			upBt.addActionListener(a[3]);
		}
			
	}
	public static void main(String[]args)
	{
		new StoreGui().setVisible(true);;
		
	}
	//创建图形界面
	private void buildDisplay()
	{
		setTitle("人员管理系统");
		buildSelectionPanel();
		buildCustPanel();
		buildAllCustPanel();
		buildLogPanel();
		
		/**carPanel采用cardLayout布局管理器
		 * 包括custPanel和allCustPanel两种卡片
		 * */
		carPanel.setLayout(card);
		carPanel.add(custPanel,"Customer");
		carPanel.add(allCustPanel,"All customers");
		this.setLayout(new BorderLayout());
		add(carPanel,BorderLayout.CENTER);
		add(selPanel,BorderLayout.NORTH);
		add(logPanel,BorderLayout.SOUTH);
		this.pack();
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}
	private void buildLogPanel()
	{
		logPanel.setLayout(new BorderLayout());
		logSp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		logSp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		logPanel.add(logLb,BorderLayout.NORTH);
		this.logPanel.add(logSp,BorderLayout.CENTER);
	}
	private void buildSelectionPanel()
	{
		selPanel.add(custBt);
		selPanel.add(allCustBt);
	}
	//创建单个人员面板
	private void buildCustPanel()
	{
		custPanel.setLayout(new GridLayout(6,2,2,2));
		custPanel.add(idLb);
		custPanel.add(idTf);
		custPanel.add(nameLb);
		custPanel.add(nameTf);
		custPanel.add(addrLb);
		custPanel.add(addrTf);
		custPanel.add(ageLb);
		custPanel.add(ageTf);
		custPanel.add(getBt);
		custPanel.add(upBt);
		custPanel.add(addBt);
		custPanel.add(delBt);
	}
	//创建所有人员面板
	private void buildAllCustPanel()
	{
		allCustPanel.setLayout(new BorderLayout());
		allCustPanel.add(allCustLb,BorderLayout.NORTH);
		allCustTa.setText("all customer display");
		tableModel=new DefaultTableModel(tableHeaders,10);
		table=new JTable(tableModel);
		tablePane=new JScrollPane(table);
		allCustPanel.add(tablePane,BorderLayout.CENTER);
		Dimension dim=new Dimension(500,150);
		table.setPreferredScrollableViewportSize(dim);
	}
}


客户端程序入口

package store;

import java.rmi.RemoteException;

import javax.naming.Context;
import javax.naming.InitialContext;

public class StoreApp 
{
	public static void main(String[]args) throws RemoteException, StoreException
	{
		String url="rmi://localhost/";
		try{
			StoreModel model;
			StoreView view;
			StoreController ctrl;
			Context namingContext=new InitialContext();
			model=(StoreModel)namingContext.lookup(url+"storeModel");
			view=new StoreViewImpl(model);
			ctrl=new StoreControllerImpl(model,view);
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}


人员POJO

package store;

import java.io.Serializable;

public class Customer implements Serializable
{
	private long id;
	private String name="";
	private String addr="";
	private int age;
	public Customer(long id,String name,String addr,int age)
	{
		this.id=id;
		this.name=name;
		this.addr=addr;
		this.age=age;
	}
	public Customer(long id)
	{
		this.id=id;
	}
	public long getId()
	{
		return id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name) 
	{
		this.name = name;
	}
	public String getAddr()
	{
		return addr;
	}
	public void setAddr(String addr)
	{
		this.addr = addr;
	}
	public int getAge()
	{
		return age;
	}
	public void setAge(int age) 
	{
		this.age = age;
	}
	public String toString()
	{
		return "Customer: "+id+" "+name+" "+addr+" "+age;
	}
}


模型层接口以及具体实现

package store;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Set;

public interface StoreModel extends Remote
{
	/**注册视图,以便当模型修改了数据库中的人员信息时可以回调视图的刷新界面方法*/
	public void addChangeListener(StoreView sv)throws StoreException,RemoteException;
	/**向数据库中添加一个新的人员*/
	public void addCustomer(Customer cust)throws StoreException,RemoteException;
	/**向数据库中删除一个新的人员*/
	public void deleteCustomer(Customer cust)throws StoreException,RemoteException;
	/**更新数据库中的人员*/
	public void updateCustomer(Customer cust)throws StoreException,RemoteException;
	/**根据参数ID检索*/
	public Customer getCustomr(long id)throws StoreException,RemoteException;
	/**返回所有人员*/
	public Set<Customer> getAllCustomer()throws StoreException,RemoteException;
}


package store;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class StoreModelImpl extends UnicastRemoteObject implements StoreModel
{
	private ArrayList<StoreView> changeListeners=new ArrayList<StoreView>(10);
	private DBService dbService;
	
	protected StoreModelImpl() throws RemoteException,StoreException 
	{
		super();
		try{
			dbService=new DBServiceImpl();
		}catch(Exception e)
		{
			throw new StoreException("数据库异常");
		}
	}
	/**判断数据库中是否存在参数指定的人员ID*/
	protected boolean idExists(long id)
	{
		Statement stmt=null;
		try{
			stmt=dbService.getStatement();
			ResultSet result=stmt.executeQuery("select ID from customers where ID="+id);
			return result.next();
		}catch(Exception e)
		{
			return false;
		}finally
		{
			dbService.closeStatement(stmt);
		}
	}
	/**注册视图,以便当模型修改了数据库中的人员信息时可以回调视图的刷新界面的方法*/
	public void addChangeListener(StoreView sv) throws StoreException,
			RemoteException {
		
		changeListeners.add(sv);
	}

	/**当数据库中人员信息发生变化时,同步刷新所有视图*/
	private void fireModelChangeEvent(Customer cust)
	{
		StoreView v;
		for(int i=0;i<changeListeners.size();i++)
		{
			try{
				v=changeListeners.get(i);
				v.handleCustomerChange(cust);
			}catch(Exception e)
			{
				System.out.println(e.toString());
			}
		}
	}
	//向数据库中添加一个新的人员
	public void addCustomer(Customer cust) throws StoreException,
			RemoteException {
		try {
			String sql="insert into customers values(0,'"+cust.getName()+"',"+cust.getAge()+",'"+cust.getAddr()+"')";
			dbService.modifyTable(sql);
			fireModelChangeEvent(cust);
			
		} catch (Exception e)
		{
			throw new StoreException("StoreModelImpl.addCustomer\n"+e);
		}
	}

	//向数据库中删除一个新的人员
	public void deleteCustomer(Customer cust) throws StoreException,
			RemoteException {
		
		try {
			String sql="delete from customers where id="+cust.getId();
			dbService.modifyTable(sql);
			fireModelChangeEvent(new Customer(cust.getId()));
			
		} catch (Exception e)
		{
			throw new StoreException("StoreModelImpl.deleteCustomer\n"+e);
		}
		
	}

	//向数据库中更新一个新的人员
	public void updateCustomer(Customer cust) throws StoreException,
			RemoteException {
		try{
			if(!idExists(cust.getId()))
			{
				throw new StoreException("Customer "+cust.getId()+"Not Found");
			}
			
			String sql="update customers set "
						+"name='"+cust.getName()+
						"',age="+cust.getAge()+
						",address='"+cust.getAddr()+
						"'where id="+cust.getId();
			dbService.modifyTable(sql);
			fireModelChangeEvent(cust);//同步刷新所有视图
		}catch(Exception e)
		{
			throw new StoreException("StoreModelImpl.updateCustomer\n"+e);
		}
		
	}

	/**根据ID检索人员*/
	public Customer getCustomr(long id) throws StoreException, RemoteException {
		Statement stmt=null;
				try{
					if(!idExists(id))
					{
						throw new StoreException("Customer "+id+"Not Found");
					}
					stmt=dbService.getStatement();
					ResultSet rs=stmt.executeQuery("select id,name,address,age from customers where id="+id);
					rs.next();
					return new Customer(rs.getLong(1),rs.getString(2),rs.getString(3),rs.getInt(4));
				}catch(Exception e)
				{
					throw new StoreException("StoreDbImpl.getCustomer\n"+e);
				}finally
				{
					dbService.closeStatement(stmt);
				}
	}

	
	public Set<Customer> getAllCustomer() throws StoreException,
			RemoteException {
		Statement stmt=null;
		try{
			stmt=dbService.getStatement();
			ResultSet rs=stmt.executeQuery("select id,name,address,age from customers");
			Set<Customer> custSet=new HashSet<Customer>();
			Customer cust;
			while(rs.next())
			{
				cust=new Customer(rs.getLong(1),rs.getString(2),rs.getString(3),rs.getInt(4));
				custSet.add(cust);
			}
			return custSet;
		}catch(Exception e)
		{
			throw new StoreException("StoreDbImpl.getAllCustomer\n"+e);
		}finally
		{
			dbService.closeStatement(stmt);
		}
	}

}

服务端程序入口

package store;

import java.rmi.RMISecurityManager;
import javax.naming.Context;
import javax.naming.InitialContext;
public class StoreServer 
{
	public static void main(String[]args)
	{
		try
		{
			//System.setProperty("java.security.policy",StoreServer.class.getResource("client.policy").toString());
			//System.setSecurityManager(new RMISecurityManager());
			StoreModel storeModel=new StoreModelImpl();		
			Context namingContext=new InitialContext();
			
			namingContext.rebind("rmi://localhost:1099/storeModel",storeModel);
			System.out.println("注册了1个对象");
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}


模型层使用的数据库连接池

package store;

import java.sql.Connection;
import java.sql.SQLException;

public interface ConnectionPool
{
	/**
	 * 连接池接口,其中声明了取出连接、释放链接和关闭连接的方法*/
	/**从连接池中取出连接*/
	public Connection getConnection()throws SQLException;
	/**把连接放回连接池*/
	public void releaseConnection(Connection con)throws SQLException;
	/**关闭连接池*/
	public void close();
}


通过动态代理实现ConnectionPool

package store;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

public class ConnectionPoolImpl implements ConnectionPool{

	private ConnectionProvider provider=new ConnectionProvider();
	private final ArrayList<Connection> pool=new ArrayList<Connection>();
	private int poolSize=10;
	
	public ConnectionPoolImpl(){}
	public ConnectionPoolImpl(int poolSize)
	{
		this.poolSize=poolSize;
	}
	/**从连接池中取出连接*/
	public Connection getConnection() throws SQLException 
	{
		synchronized(pool)//采用同步锁控制连接池
		{
			if(!pool.isEmpty())
			{
				int last=pool.size()-1;
				Connection con=pool.remove(last);
				return con;
			}
		}
		Connection con=provider.getConnection();
		return getProxy(con,this);
	}
	

	/**把连接放回连接池*/
	public void releaseConnection(Connection con) throws SQLException {
		synchronized(pool)
		{
			int currSize=pool.size();
			if(currSize<poolSize)
			{
				pool.add(con);
				//System.out.println(con.getClass().getName());
				return;
			}
			
		}
		try{
			closeJdbcConnection(con);
		}catch(Exception e)
		{
			e.printStackTrace();
		}

	}
	private void closeJdbcConnection(Connection con)throws SQLException{
		ConnectionP conP=(ConnectionP)con;
		conP.getJdbcConnection().close();
	}
	protected void finalize()//垃圾回收时可能会调用
	{
		close();
	}
	/**关闭连接池*/
	public void close()
	{
		Iterator<Connection> iter=pool.iterator();
		while(iter.hasNext())
		{
			try{
				closeJdbcConnection(iter.next());//关闭真正的数据库连接
			}catch(SQLException e)
			{
				e.printStackTrace();
			}
		}
		pool.clear();
	}
	/**返回动态连接代理*/
	private Connection getProxy(final Connection con,final ConnectionPool pool)
	{
		InvocationHandler handle=new InvocationHandler()
		{

			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				if(method.getName().equals("close"))
				{
					//System.out.println("代理类"+proxy.getClass().getName()+"调用releaseConnection()");
					pool.releaseConnection((Connection)proxy);
					return null;
				}
				else if(method.getName().equals("getJdbcConnection"))
				{
					return con;
				}
				else
				{
					return method.invoke(con, args);
				}
			}
			
		};
		return (Connection)Proxy.newProxyInstance(ConnectionP.class.getClassLoader(),new Class[]{ConnectionP.class},handle);
	}
	interface ConnectionP extends Connection
	{
		public Connection getJdbcConnection();//返回被代理的Connection对象
	}

}


获取数据库连接配置信息的类

package store;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionProvider
{
	private String JDBC_DRIVER;
	private String DB_URL;
	private String DB_USER;
	private String DB_PASSWORD;
	public ConnectionProvider()
	{
		this.JDBC_DRIVER=PropertyReader.get("JDBC_DRIVER");
		this.DB_URL=PropertyReader.get("DB_URL");
		this.DB_USER=PropertyReader.get("DB_USER");
		this.DB_PASSWORD=PropertyReader.get("DB_PASSWORD");
		try
		{
			Class.forName(JDBC_DRIVER);
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	public Connection getConnection() throws SQLException
	{
		return DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
	}
}


加载db.conf配置文件

package store;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropertyReader 
{
	private static Properties ps;
	static
	{
		ps=new Properties();
		InputStream in=PropertyReader.class.getResourceAsStream("db.conf");
		try 
		{
			ps.load(in);
			in.close();
		} catch (IOException e) 
		{
			
			e.printStackTrace();
		}
		
		
	}
	public static String get(String key)
	{
		return (String)ps.get(key);
	}
}


最后效果图:




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值