目录
MyBatis的核心组件
SqlSessionFactoryBuilder(构造器):作用是根据配置信息生成SqlSessionFactory(工厂接口)
SqlSessionFactory:(工厂接口):作用是生成SqlSession(会话)
SqlSession:可以向数据库发送信息的,类似于request对象,或者jdbc的connection对象
SqlMapper(映射器):java接口与xml配置文件(或者注解)构成,作用是描述映射关系,sql语句,参数等
Configuration:解析配置文件的信息都会封装在这个对象当中,作用与整个MyBatis的生命周期
MyBatis的执行流程
1.根据配置文件创建SQLSessionFactory
- 创建SqlSessionFactoryBuilder对象,通过build()方法读取配置文件信息
- 解析配置文件中的信息,保存在configuration对象中
- 根据configuration返回sqlSessionFactory对象,new DefaultSqlSessionFactory(config)
2.通过SessionFactory来创建sqlSession :SqlSession sqlSession = sessionFactory.openSession();
3.通过创建的sqlSession获取jdk动态代理生成mapper接口的代理对象
代码步骤
@Test
public void getUserByName()throws Exception{
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper userMapper = openSession.getMapper(UserMapper.class);
List<UserModel> userModelList = userMapper.getUserByName("hejianfeng");
log.info("结果:{}", userModelList);
}
MyBatis的参数传递
1.单个参数的时候可以直接传递,框架不会做特殊处理 #{参数名/任意名}:取出参数值。
2.多个参数:mybatis会做特殊处理。多个参数会被封装成 一个map,
key:param1...paramN,或者参数的索引也可以
value:传入的参数值
#{}就是从map中获取指定的key的值;
注意:除了可以根据key值获取map中的参数外,还可以在接口中指定参数的key名称,这样可读性会更好一点,用的是@Param注解
List<UserModel> getUserByNameAndAge(@Param("name") String name,@Param("age") int age);
3.直接传递一个map,将参数以KV的方式传递,写sql的时候要根据key的名称获取参数就可以了
4.传递Java对象,写sql的时候按照属性名称获取参数就好了
总而言之,在多个参数的情况下,都相当于map的参数传递
5.传递Collection
传递集合参数的时候,需要用collcetion来获取集合中的参数
<select id="getUserByName" resultType="model.UserModel">
SELECT * FROM t_user WHERE id IN (#{collection[0]},#{collection[1]})
</select>
MyBatis的缓存机制
在MyBatis中缓存分为一级缓存与二级缓存
一级缓存
SqlSession级别的缓存,每个SqlSession都有自己单独的一级缓存,多个SqlSession之间的一级缓存是相互隔离的,互不影响,mybatis中一级缓存是默认自动开启的。
一级缓存的工作原理是:在同一个sqlSession中执行相同的查询,会先去一级缓存中找,没有的话再去DB,获取之后再放入以及缓存
(跟用redis的原理差不多),但是这是基于HashMap的结构。
代码演示:
@Test
public void getUserByName()throws Exception{
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper userMapper = openSession.getMapper(UserMapper.class);
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
List<UserModel> userModelList = userMapper.getUserByName(idList);
List<UserModel> userModelList2 = userMapper.getUserByName(idList);
log.info("结果:{}", userModelList == userModelList2);//结果是true :说明两个对象相等,并且sql打印只有一次,说明只访问了一次数据库
}
一级缓存失效的情况:
1.两次查询中 ,出现了修改数据的情况,一级缓存会被清空
2.SqlSession.clearCache清理一级缓存
3.在mapper的<select >标签中 加上flushCache="true" ,表示该查询不使用以及缓存
二级缓存
鉴于一级缓存的局限性,就引入了二级缓存
mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession
二级缓存默认是没有开启的,需要在config.xml文件中进行配置
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
二级缓存的失效方式
- 对应的mapper中执行增删改查会清空二级缓存中数据
- select元素的flushCache属性置为true,会先清空二级缓存中的数据,然后再去db中查询数据,然后将数据再放到二级缓存中
- select元素的useCache属性置为true,可以使这个查询跳过二级缓存,然后去查询数据
MyBatis的插件编写
MyBatis如何进行分页
MyBatis的延迟加载
MyBatis的动态sql及其原理
MyBatis如何获取主键值
如何进行关联查询