目录
一、走进MyBatis
1.核心对象
- SqlSessionFact oryBuilder: 目的创建SQLSess ionF actory对象
- SqlSessionFactory:会话工厂,好比使用DataSource对象,目的:创建SalSession对象的.
- SqlSession:会话,不是HttpSession. 好比是Connection对象,该接口中提供了增删改查的方法.
2.MIyBatis的配置文件
- MyBatis全局配置文件/主配置文件:连接池、事务、关联映射文件、配置日志、定义类型别名(别名不区分大小写)等;
- MyBatis映射文件/Mapper文件:增删改查、结果集映射、缓存配置等;
- MyBatis映射文件的resultMap可以定义JavaBean中的属性与数据库中的字段名进行映射;而resultType无法进行映射;
3.OGNL表达式(对象图形-映射语言)
- #{name}、#{dept.id}等
- 如果当前上下文对象是JavaBean对象,# {属程名称}
- 如果当前上下文对象是Map对象,# {key}
- 如果当前上下文对象简单类型对象(基本类型/String),会直接取出参数值,而和花括号中的名称没关系,
4.生命周期和作用域
- SqlSessionFactoryBuilder:这个关可以被实例化、使用和丢弃, 一旦创建了SqlSessionFactory ,就不再需要它了。因此SqlSessionFactoryBuilder实例的最佳作用域是方法作用域。
- SqlSessionFactory:SqISessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用SqlSessionFactory的最佳实践是在应用运行期间不重复创建多次,保持单例。
- SqlSession:每个线程都应该有它自己的SqISession实例。SqISession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
5.Mapper接口
- Mapper文件和Mapper接口应该放在同一个包中.
- Mapper文件中的nanespace就设置为对应Mapper接口的全限定名称.
- Mapper文件中的操作的ID对应Mapper接口中的方法名称
6.参数处理
6.1解决传递多个参数的问题
- 把多个参数封装成JavaBean(XxxVO.java);
- 把多个参数封装成hashmap对象;
- 使用Param注解,底层原理就是使用了hashmap,Param注解中的字符串表示在Map中的key
- fun (@Param ( "username")String username, @Param ( "password") String password) :
6.2 # 和 & 符号的区别
- 使用#传递的参数会先转换为占位符(SQL语句已经编译确定),在通过设置占位符参数的方式来设置值(统统会给值使用单引号引起来),基于此可以防止SQL注入;
- 使用$传递的参数,直接把解析出来的数据作为SQL语句的一部分;如果我们写的内容应该作为SQL的一部分,此时应该使用$.此如要排序,分组;
7.注解开发
- 使用@Instert,@Update,@Delete,@Select注解
8.动态SQL
- if元素:<if test="minSalary!=null ">;注意 "<" 等价于"<" 小于号需要进行转义;
- choose元素:<choose> <when> <otherwise>
- where元素:判断查询条件是否有where关键字,如果没有会在第一个查询条件之前插入一个WHERE;查询条件以AND/OR开头,会在第一个查询条件上将它替换为WHERE;(建议if元素前面全部带上ADN/OR即可)
- set元素:主要用于update子句,类似于where元素的条件拼接;(会自动加上set,会自动去掉逗号,建议后面全部带上逗号)
- foreach元素:通常用在构建IN条件语句的时候;<foreach collection="ids" open="(" close=")" separator="," item="id">
- include元素:定义的sql语句,可以内嵌到其他语句<include refid= "base_where" />
二、对象关系设计
1.关联关系
- 一对一: 一个A对象属于一个B对象. 一个B对象属于一个A对象。(唯一 + 外键约束)
- 一对多:一个A对象包含多个B对象。(外键约束,外键在many的一方进行关联;为了去除冗余)
- 多对一:多个A对象属于一个B对象,并且每个A对象只能属于一个B对象。(同上)
- 多对多: 一个A对象属于多个B对象,一个B对象属于多个A对象。(通过一张中间表,包含老师ID和学生ID即可,包含两个外键,分别对应两张表;)
2.多对一对象查询
- association元素:在resultMap元素中进行额外的SQL配置(调用另一张Mapper.xml的sql语句)
- 使用额外的SQL进行查询where id=?即可;
问题:如果一次查询出所有员工信息,那么都要额外调用一次查询对应部门的SQL语句;
解决:太慢了,直接使用一条表连接SQL,代替额外SQL语句;
- 针对单属性对象,使用association元素,通常直接使用多表查询操作,也就是使用表连接查询进行映射;
- 使用额外SQL,适用于进入另一个详情页面的时候会用到;
3.一对多对象查询
- 针对集合属性对象,使用collection元素,通常使用延迟加载,也就是额外SQL处理;
- 一般都会是双向的one2many,而不会是单向的;
4.延迟加载
- 需要在全局mybatis的xml文件进行配置,配置开启延迟加载、设置不要积极地去查询关联对象、设置延迟加载触发的方法;
三、高级应用
1.一级缓存
- 也称之为本地缓存,默认已经开启,不能关闭.好比在SqlSession中存在一个Map, 用来缓存查询出来的对象;
- 作用域是SqlSession级别的,多个SqlSession不会共享;
2.二级缓存
- mapper级别,作用域是mapper文件的同一个namespace,多个SqlSession会共享;
- 一般的,只会对get方法做查询缓存默认情况下,ISNERT, DELTE, UPDATE操作都会去刷新缓存....对于删除和更改操作,刷新缓存是合理的.但是对象插入操作却没有必要.
3.流程分析
- 创建sqlsession对象,创建executor执行器,创建statementhandler,创建paramterhandler和resultsethandler(都依赖于typehandler)底层原理还是用到了JDBC
- 全局对象:configuration,mappedstatement(包括sqlsource,resultmap),boundsql;
4.插件
- 四大组件executor,statementhandler,parameterhandler,resultsethandle在创建对象时都会调用pluginAll方法利用动态代理进行拦截增强达到插件的效果;
- 自定义的插件拦截器,使用注解设定好给哪个组件的哪个方法进行增强即可,最后给全局mybatis文件进行配置即可;
5.PageHelper插件
-
以前的分页需要先查询出总数,在返回每页的数据,需要两条sql语句;
-
插件的原理就是对executor的query方法进行拦截增强,可以直接配置插件,然后只需要一条sql并且不需要加上limit;