MyBatis入门学习三(缓存、高级查询、分页 插件)

目录

1、MyBatis缓存

1.1 一级缓存

1.2 二级缓存

1.2.1 MyBatis实现

1.2.2 第三方实现

2、高级查询

2.1 数据模型

2.2 创建数据库表

2.3 一对一查询

2.3.1 第一种方式

2.3.2 第二种方式

2.4 一对多查询

2.5 多对多查询

2.6 延迟加载

3、分页插件


1、MyBatis缓存

1.1 一级缓存

        MyBatis的一级缓存的作用域是session,当openSession()后,如果执行相同的SQL(相同语句和参数),MyBatis不再执行SQL,而是从缓存中命中返回。

        原理:Mybatis执行查询时首先去缓存区命中,如果命中直接返回,没有命中则执行SQL,从数据库中查询。

  1. 使用session.clearCache()清空缓存,强制查询不缓存。
  2. 在执行insert、update、delete时会清空缓存。

测试正常的一级缓存:

调用clearCache()方法强制清空缓存:

执行update语句清空缓存数据:

1.2 二级缓存

1.2.1 MyBatis实现

        MyBatis的二级缓存的作用域是一个mapper的namespace,同一个namespace中查询sql可以从缓存中命中。二级缓存是可以跨session的。即不同的sqlSession执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存,第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。

        开启二级缓存:在mapper.xml文件中加入 <cache /> 。

        【注意】在mybatis-config中有缓存的全局控制配置(cacheEnabled),默认是开启的,所以无需手动开启。如果设置为不开启,则所有在mapper.xml文件中的缓存配置将失效。

测试配置

在mapper.xml中加入<cache/>;之后测试如下:

      【注意】二级缓存需要将缓存的数据写入缓冲区,所以对应的对象需要实现序列化接口。也即上面的User需要实现Serializable接口。

在mapper.xml中的cache元素,它还可以设置其它的属性如下:

<cache eviction="FIFO"  flushInterval="60000"  size="512"  readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。

1.2.2 第三方实现

使用第三方缓存实现二级缓存,常见的有如下:

1)EHCache

mybatis-ehcache – MyBatis Ehcache | Reference Documentation

2)Memcache

mybatis-memcached – MyBatis Memcached | Reference Documentation

2、高级查询

2.1 数据模型

一个年级下有很多学生,一个学生只属于一个年级;

一个学生有且只有一个对应的地址;

一个学生可以选择多门课程,一个课程也可以被多个学生选择。

概念模型:

物理模型:

2.2 创建数据库表

导入《mybatis.sql》文件到数据库中,创建将要演示的数据库表及数据。

2.3 一对一查询

【需求】:根据学生ID查询学生信息包括学生的地址。

2.3.1 第一种方式

        由于Studnet中没有任何关于地址的属性,但是需求中的查询将包含地址的所有属性;鉴于此,可以新创建一个StudentAddress继承于Student来解决查询 结果的映射。

1)StudentAddress类:

2)接口中方法:

3)在mapper.xml文件中SQL:

4)测试:

2.3.2 第二种方式

        在第一种方式中,不好的是如果以后每次都有这样的关联查询都需要新建一个类,太繁琐。在MyBatis中其实可以在mapper.xml文件使用resultMap来映射这种高级查询。

        在resultMap元素中有association元素可以映射有一个的情形。可以是一对一的关系,也可以是多对一中的多方使用。

        关联元素association处理“有一个”类型的关系。比如,在我们的示例中,一个学生有一个地址。 关联映射就工作于这种结果之上。

1)改造Student类,添加address属性:

2)接口中方法:

3)在mapper.xml文件中SQL:

4)测试:

2.4 一对多查询

        在MyBatis中对于返回结果是一对多的集合列表也有特定的集合元素collection来处理。集合元素的作用几乎和关联是相同的。

【需求】:根据年级ID查询该年级信息包括该年级的所有学生

1)改造年级类Grade,添加学生列表属性students:

2)接口中方法:

3)在mapper.xml文件中SQL:

4)测试:

2.5 多对多查询

        多对多的返回结果中一般也包含列表或者关联,它的处理和上述的处理没有区别。主要不同是在mapper.xml文件中SQL语句的编写需要考虑多对多的表关系。

【需求】:根据学生ID查询学生信息包括学生的地址及其学习的课程

1)改造Student类,添加课程列表属性courses:

2)接口中方法:

3)在mapper.xml文件中SQL:

第一种写法:

或者使用第二种写法,继承已有的resultMap:

4) 测试:

2.6 延迟加载

        在关联元素association查询中可以将关联的对象延迟加载;即如果使用到了关联对象的时候才需要到数据库进行查询,类似hibernate的懒加载。

        延迟加载的意义在于,虽然是关联查询,但不是及时将关联的数据查询出来,而且在需要的时候进行查询。如果在MyBatis中要启用延迟加载需要:

1) 在总配置文件中设置开启延迟加载:

        <!-- 开启延迟加载 -->

        <setting name="lazyLoadingEnabled" value="true"/>

        <setting name="aggressiveLazyLoading" value="false"/>

【说明】

        lazyLoadingEnabled:true使用延迟加载,false禁用延迟加载。默认为true

        aggressiveLazyLoading:true启用时,当延迟加载开启时访问对象中一个懒对象属性时,将完全加载这个对象的所有懒对象属性。false,当延迟加载时,按需加载对象属性(即访问对象中一个懒对象属性,不会加载对象中其他的懒对象属性)。默认为true

  1. 在mybatis-xx.xx.xx目录中找到相关依赖包:asm-x.x.x.jar和cglib-x.x.x.jar将jar包加入到项目中;
  2. 在对应的mapper.xml文件中利用association元素实现。

需求】根据学生ID查询学生信息包括延迟加载学生的地址;即调用学生对象中的获取地址的方法时才去执行查询地址的SQL。

1)改造Student,添加年级属性grade:

2) 接口中方法:

3) 在mapper.xml文件中SQL:

4) 测试:

3、分页插件

        到目前为止;所使用的查询都是查询所有数据,没有进行分页;这样显然是不合理的。如果要在MyBatis里面实现查询的分页如何做?

        解决方式一:可以在每个select语句中添加limit来实现分页,这样做是最简单的,但是这样做需要在太多地方添加比较麻烦。另外;还需要在原有的DAO层修改代码,添加查询记录总数的操作。

        方式一改动量大并需要改动原有代码,不太合适;能否做到在不改变原有业务逻辑的情况下做到分页呢?也即如果可以在MyBatis执行时候拦截即将要执行的语句,然后加入分页逻辑的话,原有的所有代码都不需要改变。这也就是解决方式二,使用MyBatis的插件(拦截器)。

        MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

  1. Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  2. ParameterHandler (getParameterObject, setParameters)
  3. ResultSetHandler (handleResultSets, handleOutputParameters)
  4. StatementHandler (prepare, parameterize, batch, update, query)

        通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定了想要拦截的方法签名即可。

        方式二的解决方案正是使用了插件;这里引用一个开源的MyBatis分页插件PageHelper。PageHelper实现了通用的分页查询,其支持的数据有,mysql、Oracle、DB2、PostgreSQL等主流的数据库。

该插件托管于github: GitHub - pagehelper/Mybatis-PageHelper: Mybatis通用分页插件

详见《Mybatis分页插件-PageHelper》

在MyBatis配置文件中配置分页插件,然后在代码中添加分页参数进行分页是非常简单的。

1) 添加PageHelper的相关jar包;

2) 配置:

3) 运用:

  • 46
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

棉花糖老丫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值