mybatis框架学习(一)

mybatis中使用到的设计模式

  • 适配器设计模式
    • 解决的问题:解决接口与接口实现类之间继承矛盾的问题,因为当一个类继承一个接口时,该类需要实现接口中的所有方法。
    • 适配器设计模式特征
      • 使用抽象类分离了接口与【接口实现类】
      • 抽象类分摊接口需要实现的常用方法
      • 使得接口实现类像逛超市一样,可以随意选择接口中的方法来实现
    • 参考Servlet规范中GenericServlet
/**
*	接口
*/
public interface Fu {

    public void zhuyaofangfa();

    public void chongfudaima1();

    public void chongfudaima2();

}

/**
*	抽象类
*/
public  abstract class AdapterFu implements Fu {

    public void chongfudaima1() {
        System.out.println("在适配器中实现重复代码1.。。。。。。。");
    }

    public void chongfudaima2() {
        System.out.println("再适配中实现重复代码2............");
    }

}

/**
*	字类
*/
public class Zi extends AdapterFu {

    public void zhuyaofangfa() {
        System.out.println("Zi类中实现的主要方法");
    }

    public void print(){
        zhuyaofangfa();
        super.chongfudaima1();
        super.chongfudaima2();
    }

}

/**
*	测试类
*/
public class TestMain {

    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.print();
    }

}
  • 模板设计模式
    • 解决的问题:让父类控制子类方法的调用顺序;(但是实际开发中父类的方法不会用final来修饰)
    • 优点:开发人员开发时,需要考虑方法的实现,不需要考虑方法在何种情况下被调用,减少代码的复用性
    • :在查看HttpServlet的时候,在service方法没有使用final来修饰,是因为sun公司的人不想把这个方法写死让继承了父类的子类可以覆盖这个方法去灵活运用该方法,所以设计模式的精髓不是一种固定不变的模式,而是根据业务去做最优化的处理
/**
*	需要被继承的类
*/
public class AClass {
    public void method1(){
        System.out.println("AClass method1 .............");
    }
    public void method2(){
        System.out.println("AClass method2 .............");
    }
    public void method3(){
        System.out.println("AClass method3 .............");
    }
    public void method4(){
        System.out.println("AClass method4 .............");
    }
    public final void print(){
        method1();
        method2();
        method3();
        method4();
    }
}
/**
*	此类是继承了Aclass并重写了其中的一个方法
*/
public class TemplateDemo extends AClass {
    @Override
    public void method1() {
        System.out.println( " TemplateDemo method1 .............");
    }
}

/**
 * 测试类
*/
public class TestMain {
    public static void main(String[] args) {
        TemplateDemo demo = new TemplateDemo();
        demo.print();
    }
}
  • 代理设计模式
  • 解决的问题:从业务的角度出发,将【次要业务】和【主要业务】解耦合
    • 【次要任务】和【主要业务】区分
      • 次要业务:起辅助功能,辅助【主要业务】顺利实现,在项目【次要业务】往往大量重复出现
      • 主要业务:主要任务
    • 【次要业务】对于开发效率影响
      • 在mybatis中,它认为只有写sql语句才是主要的任务而其它的操作都是次要任务,开发人员不应该关注这些次要业务,只需要关心主要业务
      • 比如JDBC操作中:
        • 加载驱动类(次要业务)
        • 建立连接通道(次要业务)
        • 建立数据库操作对象(次要业务)
        • 推送sql命令到数据库执行冰返回处理结果(主要任务)
        • 销毁 conn statement rs(次要业务)
  • 作用:将主要业务和次要业务分离,减少工作量,只需要关心主要业务;拦截器、过滤器和监听器都是代理模式的产物
  • 本质:行为的监听
    • 例子:< input type=“button” οnclick=“fun1”>
      onclick 相当于一个代理对象(监听对象) $proxy
      fun1 相当于InvocationHandler
      注:反射只是代理模式中运用到的技术,并不是模式的本质
  • 组成
    • 接口:声明需要被监听的行为
    • 代理实现类:一个实现InvocationHandler的实现类;次要业务实现;次要业务和主要业务绑定执行
    • 代理对象:一个监听对象
/**
* 业务:饭前便后要洗手
*      【主要业务】吃饭,拉屎
*      【次要业务】洗手
* mybatis实现接口式编程:
* 	通过代理的设计模式,当调用接口中的方法的时候,返回一个监听对象,当监听对象执行方法时,
* 	实际调用的是实现类中的方法,所以在mybatis中,一个dao对应一个dao.xml文件,dao中所有的
* 	方法一一对应dao.xml中的方法,当dao调用其中一个方法时,mybatis通过代理实际调用了相关的
* 	类去执行了对应xml文件中的sql语句并返回数据
*/

