zoukankan      html  css  js  c++  java
  • 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);
            
        }
    
    }
  • 相关阅读:
    <!DOCTYPE html>的重要性!
    ibatis 常用标签
    string.match(RegExp) 与 RegExp.exec(string) 深入详解
    JavaScript RegExp.$1
    JavaScript RegExp.exec() 方法
    正则表达式常用符号说明
    正则表达式中/i,/g,/ig,/gi,/m的区别和含义
    JavaScript Math.floor() 方法
    JavaScript RegExp.test() 方法
    js日期格式化 扩展Date()
  • 原文地址:https://www.cnblogs.com/xiarongjin/p/8409255.html
Copyright © 2011-2022 走看看