1 sqlSessionFactory 与 SqlSession 的用途
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 <= #{nowDate} and end_time >= #{nowDate}
</select>
3 springboot 中 查询没有体现出 sqlSession, 也没有关闭,应该是自动帮我们操作了,需要确认一下具体在哪个地方做了?
解答:spring boot 通过动态代理,在SqlSessionTemplate 的SqlSessionInterceptor 中,每次执行完 sql, 就会执行closeSqlSession。
4 返回结果如果是多个实体类的组合,则可以通过如下方式:
(1)当用到对应 B 的属性少时,直接在对象A里面,插入B 的几个字段 (2)当用到对应 B 的属性多时,完全可以在对象 A 中 新增一个对象 B的对象,在 mapper 中select 时 返回 B.userName ,B.userAge 等。
5 为什么多参数时,不使用@Param 也可以?
另注: 如果你使用 spring boot 2.0 及以后的版本并依赖了 spring-boot-starter-parent, 默认情况下已经启用了这一选项:
查看 IDEA 中的配置,确实默认已经有了。
6 mapper 接口的动态代理实现
mybatis 对mapper 接口实现了动态代理类。没有对某个 具体类进行代理 ,而是通过代理转化成了对其他代码的调用。
具体调用时,通过接口限定名和当前调用的方法名的组合得到一个 ID, 这个 id 就是 xml 中 namespace 和具体方法 id 的组合。
7 mybatis 一二级缓存的用途 以及他们的 区别
7.1 比对
一级缓存: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 实体类跟 映射 代码逻辑
zp: 拿到结果,将结果转换为 实体类。
11 mybatis 事务 配置 dataSource, 跟 mybatis 自己的事务不是同一个吗?
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 的基础上只做增强不做改变,为简化开发、提高效率而生。