1. 介绍
Mybatis: 和数据库交互的持久层框架(sql映射框架);
在mybatis之前,原始的数据库操作有 jdbc — dbUtils(QueryRunner) ----JdbcTemplate — ; 这些工具太麻烦,sql是硬编码
2 .环境搭建
2.1 创建一个java工程
2.2 创建安测试库,测试表,以及封装数据的javabean,和操作数据库的dao接口
2.3 用mybatis操作数据库
2.3.1 导包
mysql-connector-java-5.1.37-bin.jar
mybatis-3.4.1.jar
log4j-1.2.17.jar
2.3.2 写配置
- 第一个配置文件–全局配置文件: (称为mybatis的全局配置文件,指导mybatis如何正确运行,比如连接哪个数据库)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--引入我们自己编写的每一个接口的实现文件-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
- 第二个配置文件–sql映射文件:(编写每一个方法都如何向数据库发送sql语句,如何执行…相当于接口的实现类)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
- 上面我们写的dao接口的实现文件,mybatis默认是不知道的,
需要在全局的配置文件中注册
<!--引入我们自己编写的每一个接口的实现文件-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
note:
parameterType 可以永远都不写
增删改的sql 中不用写返回值类型 --增删改返回的是影响多少行; 如果返回的是boolean(影响0行返回的是false)
2.3.3 测试
- 根据全局配置文件先得到SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- 得到SQLSession对象 (相当于以前的获取一条连接)
SQLSession openSession = sqlSessionFactory.openSession();
- 通过当前的session获取dao接口的实现(映射器)
EmployeeDao dao = openSession.getMapper(EmployeeDao.class);
//try{
dao.xxxById(); //调用查询方法
}finally{
//跟新数据库时必须commit,否则不生效(查询方法可以不用);也可在创建session时传入true参数代表自动提交: SQLSession openSession = sqlSessionFactory.openSession(true);
//openSession.commit();
openSession.closs();
}
3. mybatis的两个配置文件
3.1 全局配置文件
mybatis-config.xml : 指导mybatis正确运行的一些全局配置
全局配置文件中的属性:
3.2 sql映射文件
EmployeeDao.xml: 相当于对dao接口的一个实现描述
通过session获取dao接口的实现
EmployeeDao dao = openSession.getMapper(EmployeeDao.class);
: 获取到的是接口的代理对象(mybatis自动创建的)
SqlSessionFactory创建SQLSession对象, factory只new一次就行了
SqlSession: 相当于connection 和数据库进行交互的,和数据库的一次会话,每次就应该创建一个新的sqlSessin;
3.2.1 sql映射文件中的标签
-
cache , cache-ref :和缓存相关
-
delete ,insert , selete , update
-
parameterMap : 参数map , (废弃)…原本是做复杂参数映射的
-
resultMap: 结果映射: 自定义结果集的封装规则
自定义每一列数据和javaBean的映射规则
type=" " : 指定为哪个javaBean自定义封装规则;全类名
id=" " : 唯一标识: 让别名在后面引用
主键列:<id property="id" column="id"/>
主键列 中的 column=" " : 指定哪一列是主键
主键列 中的 property=" " : 指定cat的哪个属性封装id之一类
结果集中含有对象的写法
或者
含集合的情况
-
sql : 抽取可重用的sql
3.2.1.1 delete,update,insert
4. mybatis中# 与$ 的区别
在mybatis中,取值有两种方式:
#{属性名} : 是参数预编译的方式,参数的位置都是用? 代替,参数后来都是预编译设置进去的,安全,不会sql注入;
${属性名} : 不是参数预编译,而是直接和sql语句进行拼串;不安全; 但是他可以动态的获取表名;
5. 动态sql
5.1. <where>
5.2. <if>
5.3. <trim>
trim: 截取字符串:
prefix=" " : 前缀: 为我们下面的sql整体添加一个前缀
prefixOverrides=" " : 去除整体字符串前面多余的字符
suffix=" " : 为整体添加一个后缀 ;
suffixOverrides=" " : 后面哪个多了可以去掉
5.4. <foreach>
foreach: 用来遍历集合
里面的属性有:
collection="" : 指定要遍历的集合的key ,一般可以指定list ,map等类型
- 注: 当时自定义类型时,这个值并不是形参的变量名,在接口中用
@Param
指定的名close="" : 以什么结束
index="" : 索引:
- 如果遍历的是一个
list
,index表示 指定的变量保存了当前的索引;item
: 保存当前遍历的元素的值- 如果遍历的是一个
map
,index : 指定的变量就是保存了当前遍历的元素的key,item
:就是保存当前遍历的元素的值item=“变量名” : 每次遍历的元素起一个变量名方便引用
open="" : 以什么开始
separator="" : 每次遍历的元素的分隔符
5.5 <choose
分支选择标签
6. 缓存机制
Mybatis缓存机制 : Map ; 能保存查询出的一些数据;
一级缓存: 线程级别的缓存; 本地缓存; SqlSession级别的缓存;
二级缓存: 全局范围的缓存; 除了当前线程;SqlSession能用外其他也可以使用;
6.1.一级缓存
6.1.1. mybatis的一级缓存(SqlSession级别的缓存),默认存在;
只要之前查询过的数据,mybatis就会默认保存在一级缓存中(Map);下次获取直接从缓存中拿;
6.1.2. 一级缓存失效的几种情况
- 不同的SqlSession
- 同一个方法,不同的参数
- 在同一个SqlSession期间执行任何一个增删改操作,增删改会把缓存清空;
- 手动清空缓存的情况
openSession.clearCache();
6.2. 二级缓存
一级缓存,SqlSession关闭活或者提交后,一级缓存的数据会放在二级缓存中;
6.2.1. 开启二级缓存
mybatis默认是没有开启二级缓存的;
- 全局配置文件中开启
<settings>
<!--开启全局缓存开关-->
<setting name="cacheEnabled" value="true"/>
</settings>
- 在sql映射文件中(xxxDao.xml),让其使用二级缓存
<!-- 使用二级缓存-->
<cache></cache>
- 不要忘记序列化哦
6.2.2.
- 不会出现一级缓存和二级缓存中有同一个数据
- 二级缓存中: 一级缓存关闭了就有了;
- 一级缓存中: 二级缓存中没有次数据,就会看一级缓存,一级缓存没有就去查数据库;数据库的查询后的结果 放在一级缓存中;
- 任何时候都是先看二级缓存,再看一级缓存,如果大家都没有就去查询数据库;
6.3 缓存有关设置
- 全局setting的
cacheEnable
: 配置二级缓存的开关. 一级缓存一直是打开的; - select 标签的
useCache
属性: 配置这个select是否使用二级缓存.一级缓存一直是使用的; - sql标签的
flushCache
属性: 增删改默认flushCache=true
。sql执行以后,会同时清空一级和二级缓存。查询默认flushCache=false
。 - sqlSession.clearCache(): 只是用来清除一级缓存。
- 当在某一个作用域(一级缓存Session/二级缓存NameSpace) 进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear。
7. 整合第三方缓存
4 . mybatis的四大组件
4.1 Executor
执行器: 执行sql
4.2 ParameterHandler
参数处理器: 它会调用typeHandlers
(类型处理器)来进行参数转换
4.3. ResultSetHandler
结果集处理器: 负责将查询出的结果集 封装成指定的对象