zoukankan      html  css  js  c++  java
  • myBatis 日记

    一级缓存默认开启, 有效范围是在当前sqlsession, 

    同一个SqlSession对象执行相同的sql并参数也要相同,缓存才有效。

     在同一个会话里面,多次执行相同的SQL 语句,会直接从内存取到缓存的结果

    一级缓存不足: 使用一级缓存的时候,因为缓存不能跨会话共享,不同的会话之间对于相同的数据可能有不一样的缓存。在有多个会话或者分布式环境下,会存在脏数据的问题。

    二级缓存的有效方范围是 Mapper(NameSpace), 多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存的作用范围更大。

    注入的单例 SqlSessionTemplate 内部包含SqlSessionProxy对象, 对每次SqlsessionTemplate的调用被代理为新创建的sqlsession的调用,所以sqlsessiontemplate每次调用都会有一个新的session生成. 

    SqlSession 持有了一个Executor 对象,用来封装对数据库的操作。

    SqlSession 持有了一个Configuration对象,用来保存所有配置信息。

    二级缓存范围更广,工作在SqlSession外部(如果启动二级缓存, myBatis在创建Executor时会自动对Executor进行装饰, 装饰器就是CacheingExecutor),而一级缓存存在于sqlsession内层, 所以一级缓存存在于二级缓存之前, 


    Mybatis基本框架


     SimpleExecutor, ReuseExecutor, BatchExecutor 区别

    SimpleExecutor:每执行一次update 或select,就开启一个Statement 对象,用完立刻关闭Statement 对象。
    ReuseExecutor:执行update 或select,以sql 作为key 查找Statement 对象,存在就使用,不存在就创建,用完后,不关闭Statement 对象,而是放置于Map 内,供下一次使用。简言之,就是重复使用Statement 对象。
    BatchExecutor:执行update(没有select,JDBC 批处理不支持select),将所有sql 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement 对象,每个Statement 对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC 批处理相同。

    获得Mapper 对象的过程,实质上是获取了一个MapperProxy 的代理对象。

    MapperProxy 中有sqlSession、mapperInterface、methodCache。

    MapperProxy执行过程

    org.apache.ibatis.binding.MapperProxy#invoke
        org.apache.ibatis.binding.MapperMethod#execute
            org.apache.ibatis.binding.MapperMethod#executeForMany
                org.apache.ibatis.session.SqlSession#selectList

      

    MapperMethod 里面主要有两个属性, 一个是SqlCommand , 一个是MethodSignature,这两个都是MapperMethod 的内部类。

    根据不同的type 和返回类型:调用convertArgsToSqlCommandParam()将参数转换为SQL 的参数。调用sqlSession 的insert()、update()、delete()、selectOne ()方法,我们以查询为例,会走到selectOne()方法。


     MyBatis设计模式


    MyBaits 支持哪些数据源类型

    UNPOOLED:不带连接池的数据源。
    POOLED : 带连接池的数据源, 在PooledDataSource 中维护PooledConnection。

    JNDI:使用容器的数据源,比如Tomcat 配置了C3P0。
    自定义数据源:实现DataSourceFactory 接口,返回一个DataSource。
    当MyBatis 集成到Spring 中的时候,使用Spring 的数据源。


    PooledDataSource 的getConnection()方法流程图:


    MyBatis 翻页的几种方式和区别?

    逻辑翻页:通过RowBounds 对象。
    物理翻页:通过改写SQL 语句,可用插件拦截Executor 实现


    MyBatis 集成到Spring 的原理是什么?

    SqlSessionTemplate 中有内部类SqlSessionInterceptor 对DefaultSqlSession进行代理;
    MapperFactoryBean 继承了SqlSessionDaoSupport 获取
    SqlSessionTemplate;接口注册到IOC 容器中的beanClass 是MapperFactoryBean。


    为什么SqlSessionTemplate 是线程安全的?

    其内部类SqlSessionInterceptor 的invoke()方法中的getSqlSession()方法:
    如果当前线程已经有存在的SqlSession 对象,会在ThreadLocal 的容器中拿到SqlSessionHolder,获取DefaultSqlSession。
    如果没有,则会new 一个SqlSession,并且绑定到SqlSessionHolder,放到ThreadLocal 中。
    SqlSessionTemplate 中在同一个事务中使用同一个SqlSession。
    调用closeSqlSession()关闭会话时,如果存在事务,减少holder 的引用计数。否则直接关闭SqlSession。


     #和$的区别:

    1、是否能防止SQL 注入:$方式不会对符号转义,不能防止SQL 注入
    2、性能:$方式没有预编译,不会缓存

    1、能用#的地方都用#
    2、常量的替换,比如排序条件中的字段名称,不用加单引号,可以使用$

  • 相关阅读:
    Python rindex()方法
    Python rfind()方法
    Python replace()方法
    服务器技术综述(三)
    服务器技术综述(二)
    服务器技术综述(一)
    TensorRT-优化-原理
    TensorRT-安装-使用
    TensorRT 加速性能分析
    GPU加速:宽深度推理
  • 原文地址:https://www.cnblogs.com/snow-man/p/10812294.html
Copyright © 2011-2022 走看看