zoukankan      html  css  js  c++  java
  • Mybatis---总结

    MyBatis是什么

    Mybatis首先是持久层框架,可以通过简单的xml和注解进行配置,将接口和java对象映射成数据库中的记录。

    可以避免jdbc代码和手动设置参数和获取结果集的繁琐过程。因为使用jdbc去做数据库持久化的步骤很繁琐:

    1. 连接数据库,设置驱动和数据库信息。

    2. 创建连接connection

    3. 创建statement然后执行sql,返回resultset

    4. 手动处理resultset映射到java对象。

    而只要通过简单的配置就能够使用mybatis帮你处理了。

    Mybatis的组成

    Mybatis主要有四个部分组成:

    SqlSessionFactoryBuilder 工厂构造器

    SqlSessionFactory 工厂类

    SqlSession 会话。能够调用映射器,发送sql语句去执行并且返回结果,能够控制事务的提交和回滚。

    映射器。能够将java接口和xml配置文件映射成SQL用来执行,也能够将执行结果映射成java对象。

    Mybatis原理---反射

    资料

    http://www.iteye.com/topic/1123081


    ===概念

    java反射机制是说在程序的运行过程中,对于任意一个类或者对象,都能够知道它的所有属性和方法和构造方法,能够创建新的对象;这种动态获取属性或者调用方法的功能叫做java反射机制。

    对于反射来说,最重要的就是Class类,这是一种用来描述类的类。java中的每一个类都会有一个Class实例对象,用来封装这个类的信息,包括属性,接口,方法,构造函数等等。要使用反射的话都要先获取这个Class对象。

    ===Class对象什么时候创建的呢?被保存在虚拟机什么位置呢?

    在类加载器加载的时候创建Class对象,保存在虚拟机的方法区中。

    ===创建Class类实例对象的方法有三种

    1.通过类获取;Person.class

    2.通过类的全限定名创建 Class.forName(com.java.Person);类加载器会做加载

    3.通过对象获取,getClass()来创建。

    4.获取当前线程的classloader来加载。

    ===使用Class.forName和直接通过类名获取Class对象引用有什么区别呢?

    首先他们都会获取到Class对象引用,但是使用.class不会做初始化,使用Class.forName会做初始化。

    类加载三个步骤:加载连接初始化。

    实际上进行了三步操作:

    1.虚拟机的类加载器加载了.class文件,首先查找并且导入Class对象

    2.验证类中的字节码,为静态变量分配了内存空间,创建了对其他类的所有引用

    3.进行初始化,进行静态初始化和静态初始化块。

    ===获取到Class类实例对象之后就能够调用他的一些方法,比如说最常见的就是newInstance()方法来创建一个对象,或者通过getMethod方法获取方法类对象,再调用invoke来执行方法。

    Class cla = Person.class;

    Object xiaoming = cla.newInstance();

    ===框架中如何使用反射呢?

    框架中大量使用到反射机制,能够使得程序更加灵活。

    举一个例子,比如说创建一个类Person,如果没有反射,那么你必须new 一个Person对象。这个时候如果person类需要修改,那么就要停下整个应用进行修改编译再运行。但是使用反射就不需要了,你只要修改配置文件就行,通过配置文件获取到对象的Class对象,然后通过Class对象的newInstance()方法来创建实例。    

    Mybatis原理---jdk动态代理

    ===使用jdk动态代理的流程

    1.创建接口

     

    2.创建委托类实现接口

     

    3.创建代理类实现invocationHandler接口,绑定委托类,实现invoke方法。

    绑定委托类:使用Proxy.newProxyInstance方法来绑定委托类返回一个代理对象,传入三个参数:委托类的类加载器,委托类接口,代理类。

     

    实现invoke代理方法

    Object invoke(Object proxy, Method method, Object[] args) throws Throwable

    proxy:  指代我们所代理的那个真实对象

    method:  指代的是我们所要调用真实对象的某个方法的Method对象

    args:  指代的是调用真实对象某个方法时接受的参数

     

    最后就是创建代理类,绑定后直接调用代理类的方法就可以了。

     

    Mybatis原理---Cglib动态代理

    产生一个子类 通过方法拦截技术拦截所有父类方法的调用。 

    核心---映射器MapperStatement

    映射器mapper是接口和xml或者注解的组合。通过动态代理来真正的实现sql语句的查询和返回结果。因为xml配置文件中配置了接口的全路径,根据全路径和方法名就能够通过动态代理去做绑定代理类MapperProxy。执行代理类的invoke方法来做执行。

    MapperProxy代理类---invoke方法---MapperMethod----execute---根据增删改查做相应的处理

    映射器的结构

    映射器包括三个核心:

    MappedStatement对象,它保存了一个节点,对应xml配置中的一个(select/insert/delete/update)增删改查的操作节点。保存了sql,缓存信息,结果集,入参类型,返参类型等等信息。

    SqlSource,是一个接口,提供boundSql对象的获取,boundsql对象用来组装sql语句。

    BoundSql 建立sql和参数的地方。包含sql语句,parameterObject和parameterMappings三个部分其中

    Parameter表示入参本身如果我们传入多个参数的时候,就会转化成一个map,

    parameterMappings用来描述参数,描述参数的属性名称,类型,javaType,jdbcType等等重要信息。通过它可以实现参数和sql的结合。

    以上就是重要的三个重要部分。

    映射器的动态代理

    执行的流程总结如下:

    1. 首先会调用代理类mapperMethod的execute方法,传入sqlsession和入参。

    2. 随后在execute方法中会判断所执行的方法是增删改查的哪个,调用相对应的sqlsession的方法去执行。

    首先动态代理会去执行invoke方法

    根据xml配置文件的接口全限定名和相应的方法能够生成动态代理类。调用动态代理类的invoke方法,在invoke方法中会判断是否是一个类,如果不是就是接口。因为是接口,那么就生成MapperMethod对象,然后执行execute方法,将sqlSession和运行的参数传递进去。

     

    因为最后会执行execute方法,这个方法传入sqlSession和参数。

    执行MapperMethod的execute方法

    根据入参去执行相应的execute方法,会区分你是想做增删改查的哪个操作。

     

    根据上下文条件会跳转到相应的方法去执行。最后通过sqlSession的方法去执行。

     

    核心---SqlSession的四大对象

    映射器最后调用SqlSession的方法来执行数据库操作的,具体的执行时通过一系列的Handler来执行。四个核心为:

     

    Executor执行器的类型

     

    执行器有三种类型,根据用户的配置文件中的设置进行创建。

    创建之后,通过插件设置一层层的动态代理对象。

    和插件之间的关联

     

    Executor的invoke方法执行

     

    如何调用三个handler?

    1. 使用StatementHandler做预编译。

    2. 使用ParameterHandler设置参数完成预编译。

    3. 执行查询后使用ResultSetHandler去包裹查询的结果。

    StatementHandler

    数据库会话器,根据使用的Executor会生成相应的StatementHandler,使用适配器的模式,通过switch…case判断executor来生成对应的handler。然后通过插件做代理对象的封装。

    创建了StatementHandler后如何执行查询呢?

     

    ParameterHandler设置参数

    从参数对象parameterObject中取参数,然后通过typeHandler去进行参数处理后进行设置。然后执行sql语句。

    ResultSetHandler结果处理器

    对查询的结果进行组装。

    Sqlsession运行总结

     

     

  • 相关阅读:
    如何提高软件可维护性
    UML系列 (二)四种关系
    软件工程
    软件工程需求规格说明书
    机房收费系统可行性分析报告
    ThreadStaticAttribute 的使用
    WPF:Border 控件
    几篇介绍在页面中引用脚本文件的技术文档
    收集两篇介绍 Fildder 的文章
    收集三篇关于数据库主键设计的文章
  • 原文地址:https://www.cnblogs.com/buptyuhanwen/p/9366218.html
Copyright © 2011-2022 走看看