zoukankan      html  css  js  c++  java
  • 设计模式学习笔记:一、代理模式(动态代理实现)

    以数据库查询为例:

    1.声明接口:执行数据库操作

    public interface SqlSession {
    	
    	 public int save(String sql)throws Exception;
    
    }

    2.接口实现类:具体的主要业务,sql执行的实现

    public class DeptMapper implements SqlSession {
        PreparedStatement ps;
    	@Override
    	public int save(String sql) throws SQLException {//JDBC主要业务 输送sql
    		   int num= ps.executeUpdate(sql);
    		return num;
    	}
    
    }

    3.InvocationHanler接口实现类:次要业务,前期数据库连接,后期sqlsession关闭

    public class Invaction implements InvocationHandler {
    
    	    private SqlSession    obj;//具体被监控对象
    	    Connection connection ;
    	    PreparedStatement pStatement;
    	    
    	    public Invaction(SqlSession param){
    	    	this.obj = param;
    	    }
    	
    	/*
    	 * 
    	 *  invoke方法:在被监控行为将要执行时,会被JVM拦截
    	 *             被监控行为和行为实现方会被作为参数输送invoke
    	 *             ****通知JVM,这个被拦截方法是如何与当前次要业务方法绑定实现 
    	 *  invoke方法三个参数
    	 *  
    	 *           int v= 小明.eat();//JVM拦截
    	 *            eat方法封装为Mehtod类型对象
    	 *            eat方法运行时接受所有的实参封装到Object[]
    	 *            将负责监控小明的代理对象作为invoke方法第一个参数
    	 * 
    	 */
    	@Override
    	public Object invoke(Object porxy, Method method, Object[] params) throws Throwable {
    		         Object value;
    		        //1.执行JDBC初始次要业务
    		            init();
    		        //2.执行JDBC主要业务
    		           Field psField = obj.getClass().getDeclaredField("ps");
    		           psField.setAccessible(true);
    		           psField.set(obj, pStatement);
    		          value= method.invoke(obj, params);
    		        //3.执行JDBC结束次要业务
    		           close();
    		return value; //返回被拦截方法,需要调用地方
    	}
    	
    	//次要业务
    	private void init()throws Exception{
    		Class.forName("com.mysql.jdbc.Driver");
    		 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123");
    	     pStatement = connection.prepareStatement("");
    	}
    	
    	private void close() throws SQLException{
    		if(pStatement!=null){
    			pStatement.close();
    		}
    		if(connection!=null){
    			connection.close();
    		}
    	}
    
    }

    4.代理对象创建

    public class SqlSessionFactory {
    	/*
    	 * 
    	 *  JDK动态代理模式下,代理对象的数据类型
    	 *  应该由监控行为来描述 
    	 *  参数: Class文件,监控类
    	 */
    	public static  SqlSession Builder(Class classFile)throws Exception {
    		
    		//1.创建被监控实例对象
    		 SqlSession obj=  (SqlSession) classFile.newInstance();
    		//2.创建一个通知对象
    		 InvocationHandler adviser= new Invaction(obj);
    		 //3.向JVM申请负责监控obj对象指定行为的监控对象(代理对象)
    		 /*
    		  *  loader:被监控对象隶属的类文件在内存中真实地址
    		  *  interfaces:被监控对象隶属的类文件实现接口
    		  *  h:监控对象发现小明要执行被监控行为,应该有哪一个通知对象进行辅助
    		  */
    		 SqlSession $proxy= (SqlSession) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), adviser);
    	     return $proxy;
    	}
    
    }

    测试:

    public static void main(String[] args) throws Exception {
    	   
    		Map StatementMapper = new HashMap();
    	    StatementMapper.put("dept.save", "insert into dept values(50,'TEST','BEIJING',1)");
    		
    		SqlSession dao =   SqlSessionFactory.Builder(DeptMapper.class);	    	    
    		dao.save((String)StatementMapper.get("dept.save"));
    }

    这样,模拟mybatis的这种动态代理的实现就完成了

  • 相关阅读:
    DB2 for Z/os Statement prepare
    Foreign key (referential) constraints on DB2 LUW v105
    复制Informational constraints on LUW DB2 v105
    DB2 SQL Mixed data in character strings
    DB2 create partitioned table
    MVC中使用EF的技巧集(一)
    Asp.Net MVC 开发技巧(二)
    Linq使用技巧及查询示例(一)
    Asp.Net MVC 开发技巧(一)
    Asp.Net MVC Identity 2.2.1 使用技巧(八)
  • 原文地址:https://www.cnblogs.com/dulinan/p/12033033.html
Copyright © 2011-2022 走看看