实现javax.sql.DataSource接口

实现Connection getConnection()方法

定义一个静态的成员属性LinkedList类型作为连接池,在静态代码块中初始化5条数据库连接,添加到连接池中,在getConnection方法中,当获取连接的时候在连接池中remove掉一条连接就可以了

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement; public class JDBCTest {
public static void main(String[] args) throws Exception {
//使用反射的方式
Class.forName("com.mysql.jdbc.Driver");
//获取数据库连接,导包的时候,注意要导java.sql下的,面向接口编程
MyPool pool=new MyPool();
Connection conn=pool.getConnection();
//获取传输器对象
Statement statement=conn.createStatement();
//获取结果集对象
ResultSet resultSet=statement.executeQuery("select * from user");
//遍历
while(resultSet.next()){
String username=resultSet.getString("username");
System.out.println(username);
}
//关闭资源
resultSet.close();
statement.close();
pool.resetConn(conn); }
}

我的连接池

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger; import javax.sql.DataSource; /**
* 手写连接池
*
* @author taoshihan
*
*/
public class MyPool implements DataSource {
// 连接池
public static List<Connection> pool = new LinkedList<Connection>();
// 初始化
static {
try {
Class.forName("com.mysql.jdbc.Driver");
for (int i = 0; i < 5; i++) {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/java", "root", "root");
pool.add(conn);
}
} catch (Exception e) {
}
} /**
* 获取连接
*/
@Override
public Connection getConnection() throws SQLException {
// 如果池中没有连接
if (pool.size() == 0) {
for (int i = 0; i < 5; i++) {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/java", "root", "root");
pool.add(conn);
}
}
//先进先出
Connection conn=pool.remove(0);
System.out.println("获取一个连接,池里还剩余"+pool.size());
return conn;
}
/**
* 重置连接
*/
public void resetConn(Connection conn){
try {
if(conn!=null && !conn.isClosed()){
pool.add(conn);
System.out.println("还回一个连接,池里还剩余"+pool.size());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Connection getConnection(String username, String password)
throws SQLException {
return null;
} @Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub } @Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub } @Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
} @Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
} @Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
} }

使用继承,装饰,动态代理改造一个类中的方法

继承的缺点:此时我们已经得到了Connection对象,因此无法通过继承改造这个对象

装饰的测试实现:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement; public class JDBCTest {
public static void main(String[] args) throws Exception { //测试装饰模式
Animal dog=new BigDog(new Dog());
dog.eat();
dog.sound(); }
} /**
* 装饰模式测试
* @author taoshihan
*
*/
interface Animal{
public void eat();
public void sound();
}
class Dog implements Animal{ @Override
public void eat() {
System.out.println("吃");
} @Override
public void sound() {
System.out.println("汪");
}
}
//此时我想修改Dog类中的sound方法
class BigDog implements Animal{
private Dog dog;
public BigDog(Dog dog) {
this.dog=dog;
}
/**
* 这个方法调原来的
*/
@Override
public void eat() {
dog.eat();
}
/**
* 这个方法进行装饰
*/ @Override
public void sound() {
System.out.println("大叫");
} }

动态代理:

        //测试代理模式
final Dog dog=new Dog();
Animal proxy=(Animal) Proxy.newProxyInstance(Dog.class.getClassLoader(),Dog.class.getInterfaces() , new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if("sound".equals(method.getName())){
System.out.println("大叫");
return null;
}else{
return method.invoke(dog, args);
}
}
});
proxy.eat();
proxy.sound();

[javaEE] 数据库连接池和动态代理的更多相关文章

  1. 【Java EE 学习 15】【自定义数据库连接池之动态代理的使用】

    一.动态代理的作用 使用动态代理可以拦截一个对象某个方法的执行,并执行自定义的方法,其本质是反射 优点:灵活 缺点:由于其本质是反射,所以执行速度相对要慢一些 二.数据库连接池设计思想 1.为什么要使 ...

  2. 使用Java中的动态代理实现数据库连接池

    2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...

  3. 使用 JAVA 中的动态代理实现数据库连接池

    数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈.我们可以在互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共 ...

  4. 关于利用动态代理手写数据库连接池的异常 java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to java.sql.Connection

    代码如下: final Connection conn=pool.remove(0); //利用动态代理改造close方法 Connection proxy= (Connection) Proxy.n ...

  5. junit,面向切面开发(动态代理),工厂设计模式,数据库连接池

    1.junit junit又叫单元测试,好处是能进行批量测试,而且如果方法出现了问题能立刻定位出出现问题的方法,还有一个好处是感官效果很好,如果方法都通过了则显示绿条,否则显示红条 TestCase. ...

  6. JAVAEE——Mybatis第一天:入门、jdbc存在的问题、架构介绍、入门程序、Dao的开发方法、接口的动态代理方式、SqlMapConfig.xml文件说明

    1. 学习计划 第一天: 1.Mybatis的介绍 2.Mybatis的入门 a) 使用jdbc操作数据库存在的问题 b) Mybatis的架构 c) Mybatis的入门程序 3.Dao的开发方法 ...

  7. javaEE(12)_数据库连接池

    一.直接获取数据库连接和通过池获取示意图: 二.编写数据库连接池 1.实现DataSource接口,并实现连接池功能的步骤: •在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加 ...

  8. 4.使用Redis+Flask维护动态代理池

    1.为什么使用代理池 许多⽹网站有专⻔门的反爬⾍虫措施,可能遇到封IP等问题. 互联⽹网上公开了了⼤大量量免费代理理,利利⽤用好资源. 通过定时的检测维护同样可以得到多个可⽤用代理理. 2.代理池的要 ...

  9. Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

    Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...

随机推荐

  1. php 多维数据根据某个或多个字段排序

    实现多维数组的指定多个字段排序 上面的实例讲解了如何实现多维数组指定一个字段排序,但如果要实现指定多个字段来对数组进行排序该如何思考? 多个字段是几个?2个,3个或更多,所以这个不确定的因素需要排除. ...

  2. Django-01Django简介

    1 MVC与MTV模型 MVCWeb服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负责业 ...

  3. day11学python 多线程+queue

    多线程+queue 两种定义线程方法 1调用threading.Thread(target=目标函数,args=(目标函数的传输内容))(简洁方便) 2创建一个类继承与(threading.Threa ...

  4. Linux常用运维指令

    cd data/apps./=========================================== ps -ef | grep tomcatps -ef | grep desktopX ...

  5. sql case 函数与详细说明

    下面是一个是用case函数来完成这个功能的例子 case具有两种格式.简单case函数和case搜索函数. --简单case函数 case sex         when '1' then '男'  ...

  6. Docker 下系统日志恢复

    众所周知,docker 是一款进程级虚拟机.上文我们已经分析解释了该如何使用,本文针对日志消失问题进行恢复与解释. Docker 可以理解为阉割版的系统,内部功能不全.可以通过组件安装进行基本功能恢复 ...

  7. 基于DALN方案C/S架构运用

    今天闲来无事,看到笔记本的蓝牙设备想着:可不可以实现电脑端播放手机端的音频. 刚刚开始想着基于蓝牙,尝试多次无解(主要原因是没有找到支持此功能的软件) 最后:有朋友建议可以研究下DALN方案解决这个需 ...

  8. Flink学习笔记:Time的故事

    本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...

  9. flask.abort

    abort(status) status:标注状态码,和异常 抛出异常后会终止当前函数 使用errorhandler装饰器捕获abort异常 @app.errorhandler(500) def in ...

  10. angular5新增全局的模块

    比如新增一个全局的swiper,需要在webpack中配置: 之后在代码中就可以用了