数据库连接池代理实现并优化

优化代码

通过类加载器读取一个资源文件:
SomeClass.class.getReesource(xxx) – 获取与SomeCalss字节码同一个目录下的xxx文件。
SomeClass.class.getClassLoader().getResource(“xxxx”); - 获取classpath根下上的xxx文件。
1:将url,driver,name,pwd写到一个配置文件中去。-properties
2:通过LinkedList来维护一个池。


配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db909?useUnicode=true&characterEncoding=UTF8
name=root
pwd=1234
poolSize=3

此处注意 jdbc.properties字符串的空格也算数  一定要注意
public class ConnUtils3 {
	private static LinkedList<Connection> pool = new LinkedList<Connection>();
	static {
		try {
			// 声明资源器类 - 
			Properties prop = new Properties();
			// 获取这个文件的路径
			URL url = ConnUtils3.class.getClassLoader().getResource(
					"jdbc.properties");
			// ConnUtils3.class.getResource("jdbc.properties")获取的是同目录下
			String path = url.getPath();// 运行是路径
			// 为了防止有中文或是空格
			path = URLDecoder.decode(path, "UTf-8");// 反向将url编码过的路径转换回来
			File file = new File(path);
			// 加载jdbc.properties这个文件
			prop.load(new FileInputStream(file));
			// 获取信息
			String driver = prop.getProperty("driver");
			Class.forName(driver);
			String jdbcurl = prop.getProperty("url");
			String nm = prop.getProperty("name");
			String pwd = prop.getProperty("pwd");
			// 创建三个原生的连接,都将它们代理
			String poolSize = prop.getProperty("poolSize");
			int size = Integer.parseInt(poolSize);
			for (int i = 0; i < size; i++) {
				final Connection con = DriverManager.getConnection(jdbcurl, nm,
						pwd);
				// 对con进行动态代理
				Object proxyedObj = Proxy.newProxyInstance(
						ConnUtils3.class.getClassLoader(),
						new Class[] { Connection.class },
						new InvocationHandler() {
							public Object invoke(Object proxy, Method method,
									Object[] args) throws Throwable {
								// 是否是close方法
								if (method.getName().equals("close")) {
									synchronized (pool) {
										pool.addLast((Connection) proxy);//链接往最后放速度最快
										pool.notify();
									}
									return null;// 如果调用的是close则不会调用被代理类的方法。
								}
								return method.invoke(con, args);
							}
						});
				// 将代理对象放到pool中
				pool.add((Connection) proxyedObj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static Connection getConn() {
		synchronized (pool) {
			if (pool.size() == 0) {
				try {
					pool.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return getConn();//线程唤醒之后递归继续取链接
			} else {
				Connection con = pool.removeFirst();//取出第一个速度快
				System.err.println("还有几个:" + pool.size());
				return con;
			}
		}
	}

}

再说连接池的作用

1:维护多个连接。
在初始化时创建List,将多个连接放到List中去.
2:可以在close时回收连接
对Connection进行动态代理,
对close方法进行拦截。

项目练习(联系人管理小系统)

1:需要分析

 用户可以注册
用户登录功能。
用户登录以后可以显示自己的联系人。
对自己的联系人可以CRUD。

需要分析-设计――编码-测试

 

 第一步:设计数据结构
    抽象出系统中对象
  用户 - 领域模型 - (Java Bean与表有一一对应的关系)
Users表:
Id  vc(32)
Name
pwd


联系人
Id
Name
Sex
Ttel
Addr
Uid – 属于哪一个用户






第二步:创建两个Bean

Cn.itcast.domain
User
Contact


第三步:分包

Cn.itcast.user - 只做与Usre类相关的CURD,注册,密码修改,登录,退出
UserServlet
Serivce
UserServide
Dao
userDao

cn.itcast.contact - CURD
ContactSevlet
Serivce
ContactSevice
Dao
ContactDao


第四步:工具类

生成UUID的工具类
连接数据库的工具类
请求分发的工具类.
/**
 * 分发的基类
 * @author Administrator
 */
public abstract class BaseServlet extends HttpServlet {
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}
	//http://server:port/project/someServlet?cmd=someMethod
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		//设置编码
		req.setCharacterEncoding("UTf-8");
		//获取参数
		String methodName = req.getParameter("cmd");
		if(methodName==null || methodName.trim().equals("")){
			methodName="execute";//默认方法
		}
		//通过反射调用子类的方法
		try{
			Method method = this.getClass()
						.getMethod(methodName,
						HttpServletRequest.class,HttpServletResponse.class);
			method.invoke(this,req,resp);
		}catch(Exception e){
			throw new RuntimeException(e.getMessage(),e);
		}
	}
	//要求子类必须要拥有exexute方法
	public abstract void execute(HttpServletRequest req,HttpServletResponse resp) throws Exception;
}

public class OneServlet extends BaseServlet {

	@Override
	public void execute(HttpServletRequest req, HttpServletResponse resp)
			throws Exception {
		System.err.println("这是默认的方法。。。。。");
	}
	public void login(HttpServletRequest req, HttpServletResponse resp)
			throws Exception {
		System.err.println("这是login。。。。。");
	}
	public void exit(HttpServletRequest req, HttpServletResponse resp)
			throws Exception {
		System.err.println("这是exit。。。。。");
	}

}





第五步:手工的写入一部分数据



第六步:实现用户登录功能

Cn.itcast.user - 
UserServlet0书写一个login方法
Serivce
UserServide
Dao
userDao
登录

第七步:创建联系人包结构

cn.itcast.contact - CURD
ContactSevlet
Serivce
ContactSevice
Dao
ContactDao



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值