[javaEE] 数据库连接池和动态代理
实现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] 数据库连接池和动态代理的更多相关文章
- 【Java EE 学习 15】【自定义数据库连接池之动态代理的使用】
一.动态代理的作用 使用动态代理可以拦截一个对象某个方法的执行,并执行自定义的方法,其本质是反射 优点:灵活 缺点:由于其本质是反射,所以执行速度相对要慢一些 二.数据库连接池设计思想 1.为什么要使 ...
- 使用Java中的动态代理实现数据库连接池
2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...
- 使用 JAVA 中的动态代理实现数据库连接池
数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈.我们可以在互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共 ...
- 关于利用动态代理手写数据库连接池的异常 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 ...
- junit,面向切面开发(动态代理),工厂设计模式,数据库连接池
1.junit junit又叫单元测试,好处是能进行批量测试,而且如果方法出现了问题能立刻定位出出现问题的方法,还有一个好处是感官效果很好,如果方法都通过了则显示绿条,否则显示红条 TestCase. ...
- JAVAEE——Mybatis第一天:入门、jdbc存在的问题、架构介绍、入门程序、Dao的开发方法、接口的动态代理方式、SqlMapConfig.xml文件说明
1. 学习计划 第一天: 1.Mybatis的介绍 2.Mybatis的入门 a) 使用jdbc操作数据库存在的问题 b) Mybatis的架构 c) Mybatis的入门程序 3.Dao的开发方法 ...
- javaEE(12)_数据库连接池
一.直接获取数据库连接和通过池获取示意图: 二.编写数据库连接池 1.实现DataSource接口,并实现连接池功能的步骤: •在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加 ...
- 4.使用Redis+Flask维护动态代理池
1.为什么使用代理池 许多⽹网站有专⻔门的反爬⾍虫措施,可能遇到封IP等问题. 互联⽹网上公开了了⼤大量量免费代理理,利利⽤用好资源. 通过定时的检测维护同样可以得到多个可⽤用代理理. 2.代理池的要 ...
- Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题
Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...
随机推荐
- 爬虫开发3.requests模块
requests模块 - 基于如下5点展开requests模块的学习 什么是requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能 ...
- maven(私库)上传jar包
在实际开发过程中,我们经常会遇到需要引用的jar依赖,在我们公司的maven仓库不存在,这个时候我们就需要把jar上传上去,在项目中添加对应依赖就OK了. 步骤1:下载jar 在http://mvnr ...
- Java面向对象之异常(throw与throws)
一.基础概念 1.throw和throws的区别: 位置不同:throws用在函数上,后面跟的是异常类,可以跟多个. throw用在函数内,后面跟的是异常对象. 功能不同:throws用来声明异常,让 ...
- php从文本读入数据,处理结果再导入到文本
1,php从文本逐行读入数据,保存到数据组.使用fopen读取文本内容,逐行读取文本是$majorId = trim(fgets($rfile, 4096));. $rfile = fopen(&qu ...
- 8,Phaser__并发且多阶段任务
使用场景 考选武状元 10 个 武生 参加考试 ,第一个关 靠耐力, 坚持最久的5个人进入第二关, 第二关考 力气,力气最大的 3个人进入第二关,第三关考兵法,兵法最好的当选武状元
- UIViewController读书笔记
当一个VC把另一个VC作为子view加到自己的view时,一定要先调用addChildViewController(_:)方法. 因为一个VC的root view,也就是VC的view只能被这个VC持 ...
- P2540 斗地主增强版
P2540斗地主增强版 参考大佬题解 思路:顺子暴力搜,剩下的牌我不会贪心所以用记忆化搜索(或者dp): 注意:双王不能当对,二不算顺子 代码 #include <cstdio> #inc ...
- 搭建USB摄像头转RTSP服务器的多种方法
USB摄像头与网络摄像头相比,可选择范围广.种类多.成本低,但是实际使用时需要通过rtsp流来访问,起到直播的效果,因此在摄像头采集终端上构建rtsp流媒体服务器,将USB摄像头数据转化为rtsp,可 ...
- Little Sub and Traveling(杭师大第十二届校赛E题) 欧拉回路
题目传送门 题目大意: 从0出发,每次只能跳到(i*2)%n或者(i*2+1)%n,求字典序最大的哈密顿回路. 思路: 首先n为奇数时无解,先来证明这一点. 先假设n为奇数,若要回到原点,则必定有一步 ...
- 配置idea解决乱码
在项目开发过程中,我们一般希望在修改完代码之后不重启项目即可提现出修改的结果,那么热部署项目就显得十分必要了.在idea中将项目热部署至tomcat中的方法如下: 首先打开tomcat配置界面,在se ...