Java编写准备数据源
1、装饰设计模式
package com.itheima.ds; import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.List;
import java.util.Map;
import java.util.Properties;
//目前要包装的是:com.mysql.jdbc.Connection //1、编写一个类,实现与被包装类(数据库驱动对Connection的实现)相同的接口。(使这个类和数据库的驱动实现有着相同的行为)
public class MyConnection implements Connection {
// 2、定义一个变量,引用被包装类的实例
private Connection conn;//引用具体的数据库驱动 private List<Connection> pool; // 3、定义构造方法,传入被包装类的实例。
public MyConnection(Connection conn,List<Connection> pool){//依赖注入
this.conn = conn;
this.pool = pool;
}
//把链接还回池中
// 4、对于要改写的方法,编写自己的代码即可。
public void close() throws SQLException {
pool.add(conn);
}
public Statement createStatement() throws SQLException {
return conn.createStatement();
}
//5、对于不需要改写的方法,调用原有对象的对应方法。
public <T> T unwrap(Class<T> iface) throws SQLException {
return conn.unwrap(iface);
}
}
package com.itheima.ds; import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import javax.sql.DataSource; import com.itheima.util.JdbcUtil; public class MyDataSource1 implements DataSource { private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
static{
try {
for(int i=0;i<10;i++){
Connection conn = JdbcUtil.getConnection();//创建的新连接
pool.add(conn);
}
} catch (Exception e) {
e.printStackTrace();
}
} //从池中获取链接 > com.mysql.jdbc.Connection
public Connection getConnection() throws SQLException {
if(pool.size()>0){
Connection conn = pool.remove(0);
MyConnection1 mconn = new MyConnection1(conn,pool);
return mconn;
}else{
throw new RuntimeException("服务器真忙");
}
}
public PrintWriter getLogWriter() throws SQLException {
return null;
} public void setLogWriter(PrintWriter out) throws SQLException { } public void setLoginTimeout(int seconds) throws SQLException { } public int getLoginTimeout() throws SQLException {
return 0;
} public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
} public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
} public Connection getConnection(String username, String password)
throws SQLException {
return null;
} }
2、适配器设计模式
package com.itheima.ds; import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
//默认的适配器
/*
本身也是一个包装类,但并没有对任何的方法进行改写
1、编写一个类,实现与被包装类(数据库驱动对Connection的实现)相同的接口。(使这个类和数据库的驱动实现有着相同的行为)
2、定义一个变量,引用被包装类的实例。
3、定义构造方法,传入被包装类的实例。
4、全部调用原有对象的对应方法
*/
public class ConnectionAdapter implements Connection {
private Connection conn;
public ConnectionAdapter(Connection conn){
this.conn = conn;
}
public <T> T unwrap(Class<T> iface) throws SQLException {
return conn.unwrap(iface);
} public boolean isWrapperFor(Class<?> iface) throws SQLException {
return conn.isWrapperFor(iface);
} @Override
public Statement createStatement() throws SQLException {
return conn.createStatement();
}
......
}
package com.itheima.ds; import java.sql.Connection;
import java.sql.SQLException;
import java.util.List; /*
这也是包装:对ConnectionAdapter进行包装。 包装类即是被包装类的包装,又是他的子类。 1、编写一个类,继承已经是包装类的类。
2、定义一个变量,引用被包装类的实例。
3、定义构造方法,传入被包装类的实例。
4、覆盖掉需要改写的方法
*/
public class MyConnection1 extends ConnectionAdapter {
private Connection conn;
private List<Connection> pool;
public MyConnection1(Connection conn,List<Connection> pool){
super(conn);
this.conn = conn;
this.pool = pool;
}
public void close() throws SQLException {
pool.add(conn);
} }
3、基于接口的动态代理:Proxy
package com.itheima.ds; import java.io.PrintWriter;
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.Collections;
import java.util.List; import javax.sql.DataSource; import com.itheima.util.JdbcUtil;
//用动态代理编写的数据源
public class MyDataSource2 implements DataSource { private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
static{
try {
for(int i=0;i<10;i++){
Connection conn = JdbcUtil.getConnection();//创建的新连接
pool.add(conn);
}
} catch (Exception e) {
e.printStackTrace();
}
} public Connection getConnection() throws SQLException {
if(pool.size()>0){
final Connection conn = pool.remove(0);//得到的是数据库驱动的实现
Connection connProxy = (Connection)Proxy.newProxyInstance(conn.getClass().getClassLoader(),
conn.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if("close".equals(method.getName())){
//还回池中
return pool.add(conn);
}else{
return method.invoke(conn, args);
}
}
}
);
return connProxy;//返回30行的代理对象
}else{
throw new RuntimeException("服务器真忙");
}
}
package com.itheima.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class Client1 { public static void main(String[] args) {
final Human sb = new SpringBrother(); //代理人:如何动态产生代理人 /*
ClassLoader loader:动态代理,必须有字节码class。加到内存中运行,必须有类加载器。固定:和被代理人用的是一样的
Class<?>[] interfaces:代理类要实现的接口,要和被代理对象有着相同的行为。固定:和被代理人用的是一样的
InvocationHandler h:如何代理。他是一个接口。策略设计模式。 */
//产生代理类,得到他的实例
Human proxyMan = (Human)Proxy.newProxyInstance(sb.getClass().getClassLoader(),
sb.getClass().getInterfaces(),
new InvocationHandler() {
//匿名内部类,完成具体的代理策略
//调用代理类的任何方法,都会经过该方法。 拦截 /*
Object proxy:对代理对象的引用。
Method method:当前执行的方法
Object[] args:当前方法用到的参数 返回值:当前调用的方法的返回值
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//判断出场费
if("sing".equals(method.getName())){
//唱歌
float money = (Float)args[0];
if(money>10000){
method.invoke(sb, money/2);
}
}
if("dance".equals(method.getName())){
//唱歌
float money = (Float)args[0];
if(money>20000){
method.invoke(sb, money/2);
}
}
return null;
}
}
);
proxyMan.sing(20000);
proxyMan.dance(100000);
} }
4、基于子类的动态代理:CGLIB
前提:被代理类的要求
1、不能是final的
2、必须是public的
package com.itheima.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class Client1 { public static void main(String[] args) { final SpringBrother sb = new SpringBrother(); //产生sb的代理:
/*
Class type:代理类的父类型
Callback cb:回调,如何代理
*/
SpringBrother proxy = (SpringBrother) Enhancer.create(SpringBrother.class,new MethodInterceptor(){ public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy arg3) throws Throwable {
//判断出场费
if("sing".equals(method.getName())){
//唱歌
float money = (Float)args[0];
if(money>10000){
method.invoke(sb, money/2);
}
}
if("dance".equals(method.getName())){
//唱歌
float money = (Float)args[0];
if(money>20000){
method.invoke(sb, money/2);
}
}
return null;
}
});
System.out.println(proxy instanceof SpringBrother);
proxy.dance(100000);
proxy.sing(50000); } }
Java编写准备数据源的更多相关文章
- 基于 Web 的数据挖掘--自动抽取用 HTML、XML 和 Java 编写的信息
简介: 不可否认,万维网是到目前为止世界上最丰富和最密集的信息来源.但是,它的结构使它很难用系统的方法来利用信息.本文描述的方法和工具将使那些熟悉 Web 最常用技术的开发人员能快速而便捷地获取他们所 ...
- 网页动物园2.0发布,经过几个月的努力,采用JAVA编写!
网页动物园2.0发布,经过几个月的努力,采用JAVA编写! 网页动物园2.0 正式发布!游戏发布 游戏名称: 网页动物园插件 游戏来源: 原创插件 适用版本: Discuz! X1.5 - X3.5 ...
- 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小
原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...
- java 编写hadoop程序中使用第三方libxx.so库
在使用java编写hadoop处理程序时遇到了,java使用依赖的第三方libxx.so库的情况,找到了一种可行的方法,记录一下,希望对别人也有帮助: 加入需要使用的lib库为libxxx.so 1. ...
- 如何用Java编写一段代码引发内存泄露
本文来自StackOverflow问答网站的一个热门讨论:如何用Java编写一段会发生内存泄露的代码. Q:刚才我参加了面试,面试官问我如何写出会发生内存泄露的Java代码.这个问题我一点思路都没有, ...
- Java编写的C语言词法分析器
Java编写的C语言词法分析器 这是java编写的C语言词法分析器,我也是参考很多代码,然后核心代码整理起来,放在QQ空间和博客上,目的是互相学习借鉴,希望可以得到高手改进.这个词法分析器实现的功能有 ...
- delphi调用java编写的webservice
delphi调用java编写的webservice JAVApojo: public class GroupInfo implements Serializable{ private stati ...
- 实战WEB 服务器(JAVA编写WEB服务器)
实战WEB 服务器(JAVA编写WEB服务器) 标签: web服务服务器javawebsockethttp服务器 2010-04-21 17:09 11631人阅读 评论(24) 收藏 举报 分类: ...
- Java 编写小程序,下载指定网页上的所有图片
使用Java编写一个小程序,可以根据指定的网页地址,下载网页中的所有图片:使用到网络编程.线程池.IO和UUID的技术.具体代码如下: import java.io.File; import java ...
随机推荐
- Redis系列二:reids介绍
一.什么是redis.redis有哪些特性.redis有哪些应用场景.redis的版本 1. 什么是redis redis是一种基于键值对(key-value)数据库,其中value可以为string ...
- UI之富文本编辑器-UEditor
在做Web应用时,经常会进行富文本编辑,常用的富文本编辑器有很多,比如CuteEditor.CKEditor.NicEditor.KindEditor.UEditor等等. 在这里为大家推荐百度推出的 ...
- gatewayworker中使用tcp协议连接硬件设备获取数据报错解决办法!
运行后过段时间报错, Warning: Error while sending STMT_PREPARE packet. PID=1776 in D:\phpStudy\WWW\api\mysql-m ...
- linux问题解答
1.Linux如何查询进程?杀死一个进程? ps命令提供进程的一次性查看(瞬时信息),结果不是动态的:top对命令实时监控 ps只是查看进程,而top还可以监视系统性能,如平均负载,cpu和内存的消耗 ...
- Python2.7-fileinput
fileinput 模块,对输入的文件流进行迭代操作,可以说是对 open() 的一个扩展,它可以直接修改文件,也可以对他们进行备份 模块方法: fileinput.input([files[, in ...
- jquery获取具有多个类class的标签内容
var tag = $('div.firstClassName.secondClassName.thirdClassName'); 注意空格
- Codeforces round 1100
Div 2 532 我对交互一无所知 只能寄期望与NOI和省选不出交互吧... E 这个题,真的是耻辱... 其实非常简单,就是二分+判环... 那么就直接二分答案+拓扑排序即可... (我居然在考试 ...
- VB 批量重命名文件
VERSION 5.00 Begin VB.Form Form1 BorderStyle = 3 'Fixed Dialog Caption = "Rename use VB QQ 1009 ...
- 20155323刘威良《网络对抗》Exp8 Web基础
20155323刘威良<网络对抗>Exp8 Web基础 实践内容 (1).Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编 ...
- vue 使用 proxyTable 解决跨域问题
1.在 main.js 中,在引入 axios: import axios from 'axios' Vue.config.productionTip = false Vue.prototype.$a ...