1.hello world
①设计好数据库和java对应的实体类
②设置全局配置文件
③配置映射文件
④编写测试类
2.接口式编程
①创建一个对应接口
②修改映射文件的某些配置
③编写测试类
3.全局配置文件(标签的顺序不能打乱)
①settings
②typeAliases(别名处理器)
③.typeHandlers(类型处理器)
④.plugins(插件)
插件能拦截四大对象的方法
1.Executor
2.ParameterHandler
3.ResultSetHandler
4.StatementHandler
⑤.environments(运行环境:可以配置多种环境)
⑥.databaseIdProvider数据库厂商
⑦.mappers
上面第三点,还必须映射文件名和接口名一致
有的公司使用以下方法:
mybatis还有另一种方式:没有映射文件,sql语句利用注解写在接口上
4.映射文件
select、insert、update、delete
如果想要获取自增主键,可以采用以下方式(oracle不支持自增)
-------------------------------------------------------参数处理-------------------------------------------
①如果传过来的参数是单个参数,mybatis不做特殊处理,例如
②如果传过来的参数是多个参数,mybatis会将多个参数封装成map结构
所以以下书写结构是错误的:
解决方法1:(使用mybatis给定的map结构 param1、param2…)
解决方法2:(使用@param注解)
在参数很多有五六个的情况下:
1.如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo
2.如果不是我们业务逻辑里的模型也不经常使用的话,我们可以使用map
3.如果不是我们业务逻辑里的模型但是经常使用的话,我们可以创建一个实体类
特别注意:
如果穿过来的参数是Collection类型或者数组也会进行特殊处理
例如: public Employee getEmployeeByI的(List ids);
取第一个值: #{list[0]}
Collection------->colllection[0]
Array-------------->array[0]
经典面试题:#{}和${}的区别
#{}和${}的区别
#{}是以预编译的形式,将参数设置到sql语句当中,防止sql注入
${}:取出的值直接拼装在aql语句中,会有安全问题,原生jdbc不支持占位符的地方,就可以使用
sslect查询返回list集合:
返回一个map对象
①key为列名,value为列名对应的值(map里只有一个对象)
②key为指定列的值,value为employee对象
resultMap(自定义结果集映射规则)
resultMap更强大的用法:
①(级联属性封装结果类)
一个类中有自定义的属性,可以使用如下方法:
②使用association
③使用分步查询
创建department对应的接口和xml文件
在全局配置文件中注册映射文件
在employee.xml文件中使用分步查询:
延迟加载:对于上面的分步查询中department对象用到的时候才加载
----------------collection嵌套结果集的方式,定义关联的集合类型元素的封装------------------
一个实体类里有一个集合属性就可以用collection
例如:查询部门时,将部门下的所有员工都查询出来
在分布查询当中,第二步查询需要的参数是通过column传递的,如果有多列的值要传递过去怎么办?
解决方法:封装成一个map
分步查询:association、collection里面的select属性
5.动态sql
if、chose、trim、foreach
if
当第一个if标签中的表达式不成立,会造成语法错误,例如
解决方法1:在where后加一个 1=1 这样就不会出现语法错误
解决方法2:使用wherer标签,只会去掉写在开头的and,如果and写在后面,则不起效果
where
解决以上问题
trim
自定义截取规则
这样的话,如果where后面有一个多余的and,就会被去除
choose
与if的区别:
if只要满足条件就会拼接,而choose只能选择一个
set
set与if配合使用
正确写法:
for each属性(对于sql中的in)
两个内置参数
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装成一个map,_parameter就是这个map
databaseId:代表当前数据库的别名
bind
bind‘可以将一个ognl表达式的值绑定到一个变量中,方便后面引用这个变量的值
sql(抽取可重用的sql片段,方便后面引用)
经常将要查询的列名或者插入用的列名抽取处出来,方便引用。
与include配合使用,进行引用
6.缓存机制
mybatis默认定义了两级缓存:一级缓存和二级缓存
一级缓存
一级缓存:与数据库同一次会话中查询到的数据会放在本地缓存当中,以后如果需要获取相同的数据,直接从缓存当中拿
一级缓存的失效情况:
①sqlsession不同
②同一个sqlsession,查询条件不同(一级缓存中还没有这个数据
③两次查询中,有写操作
④sqlsession相同,但两次查询之间清除了缓存
------------------------opensession.clearCache()--------------------------------
二级缓存
二级缓存:基于namespace级别的缓存
开启二级缓存:
清空缓存
方法一:
方法二:
一级缓存和二级缓存的联系?
只有一级缓存的会话关闭,数据才会到二级缓存当中。
新的会话会先查找二级缓存是否有对应的数据,然后再找一级缓存,最后数据库
7.Mybatis分层架构
8.Mybatis运行原理
1.获取sqlsessionFactory对象:
解析文件中的每一个信息保存在Configuration中,返回包含Configuration的defaultSqlSession
注意:一个MapperStatement代表着一个增删改查标签的详细信息
②获取sqlSession对象
返回一个DefaultSQLSession对象,包含Executor和Configuration;
这一步会创建Executor对象
3.获取接口的代理对象
代理对象里面包含DefaultSqlSession()
④执行增删改查
插件原理
四大对象:
executor:
StatementHandler:预编译参数和封装结果,创建StatementHandler时也创建了下面两个
ParameterHandler:预编译参数
ResultSetHandler:封装结果
插件可以使用动态代理机制一层层的包装目标对象,而实现在目标对象执行目标方法之前进行拦截的效果。
在每创建一个四大对象前都会执行以下操作:
插件的编写过程:
多个插件的运行流程
创建代理对象时,按照配置文件顺序创建层层代理对象,执行目标方法时,按照逆向顺序执行。
分页插件的使用(PageHelper)
①下载分页插件需要的jar包
https://pagehelper.github.io/
②在全局配置文件中注册插件
③代码的编写
批量操作
执行器有三种:
simple、reuse、batch