mybatis 梳理

88 阅读4分钟

1 sqlSessionFactory 与 SqlSession 的用途

blog.51cto.com/u_14479502/…

sqlSessionFactory 创建与数据库的链接,放在本地内存中。整个项目中是单例的。

SqlSession 每次sql 执行都需要一个 SqlSession, 里面封装了底层 JDBC 连接。

每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的。同时,SqlSession实例也是线程不安全的,因此其使用范围最好在一次请求或一个方法中, 绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围(如Servlet的HttpSession)中使用。 使用完SqlSession对象后要及时关闭,通常可以将其放在finally块中关闭。

2 mybatis 加载过程

(1)通过Bean 生成 SqlSessionFactory

@Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource,
                                               PaginationInterceptor paginationInterceptor)

(2)SqlSessionFactory 中找到了Spring 默认的 DataSource

 sqlSessionFactory.setDataSource(dataSource);

(3)通过mapperLocations 找到了 xml 文件

sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/*.xml"));

(4)每一个 xml 中 通过 mapper namespace 找到了 对应的接口类。

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.XXX.yyy.offline_pkg.dao.mapper.PkgCirclePushConfigMapper" >
  

(5)select 中的resultMap 是结果映射的实体类

resultMap中的 type 是具体的实体类。 extends 是继承的关系。 result 中 column 是数据库的字段,property 是实体类的属性,jdbcType 是列对应的数据库类型。


<resultMap id="BaseResultMap" type="com.ushareit.gaia.offline_pkg.model.bean.PkgCirclePushConfig" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="app_id" property="appId" jdbcType="VARCHAR" />
    <result column="business_type" property="businessType" jdbcType="VARCHAR" />
    <result column="source_info_id" property="sourceInfoId" jdbcType="INTEGER" />
    <result column="source_info_name" property="sourceInfoName" jdbcType="VARCHAR" />
    <result column="status" property="status" jdbcType="INTEGER" />
    <result column="time_interval" property="timeInterval" jdbcType="INTEGER" />
    <result column="cmd_id_type" property="cmdIdType" jdbcType="TINYINT" />
    <result column="exec_time" property="execTime" jdbcType="TIMESTAMP" />
    <result column="end_time" property="endTime" jdbcType="TIMESTAMP" />
    <result column="single_cmd_expire_time" property="singleCmdExpireTime" jdbcType="INTEGER" />
    <result column="create_user" property="createUser" jdbcType="VARCHAR" />
    <result column="update_user" property="updateUser" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
  </resultMap>

  <resultMap id="ResultMapWithBLOBs" type="com.ushareit.gaia.offline_pkg.model.bean.PkgCirclePushConfig" extends="BaseResultMap" >


 <select id="selectValid" resultMap="ResultMapWithBLOBs">
    select
    <include refid="Base_Column_List" />
    from pkg_circle_push_config
    where status = 1 and exec_time &lt;= #{nowDate} and end_time &gt;= #{nowDate}
  </select>

3 springboot 中 查询没有体现出 sqlSession, 也没有关闭,应该是自动帮我们操作了,需要确认一下具体在哪个地方做了?

blog.csdn.net/RicardoDing…

解答:spring boot 通过动态代理,在SqlSessionTemplate 的SqlSessionInterceptor 中,每次执行完 sql, 就会执行closeSqlSession。

4 返回结果如果是多个实体类的组合,则可以通过如下方式:

(1)当用到对应 B 的属性少时,直接在对象A里面,插入B 的几个字段 (2)当用到对应 B 的属性多时,完全可以在对象 A 中 新增一个对象 B的对象,在 mapper 中select 时 返回 B.userName ,B.userAge 等。

5 为什么多参数时,不使用@Param 也可以?

xiaogd.net/md/use-java…

另注: 如果你使用 spring boot 2.0 及以后的版本并依赖了 spring-boot-starter-parent, 默认情况下已经启用了这一选项:

查看 IDEA 中的配置,确实默认已经有了。

6 mapper 接口的动态代理实现

mybatis 对mapper 接口实现了动态代理类。没有对某个 具体类进行代理 ,而是通过代理转化成了对其他代码的调用。

具体调用时,通过接口限定名和当前调用的方法名的组合得到一个 ID, 这个 id 就是 xml 中 namespace 和具体方法 id 的组合。

7 mybatis 一二级缓存的用途 以及他们的 区别

7.1 比对

tech.meituan.com/2018/01/19/…

一级缓存:sqlSession 级别,主要利用了本地的 hashmap 来实现

二级缓存:sqlSessionFactory 级别,可以跨 sqlSession. 但是粒度只能到 namespace 级别(一个 Mapper.xml 文件就是一个 namespace).如果跨 namespace ,会有脏数据的问题。

7.2 如何解决二级缓存跨 namespce 读取到脏数据的问题。

解决方案: string.quest/read/305128…

(方案1)关闭一级缓存,并将查询的sqlsession改为自动提交 在spring中也不一定发生,创建时一般为单例的mapper,每次查询都会创建新的sqlsession(若开启事务则是同一sqlsession),所以可以避免,不用担心。

(方案2)不使用缓存

8 mybatis 通过一个插件,了解 mybatis 的源码流程

todo:

9 现在的 mybatis 执行都默认开启了自动提交,执行了一条语句就会提交了,所以 一般一级缓存不生效。也就是说 在同一个事务中时,才会命中缓存。

zhuanlan.zhihu.com/p/142794376

10 mybatis 实体类跟 映射 代码逻辑

www.cnblogs.com/java-chen-h…

zp: 拿到结果,将结果转换为 实体类。

11 mybatis 事务 配置 dataSource, 跟 mybatis 自己的事务不是同一个吗?

www.cnblogs.com/java-chen-h…

zp: 如果开启了 spring 的@Transaction, spring 事务会创建 connection, 并放入 ThreadLocal, 后面 mapper 的执行也会使用 spring 创建的connection。如果没有开启 spring 的事务,则 mapper 会自己创建一个 connection, 并放入 ThreadLocal.

12 sql 执行过程分析

www.cnblogs.com/java-chen-h… www.cnblogs.com/java-chen-h…

13 mybatis-plus 跟 mybatis 的关系???

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。