Mybatis动态sql

1、多表关联的嵌套查询

将一个多表关联查询拆分为多次查询,先查询主表数据,然后查询关联表数据.

select="findDeptByID" column="dept_id">

(1). select:指定关联查询对象的 Mapper Statement ID 为 findDeptByID

(2). column="dept_id":关联查询时将 dept_id 列的值传入 findDeptByID,

并将 findDeptByID 查询的结果映射到 Emp 的 dept 属性中

(3).collection 和 association 都需要配置 select 和 column 属性,两者配置方法

相同

2、注解

一般写在Dao中接口的抽象方法的上面,可以代替简单的sql操作,比如一个简单的增加操作,这个时候在对应的mappers映射文件xml中就不需要在写标签了。

 

注:我们使用注解一般是简单的且只涉及一张表的操作,而涉及多张表的复杂操作我们还是在xml文件中设置

注:我们一般在定义类中的属性时,一般不定义基本类型,如int,我们需要定义成integer类型,即引用类型,因为引用类型的默认值都为null,这样在判断时就都为null了,就不需要每一种基本类型都使用不同的默认值

3、动态sql

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。 如果你有使用JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么 的痛苦,确保不能忘了空格或在列表的最后省略逗号。动态 SQL 可以彻底处理 这种痛苦。

Mybatis实现动态sql的关键字有:

1.if where

标签会对传入的条件进行判断 ,如果满足条件,就将if标签中的sql语句与前面的sql语句进行拼接,不满足则跳过。

标签会进行判断,如果它包含的子标签(一般是if)又返回值,就会在其前面插入一个‘where’,于此同时,他还会根据情况将子标签前面的and和or进行剔除

举例:

Mybatis动态sql_第1张图片

 

2.trim

标签的功能是可以实现代替其他标签的功能,但同时又比其他标签更加灵活

比如通过设置它的属性就可以实现where标签的功能

他有四个标签,分别是:prefix,prefixOverrides,suffix,suffixOverrides

若有子句

prefix,suffix 是将其属性值分别放在子句之前和之后。

prefixOverrides,suffixOverrides是删除子句首和子句尾的指定内容。

例如where标签用trim来实现如下:


  ...

3.choose when otherwise

choose标签实现多路选择,当choose下的when标签条件满足时,就将when中的sql拼进外面的sql,反之若不满足,则将下面的otherwise标签中的sql拼进总sql。

例如:

Mybatis动态sql_第2张图片

4.set

标签是在我们进行update操作时使用。子句

它可以为我们删除子句尾的',',当子句中有内容时,会自生成set在子句首。

Mybatis动态sql_第3张图片

 

同样的,set标签也可以使用trim标签来代替,

子句

意思就是当子句中有内容时,会在子句首生成set,反之不生成;然后就是在删除字句尾的','

5.foreach

foreach标签的使用场景是对集合进行遍历,并可以自定义的设置

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及各个元素之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

例如:

Mybatis动态sql_第4张图片

 

最终效果是:select * from student where no in (100,101)

4、特殊符号处理

在 mybatis 中的 xml 文件中,存在一些特殊的符号,比如:<、>、"、&、<> 等,正常书写 mybatis 会报错,需要对这些符号进行转义。具体转义如下所示:

Mybatis动态sql_第5张图片

 

除了可以使用上述转义字符外,还可以使用来包裹特殊字符。如

下所示:

AND #{id} ]]>

是 XML 语法。在 CDATA 内部的所有内容都会被解析器忽略。但是有个问题那就是

等这些标签都不会被解析,所以 我们只把有特殊字符的语句放在 尽量缩小 的范围。

5、Mybatis缓存

Mybatis缓存的作用是为了减轻数据库的压力,提高查询性能。缓存实现的原理是从数据库中查出来的对象不删除,而是将其存储在缓存中,当我们再次查询查询同样的对象时,就直接调用缓存中的对象,不再向数据库执行select,减少了数据库的使用频率,从而提高了数据库的性能。

Mybatis中有一级缓存和二级缓存

(1)一级缓存

一级缓存的作用域是一个sqlsession对象,第一次查询数据时会保存到sqlsession对象中,第二次如果查询相同的数据,则直接从sqlsession获取,直接获取的前提是这期间这个对象中的数据没有改变,即增删改操作;反之,若有改变,则会自动清除sqlsession缓存,重新进行查询,这并不代表我们关闭了sqlsession。

消除sqlsession缓存的方式(清除缓存并不代表着关闭sqlsession):

1.存储期间数据发生改变,自动清除缓存;

2.手动清除:sqlsession.clearCache();

  1. sqlsession关闭时会清除缓存。

(2)二级缓存

二级缓存是多个sqlsession共享的,是sqlsession factory 级别的,根据 mapper 的 namespace 划分区域 的,相同 namespace 的 mapper 查询的数据缓存在同一个区域,如果使用 mapper 代理方法每个 mapper 的 namespace 都不同,此时可以理解为二级缓 存区域是根据 mapper 划分。

每次查询会先从缓存区域查找,如果找不到则从数据库查询,并将查询到数据写 入缓存。Mybatis 内部存储缓存使用一个 HashMap,key 为 hashCode+sqlId+Sql 语句。value 为从查询出来映射生成的 java 对象。

sqlSession 执行 insert、update、delete 等操作 commit 提交后会清空缓存区域,防止脏读数据。

(3)二级缓存的配置

1.在全局配置文件中的目录下启用二级缓存,

如下代码所示,当 cacheEnabled 设置为 true 时启用二级缓存,设置为 false 时禁用二级缓存。

2、让我们的model包中的各个类(admin,student,grade)都实现序列化接口 Java.io. Serializable。

3、配置映射文件,在 Mappers 各个映射文件中添加,表示此 mapper 开启二级缓存。 当 SqlSeesion 关闭时,会将数据存入到二级缓存.

注:cache会有一些属性,例如:

这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

eviction中属性可用清除策略有:

  • LRU – 最近最少使用:移除最长时间不被使用的对象。

  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

  • SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。

  • WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

默认的清除策略是 LRU。

你可能感兴趣的:(笔记,mybatis,sql,缓存)