/**
*	dao接口
*/
public interface BaseService {
    public void eating (String food);
    public void wcing();
}

/**
*	接口实现类
*/
public class Person implements BaseService {
    public void eating(String food) {
        System.out.println("chi " + food);
    }
    public void wcing() {
        System.out.println("la shi ....");
    }
}

/**
*	代理实现类,实际当调用了dao的方法时,该类将执行代理实现类中的方法
*/
public class Agent implements InvocationHandler {
    private BaseService obj; // 被开发人员索要的真实对象
    public Agent(BaseService param){
        this.obj = param;
    }
    //次要业务和主要业务的绑定
    /**
     *
     * @param proxy 本次负责监听的对象 ---- 相当于 onclick
     *
     * @param method 被拦截的主要业务方法
     *
     * @param params 被拦截主要业务方法接受的实数
     *
     * @return
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
        //1.读取被拦截方法名称
        String methodName = method.getName();
        if("eating".equals(methodName)){//饭前洗手
            wash();
            //System.out.println(methodName + "is run .....");
            method.invoke(obj,params);
        }else{
            //System.out.println(methodName + "is run .....");
            method.invoke(obj,params);
            wash();
        }
        /*
        主要业务方法被拦截之后,主要业务的方法是在本方法内被调用的,因此它需要
        将方法的执行结果返回给代理对象(监听对象)
        * */
        return null;

    }
    //次要业务
    private void wash(){
        System.out.println("祈祷"); //解耦合
    }
}

/**
*	代理工厂,该类返回一个代理监听对象,当监听对象执行方法时,则会去调用代理实现类的方法
*/
public class ProxyFactory {
    //返回一个代理监听对象
    public static BaseService newInstance(){
        //0.创建被索要的类型的实例对象
        BaseService xiaoming = new Person();
        //1.拥有一个代理实现类对象
        //InvocationHandler agent = new Agent();
        InvocationHandler agent = new Agent(xiaoming);
        //2.申请/注册一个对特定行为监控对象(代理对象;他就是一个onclick监听对象)
        /**
         * loader 用来指向被监控的类文件在内存中真实地址;在此处BaseService就是被监听的对象
         *
         * interface 被监控的类所实现的接口,这个接口中所声明的方法就是需要被监控的行为
         *           也是主要业务行为名称
         *
         */
        Class classArry[]  = {BaseService.class};
        //BaseService 监听对象 = (BaseService)Proxy.newProxyInstance(BaseService.class.getClassLoader()/*loader*/,classArry/*interface*/,agent);
        BaseService 监听对象 = (BaseService)Proxy.newProxyInstance(Person.class.getClassLoader()/*loader*/,classArry/*interface*/,agent);
        return 监听对象;
    }
    
    //返回一个代理监听对象
    public static BaseService newInstance(Class classFile) throws Exception {
        //0.创建被索要的类型的实例对象
        BaseService 索要对象 = (BaseService)classFile.newInstance();
        //1.拥有一个代理实现类对象
        //InvocationHandler agent = new Agent();
        InvocationHandler agent = new Agent(索要对象);

        //2.申请/注册一个对特定行为监控对象(代理对象;他就是一个onclick监听对象)
        /**
         * loader 用来指向被监控的类文件在内存中真实地址;在此处BaseService就是被监听的对象
         *
         * interface 被监控的类所实现的接口,这个接口中所声明的方法就是需要被监控的行为
         *           也是主要业务行为名称
         *
         */

        Class classArry[]  = {BaseService.class};

        //BaseService 监听对象 = (BaseService)Proxy.newProxyInstance(BaseService.class.getClassLoader()/*loader*/,classArry/*interface*/,agent);

        BaseService 监听对象 = (BaseService)Proxy.newProxyInstance(classFile.getClassLoader()/*loader*/,classArry/*interface*/,agent);

        return 监听对象;
    }
}

/**
*	测试类
*/
public class TestMain {
    public static void main(String[] args) throws Exception {
        //实质拿到的是一个监听对象
        /*BaseService service = ProxyFactory.newInstance();
        service.eating("jitui");*/
        //BaseService xiaoming = new Person(); //丑陋的行为 对象不受监控的创建行为
        BaseService xiaoming = ProxyFactory.newInstance();
        xiaoming.eating("ya ");
    }
}

你可能感兴趣的:(mybatis)