zoukankan      html  css  js  c++  java
  • Mybatis整合Spring

    1,使用配置


    1.1 引入mybatis整合spring的jar包

            <!--mybatis 和Spring整合 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>${mybatis-spring.version}</version>
            </dependency>

            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>

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

        <!-- 在Spring启动时创建 sqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="configLocation" value="classpath:mybatis-config.xml"></property>
            <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.gupaoedu.crud.dao"/>
        </bean>

    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
                        




  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    HDFS HA高可用
  • 原文地址:https://www.cnblogs.com/gaojf/p/12896079.html
Copyright © 2011-2022 走看看