Mybatis整合Spring

2021-01-21 11:13

阅读:641

标签:targe   cep   figure   image   定义   red   通过   基本   实现类   

1,使用配置


1.1 引入mybatis整合spring的jar包

       
       
            org.mybatis
            mybatis-spring
            ${mybatis-spring.version}
       

       
       
            org.mybatis
            mybatis
            ${mybatis.version}
       

1.2,在spring的applicationContext.xml中配置SqlSessionFactoryBean,它是用来帮助我们创建会话的。同时配置需要扫描Mapper接口的路径。

   
   
       
       
       
   
   
       
   

2,创建会话工厂


    我们在spring配置文件中配置了SqlSessionFactoryBean,我们来看下这个类。
技术图片
    它实现了InitializingBean接口,所以要实现afterPropertiesSet()方法,这个方法会在bean的属性值设置完的时候被调用。
    又实现了FactoryBean接口,所以它初始化的时候,实际上是调用getObject()方法,它里面调用的也是afterPropertiesSet()方法。
    在afterPropertiesSet()方法中,我们实际上执行的还是mybatis那一步来创建初始化configuration对象和解析mapper文件,把接口和对应的MapperProxyFactory注册到mapperRegistry中。
    最后调用sqlSessionFactoryBuilder.build(targetConfiguration)返回一个DefaultSqlSessionFactory。

3,创建SqlSession


3.1,可以直接使用DefaultSqlSessionFactory创建吗?
    不能,它是不安全的,Spring用SqlSessionTemplate对SqlSession进行了包装。在编程式的开发中,我们会在每次请求的时候创建一个SqlSession,但是Spring中只有一个SqlSessionTemplate。SqlSessionTemplate中有SqlSession中的所有方法,不过它都是通过一个代理类对象实现的,这个代理对象是在构造方法里面通过一个代理类创建的。

    this.sqlSessionProxy = (SqlSession) newProxyInstance(
        SqlSessionFactory.class.getClassLoader(),
        new Class[] { SqlSession.class },
        new SqlSessionInterceptor());
    所有的方法都会先走到内部代理类SqlSessionInterceptor的invoke方法,

3.2,怎么拿到一个SqlSessionTemplate?
    Dao继承Mybatis提供的SqlSessionDaoSupport,就可以获得。
    为了减少代码量我们可以建立一个BaseDao继承SqlSessionDaoSupport拿到SqlSessionTemplate对象,然后定义一些基本的操作,其它的Dao都继承它。

3.3,有没有更好的方法拿到SqlSessionTemplate?
    3.2的方式,需要我们的每一个Dao层的接口想拿到SqlSessionTemplate对象,都需要去继承BaseDao编写一个实现类,工作量并不小,另一个我们调用方法的时候其实还是会使用硬编码的方式,MapperProxy根本用不上。那怎么解决呢?我们使用接口的扫描注册。

4,接口的扫描注册


    在Service层使用@Autowired自动注入Mapper接口,需要保存在BeanFactory中,也就是说接口肯定在Spring启动的时候就被扫描了,注册过的。
技术图片

4.1,MapperScannerConfigurer是BeanFactoryPostProcessor的子类,可以通过编码的方式修改,新增或者删除某些Bean的定义。我们只需要重写postProcessBeanDefinitionRegistry()方法,在这里面操作Bean就行了。

技术图片
技术图片
技术图片

4.2,ClassPathMapperScanner中的doScan方法调用了processBeanDefinitions()方法,在该方法中,注册beanDefinitions的时候,BeanClass被修改为MapperFactoryBean ?为什么要把它修改为MapperFactoryBean呢,因为MapperFactoryBean继承了SqlSessionDaoSupport,可以拿到SqlSessionTemplate。

5,接口注入使用


    我们使用Mapper的时候,只需要在加了Service注解的类里面使用@Autowired注入Mapper接口就好了。

技术图片

    我们启动Spring去实例化EmployeeService的时候,发现它依赖了employeeMapper,这时候我们要根据它的名字去BeanFactory中获取它的BeanDefinition,再从BeanDefinition中获取他的BeanClass,上面已经知道这时候的BeanClass是MapperFactoryBean,因为它实现了FactoryBean接口,同样是调用getObject方法,

技术图片

技术图片

技术图片

技术图片

    通过调用SqlSessionDaoSupport中的getSqlSession拿到SqlSessionTemplate。接着调用mapperRegistry的getMapper方法,然后通过MapperProxyFactory新建一个MappProxy代理对象,最后调用Mapper接口的方法,也是执行MapperProxy的invoke方法。

    SqlSessionTemplate:Spring中SqlSession的替代品,线程安全的,通过代理的方式调用DefaultSqlSession的方法。
    SqlSessionInterceptor(内部类):代理对象,用来代理DefaultSqlSession对象,在SqlSessionTemplate中使用。
    SqlSessionDaoSupport:用于获取SqlSessionTemplate,只需要继承它就行,
    MapperFactoryBean:注册到IOC容器中替换接口类,它继承SqlSessionDaoSupport用于获取SqlSessionTemplate。
    SqlSessionHolder:控制SqlSession和事务。

6,设计模式总结

    工厂:SqlSessionFactory,MapperProxyFactory
    建造者:XMLConfigBuilder
    单例模式:SqlSessionFactory,Configuration
    代理:
        MapperProxy代理Mapper接口
        Plugin 插件
    模板:BaseExecutor与子类SimpleExecutor,BatchExecutor和ReuseExecutor
    装饰器:CachingExecutor对其他Executor额装饰。
    责任链:InterceptorChain
                    


来自为知笔记(Wiz)


Mybatis整合Spring

标签:targe   cep   figure   image   定义   red   通过   基本   实现类   

原文地址:https://www.cnblogs.com/gaojf/p/12896079.html


评论


亲,登录后才可以留言!