初见MyBatis的理解与认知 四

MyBatis

上期我们讲了mapper代理来解决硬编码的问题,非常方便哈,但问题也随之出现了————MyBatis Mapper 接口没有实现类是怎么实现SQL查询的呢?
在思考这个问题之前,我们先来了解一下Java代理模式。


Java代理模式

1、静态代理:由我们手动创建编写的代理类,在执行代码之前就已经存在了。
2、动态代理:在程序运行时,通过反射机制动态创建完成的。

静态代理
老方法,先举个例子。现在有一个业务模块,采购和付钱两个业务(定义一个接口,里面有两个方法,但里没没有具体的实现内容)

interface Service {
    void purchase();
    void pay();
}

超市采购经理想承包下这个业务模块(说明采购经理要继承这个接口,并且给出买什么和付钱的具体方法)

class serviceImplA implements Service{

    @Override
    public String purchase(String a) {
        System.out.println("采购东西");
        return a ;
    }

    @Override
    public int pay(int b) {
        System.out.println("付钱");
        return b;
    }
}

但是这个采购经理(被代理对象 serviceImpl)不想(不能)直接参与这个业务,所以需要采购部门(其实就是代理对象 serviceProxy)并且此时采购部门可以给出更为具体的方法(代理对象可以扩展被代理对象的功能)。

class serviceProxy implements Service{
    serviceImplA service = new serviceImplA();

    @Override
    public String purchase(String a) {
        service.purchase(a);
        System.out.println("采购"+a);
        return null;
    }

    @Override
    public int pay(int b) {
        service.pay(b);
        System.out.println(b+"元太贵了,价格低一点");
        return 0;
    }
}

来与批发商(就是测试用例 Test)进行这个业务模块。

public class Test {
    public static void main(String[] args) {
        Service service = new serviceProxy();
        String a = "面包";
        int b = 5;
        String commodity = service.purchase(a);
        int money = service.pay(b);
        System.out.println(commodity);
        System.out.println(money);
    }
}

执行!
初见MyBatis的理解与认知 四_第1张图片
成功啦!但如果此时销售经理也承包了一个业务模块,销售和收钱呢?那我们还得再在找销售部门去帮销售经理去卖东西,就很不省钱(bushi)。

interface ServiceB {
    String sales(String a);
    int collect(int b);
}

class serviceImplB implements ServiceB{

    @Override
    public String sales(String a) {
        System.out.println("销售东西");
        return a ;
    }

    @Override
    public int collect(int b) {
        System.out.println("收钱");
        return b;
    }
}
class serviceProxyB implements ServiceB{
    serviceImplB service = new serviceImplB();

    @Override
    public String sales(String a) {
        service.sales(a);
        System.out.println("销售"+a);
        return null;
    }

    @Override
    public int collect(int b) {
        service.collect(b);
        System.out.println(b+"元太便宜了,不能再便宜了");
        return 0;
    }
}

而且比如这次采购东西只要去告知批发商采购什么东西,而不用付钱,只需要采购部门负责告知批发商买什么的人来上班就行了,不需要付钱的人来上班,但部门的人都来干活了(静态代理的硬编码问题)总不能不给工资吧,那有没有更好的方法呢?Java动态代理!

动态代理
利用动态代理,我们对员工进行告知(让代理对象继承 InvocationHandler 接口)让采购部门的都不来上班,需要他们时我们就能精准的让告知(InvocationHandler 接口下的invoke(Object o, Method method, Object[] objects)方法:调用代理类的方法时,处理程序会利用反射,将代理类、代理类的方法、要调用代理类的参数传入这个函数,并运行这个函数,)需要来上班的人来上班就行了,就能省下钱了,嘿嘿。

interface Service {
    String purchase(String a);
    int pay(int b);
}

class serviceImplA implements Service {

    @Override
    public String purchase(String a) {
        System.out.println("采购东西");
        return a;
    }

    @Override
    public int pay(int b) {
        System.out.println("付钱");
        return b;
    }

}

class serviceProxy implements InvocationHandler{
    private Service service;

    public serviceProxy (Service service){
        this.service=service;
    }

    public Object getServiceProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), service.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        var result = method.invoke(service, objects);
        String methodName = method.getName();
        if(methodName.equals("purchase")){
            System.out.println("付钱的没来上班, 采购"+result);
        } else if (methodName.equals("pay")) {
            System.out.println("告知的没来上班, "+result+"元太贵了,价格低一点");
        }
        return  result;
    }
}

让来上班的人与批发商交流业务。

public class Test {
    public static void main(String[] args) {
          Service serviceA = new serviceImplA();
          Service serviceA1 = (Service) new serviceProxy(serviceA).getServiceProxy();
          String  a = "面包";
          int b = 5;
          String count = serviceA1.purchase(a);
          int money = serviceA1.pay(b);
          System.out.println(count);
          System.out.println(money);
    }
}

执行!
初见MyBatis的理解与认知 四_第2张图片
成功!
我们继续来解决静态代理没解决的问题————销售经理也承包了一个业务模块,销售和收钱呢?
这时我们让两个部门合并一下(利用object)。

interface Service {
    String purchase(String a);
    int pay(int b);
}

class serviceImplA implements Service {

    @Override
    public String purchase(String a) {
        System.out.println("采购东西");
        return a;
    }

    @Override
    public int pay(int b) {
        System.out.println("付钱");
        return b;
    }

}
interface ServiceB {
    String sales(String a);
    int collect(int b);
}

class serviceImplB implements ServiceB {

    @Override
    public String sales(String a) {
        System.out.println("销售东西");
        return a;
    }

    @Override
    public int collect(int b) {
        System.out.println("收钱");
        return b;
    }

}
class serviceProxy implements InvocationHandler{
    private Object service;

    public serviceProxy (Object service){
        this.service=service;
    }

    public Object getServiceProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), service.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        var result = method.invoke(service, objects);
        String methodName = method.getName();
        if(methodName.equals("purchase")){
            System.out.println("我是采购部门告知的,付钱的和销售部门没来上班, 采购"+result);
        } else if (methodName.equals("pay")) {
            System.out.println("我是采购部门付钱的,告知的和销售部门没来上班, "+result+"元太贵了,价格低一点");
        } else if (methodName.equals("sales")) {
            System.out.println("我是销售部门卖货的的,收钱的和采购部门没来上班, 销售"+result);
        } else if (methodName.equals("collect")) {
            System.out.println("我是销售部门收钱的,卖货的和采购部门没来上班, "+result+"元太便宜了,价格不能再低了");
        }
        return  result;
    }
}

客户与批发商

public class Test {
    public static void main(String[] args) {
        //批发商
        Service serviceA = new serviceImplA();
        Service serviceA1 = (Service) new serviceProxy(serviceA).getServiceProxy();
        String  a = "面包";
        int b = 5;
        String commodity = serviceA1.purchase(a);
        int money = serviceA1.pay(b);
        System.out.println(commodity);
        System.out.println(money);
        //客户
        ServiceB serviceB = new serviceImplB();
        ServiceB serviceB1 = (ServiceB) new serviceProxy(serviceB).getServiceProxy();
        String c = a;
        int d = 7;
        String sell = serviceB1.sales(c);
        int count = serviceB1.collect(d);
        System.out.println(sell);
        System.out.println(count);
    }
}

执行!
初见MyBatis的理解与认知 四_第3张图片
成功!
吼吼,这样只有一个部门在上班,而且只要给来上班的那些给工资就行啦!

你可能感兴趣的:(mybatis)