码迷,mamicode.com
首页 > 编程语言 > 详细

Java编写准备数据源

时间:2018-02-03 15:55:34      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:blog   word   return   lib   turn   返回   rri   pos   接口   

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编写准备数据源

标签:blog   word   return   lib   turn   返回   rri   pos   接口   

原文地址:https://www.cnblogs.com/xiarongjin/p/8409255.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!