MyBatis学习总结

MyBatis分页如何实现

分页分为
逻辑分页:查询出所有的数据缓存到内存里面,在从内存中筛选出需要的数据进行分页
物理分页:直接用数据库语法进行分页limit
mybatis提供四种方法分页:

  1. 直接在sql语句中分页,传递分页参数
    select _column,_column from _table [where Clause] [limit N][offset M]
    select * : 返回所有记录
    limit N : 返回 N 条记录
    offset M : 跳过 M 条记录, 默认 M=0, 单独使用似乎不起作用
    limit N,M = limit M offset N , 从第 N+1 条记录开始, 返回 M 条记录
  2. MyBatis提供了RowBounds对象实现逻辑分页
 @Testpublic void getUserByRowBounds(){SqlSession sqlSession = MybatisUtil.getSqlSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);//RowBounds实现RowBounds rowBounds = new RowBounds(1,2);//通过java代码层面实现分页List<Map> userList = sqlSession.selectList("com.jin.mapper.UserMapper.getUserByRowBounds", null, rowBounds);for (Map map1 : userList) {System.out.println(map1);}sqlSession.close();}

但是:RowBounds是将所有符合条件的数据全都查询到内存中,然后在内存中对数据进行分页,数据量非常大时,造成内存OOM。
3.MyBatis拦截器interceptor实现分页,截获所执行方法的sql语句与参数,动态拼接sql分页语句

利用拦截器实现Mybatis分页的一个思路就是拦截StatementHandler接口的prepare方法,然后在拦截器方法中把Sql语句改成对应的分页查询Sql语句,之后再调用StatementHandler对象的prepare方法,即调用invocation.proceed()

4.分页插件
例如pagehelper,物理分页,实际原理就是修改最后的执行sql,增加相应的分页内容,是基于拦截器实现的。
在这里插入图片描述

MyBatis二级缓存

  1. 功能 - 提高查询效率
  2. 工作流程-一级缓存-缺点-二级缓存
  3. 实现原理
    MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率。默认定义了两级缓存,分别是一级缓存和二级缓存。
    默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。二级缓存需要手动开启和配置,他是基于namespace级别的缓存。为了提高扩展性,MyBatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存。
    一级缓存(本地缓存)
    sqlSession级别的缓存,一级缓存一直是开启的,它实质上就是sqlSession级别的一个Map。
    一级缓存失效:
    sqlSession不同。
    sqlSession相同,查询条件不同(当前一级缓存中还没有这个数据)。
    sqlSession相同,两次查询之间执行了增删改操作(这次增删改可能对当前数据有影响),实际上,这个是因为每个增删改查都有标签flushCache,增删改默认为flushCache=“true”,即执行完后就清除一级缓存和二级缓存。
    sqlSession相同,手动清除了一级缓存(缓存清空,session.clearCache(),注意,该方法只清除当前session的一级缓存)。
    二级缓存(全局缓存)
    namespace级别的缓存,一个namespace对应一个二级缓存。
    工作机制
    一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中。
    如果会话关闭或提交,一级缓存中的数据会被保存到二级缓存中,新的会话查询信息,就可以参照二级缓存中的内容。
    注意:不同的namespace查出的数据会放在自己对应的缓存(map)中。
    效果:数据会从二级缓存中取出。查出的数据都会被默认先放在一级缓存中,只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中。

先查询二级缓存,再查询一级缓存,最后查询数据库。
在这里插入图片描述
原理:sqlSession的executor持有一个Local cache对象,当用户发起查询,会根据执行语句到缓存查找,如果命中,直接返回,否则查询数据库再写入缓存。二级缓存则是executor的基础上做了一个装饰CachingExecutor装饰器,查询时先通过CachingExecutor查询二级缓存。

{}和\${}的区别

mybatis会对这两个符号解析,实现动态sql。

#{}匹配的是一个占位符,相当于JDBC中的一个?,会对一些敏感的字符进行过滤,编译过后会对传递的值加上双引号,因此可以防止SQL注入问题。

\${}匹配的是真实传递的值,传递过后,会与sql语句进行字符串拼接。${}会与其他sql进行字符串拼接,不能预防sql注入问题。

#{}的应用场景是为给SQL语句的where字句传递条件值,${}的应用场景是为了传递一些需要参与SQL语句语法生成的值。

mybatis代理模式

在这里插入图片描述
mapper接口和mapper配置文件的目录要对应。

//mybatis代理开发
public class MyBatisDemo2 {public static void main(String[] args) throws IOException {//1. 加载mybatis的核心配置文件,获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);//2.获取SqlSession对象,用来执行sqlSqlSession sqlSession = sqlSessionFactory.openSession();//3.执行sql namespace+id//List<Student> students = sqlSession.selectList("test.findAll");//3.1 获取StudentMapper接口的代理对象StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);studentMapper.findAll();//System.out.println(students);//mybatis提供了mapper接口代理的开发方式,不需要再编写dao类,只需要编写一个mapper接口,一个mapper的接口和一个mapper.xml相对应,// 只需要调用SqlSession对象上的getMapper(),传入mapper接口的class信息,即可获得一个mapper代理对象,// 直接调用mapper接口中的方法,即相当于调用mapper.xml中的各个SQL标签,此时就不需要指定SQL标签的id字符串了,// mapper接口中的一个方法,就对应了mapper.xml中的一个SQL标签//4.释放资源sqlSession.close();}

mybatis动态数据源配置

Spring内置了一个AbstractRoutingDataSource,它可以把多个数据源配置成一个Map,然后,根据不同的key返回不同的数据源。因AbstractRoutingDataSource也是一个DataSource接口。应用程序可以先设置好key, 访问数据库的代码就可以从AbstractRoutingDataSource拿到对应的一个真实的数据源,从而访问指定的数据库。
源码中有一个核心的方法 setTargetDataSources(Map<Object, Object> targetDataSources) ,它需要一个Map,在方法注释中我们可以得知,这个Map存储的就是我们配置的多个数据源的键值对。我们整理一下这个类切换数据源的运作方式,这个类在连接数据库之前会执行determineCurrentLookupKey()方法,这个方法返回的数据将作为key去targetDataSources中查找相应的值,如果查找到相对应的DataSource,那么就使用此DataSource获取数据库连接它是一个abstract类,所以我们使用的话,推荐的方式是创建一个类来继承它并且实现它的determineCurrentLookupKey() 方法,这个方法介绍上面也进行了说明,就是通过这个方法进行数据源的切换。

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {@Nullableprivate Map<Object, Object> targetDataSources;@Nullableprivate Object defaultTargetDataSource;private boolean lenientFallback = true;private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();// 存放的数据对象的Map集合类@Nullableprivate Map<Object, DataSource> resolvedDataSources;@Nullableprivate DataSource resolvedDefaultDataSource;public AbstractRoutingDataSource() {}// 初始化设置数据源public void setTargetDataSources(Map<Object, Object> targetDataSources) {this.targetDataSources = targetDataSources;}// ...protected DataSource determineTargetDataSource() {Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");// 决策当前选择的数据源的KeyObject lookupKey = this.determineCurrentLookupKey();// 当前选择的数据源DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey);if (dataSource == null && (this.lenientFallback || lookupKey == null)) {dataSource = this.resolvedDefaultDataSource;}if (dataSource == null) {throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");} else {return dataSource;}}// 数据源Key的实现方法,由子类去实现@Nullableprotected abstract Object determineCurrentLookupKey();
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/692994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网贷大数据查询多了对征信有影响吗?

网贷大数据在日常的金融借贷中起到很重要的风控作用&#xff0c;不少银行已经将大数据检测作为重要的风控环节。很多人在申贷之前都会提前了解自己的大数据信用情况&#xff0c;那网贷大数据查询多了对征信有影响吗?本文带你一起去看看。 首先要说结论&#xff1a;那就是查询网…

[极客大挑战2019]upload

该题考点&#xff1a;后缀黑名单文件内容过滤php木马的几种书写方法 phtml可以解析php代码&#xff1b;<script language"php">eval($_POST[cmd]);</script> 犯蠢的点儿&#xff1a;利用html、php空格和php.不解析<script language"php"&…

寄存器 Flip-Flop

组合逻辑是电平输入和电平输出。&#xff08;组合逻辑虽然符合人的思维习惯&#xff0c;并且元器件结构简单&#xff0c;但问题是如果输入含有毛刺&#xff0c;输出就有毛刺。eg. 如果输入信号突然从0变成1后又在短时间内恢复0&#xff0c;可以视为毛刺&#xff0c;输出信号受到…

说说 Dubbo 工作原理?Dubbo 容错策略?Zookeeper 和 Dubbo 的关系?Dubbo 动态代理策略有哪些?Dubbo 负载均衡策略?

说说 Dubbo 工作原理? 工作原理分 10 层&#xff1a; 第一层&#xff1a; service 层&#xff0c;接口层&#xff0c;给服务提供者和消费者来实现的&#xff08;留给开发人员来实现&#xff09;&#xff1b; 第二层&#xff1a; config 层&#xff0c;配置层&#xff0c…

Oracle的TimesStamp和Date的区别

在Oracle数据库中&#xff0c;DATE和TIMESTAMP数据类型都是用于存储日期和时间信息&#xff0c;但它们之间有几个重要的区别&#xff1a; 精度不同&#xff1a; DATE数据类型能存储日期和时间到秒的精度&#xff0c;格式通常是YYYY-MM-DD HH24:MI:SS&#xff0c;并且它总是包含…

软件测试工程师经典面试题

软件测试工程师&#xff0c;和开发工程师相比起来&#xff0c;虽然前期可能不会太深&#xff0c;但是涉及的面还是比较广的。前期面试实习生或者一年左右的岗位&#xff0c;问的也主要是一些基础性的问题比较多。涉及的知识主要有MySQL数据库的使用、Linux操作系统的使用、软件…

缓存驱动联邦学习架构赋能个性化边缘智能 | TMC 2024

缓存驱动联邦学习架构赋能个性化边缘智能 | TMC 2024 伴随着移动设备的普及与终端数据的爆炸式增长&#xff0c;边缘智能&#xff08;Edge Intelligence, EI&#xff09;逐渐成为研究领域的前沿。在这一浪潮中&#xff0c;联邦学习&#xff08;Federated Learning, FL&#xf…

golang 如何防止内存逃逸

在Go语言中&#xff0c;内存逃逸是指在函数中分配的变量在函数结束后仍然被引用&#xff0c;从而导致变量的生命周期延长&#xff0c;被分配在堆上而不是栈上。防止内存逃逸有助于提高程序的性能&#xff0c;因为栈上分配的内存可以更快地被回收。 以下是一些防止内存逃逸的方…

leetcode hot100零钱兑换Ⅱ

本题可以看出也是背包问题&#xff0c;但区别于之前的01背包问题&#xff0c;这个是完全背包问题的变形形式。 下面介绍01背包和完全背包的区别与联系&#xff1a; 01背包是背包中的物品只能用一次&#xff0c;不可以重复使用&#xff0c;而完全背包则是可以重复使用。01/完全…

为BUG编程:char的默认类型导致的BUG

char的默认类型大部分是signed&#xff0c;教科书上也这么讲&#xff0c;所以一般遇不到什么问题&#xff0c;但是在arm上出问题了&#xff0c;默认char是unsigned&#xff0c;导致c<0永远失败。 代码是这样的&#xff1a; //计算输出长度size_t outputlen(string const &am…

一个基于C#开发的、开源的特殊字符输入法

emoji表情在社交网络非常流行&#xff0c;我们在手机也非常方便输入&#xff0c;但是在PC电脑我们一般需要到归集好的网页拷贝&#xff0c;所以今天推荐一个Windows小工具&#xff0c;让你方便输入特殊字符和emoji表情。 01 项目简介 这是一个基于C#开发的开源项目&#xff0…

JCL中的位置参数

JCL中DD语句的位置参数 ​ DD语句的格式&#xff1a; ​ //DD名 DD 位置参数 ​ DD名&#xff0c;是DD语句定义的名字&#xff0c;由1-8个字符组成&#xff0c;一个STEP里面可以有多个DD语句&#xff0c;每个DD语句指向一个系统中的数据资源&#xff0c;这就是为了操纵数据文…

ansible及其模块

一、ansible是什么&#xff1f; Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部…

手动实现new操作符

<script>//前置知识// 每一个函数在创建之初就会有一个prototype属性&#xff0c;这个属性指向函数的原型对象// function abc(){// }// abc.prototype--> {constructor: f}// 在JS中任意的对象都有内置的属性叫做[[prototype]]这是一个私有属性&#xff0c;这个私有属…

如何用GPT进行论文写作?

一&#xff1a;AI领域最新技术 1.OpenAI新模型-GPT-5 2.谷歌新模型-Gemini Ultra 3.Meta新模型-LLama3 4.科大讯飞-星火认知 5.百度-文心一言 6.MoonshotAI-Kimi 7.智谱AI-GLM-4 二&#xff1a;GPT最新技术 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析&#x…

安宝特AR汽车行业解决方案系列1-远程培训

在汽车行业中&#xff0c;AR技术的应用正悄然改变着整个产业链的运作方式&#xff0c;应用涵盖培训、汽修、汽车售后、PDI交付、质检以及汽车装配等&#xff0c;AR技术为多个环节都带来了前所未有的便利与效率提升。 安宝特AR将以系列推文的形式为读者逐一介绍在汽车行业中安宝…

Navicat 连接MySQL 8.0.11 出现2059错误 解决

原因 mysql8 之前的版本中加密规则是mysql_native_password,而在mysql8之后,加密规则是caching_sha2_password 解决 mysql -uroot -ppassword #登录use mysql; #选择数据库# 远程连接请将localhost换成% ALTER USER rootlocalhost IDENTIFIED BY password PASSWORD EXPIRE N…

使用 npm/yarn 等命令的时候会,为什么会发生 Error: certificate has expired

缘起 昨天&#xff0c;我写了一篇文章&#xff0c;介绍如何使用项目模板&#xff0c;构建一个 Electron 项目的脚手架&#xff0c;我发现我自己在本地无法运行成功&#xff0c;出现了错误。 ✖ Failed to install modules: ["electron-forge/plugin-vite^7.2.0",&qu…

多维时序 | Matlab实现BiLSTM-MATT双向长短期记忆神经网络融合多头注意力多变量时间序列预测模型

多维时序 | Matlab实现BiLSTM-MATT双向长短期记忆神经网络融合多头注意力多变量时间序列预测模型 目录 多维时序 | Matlab实现BiLSTM-MATT双向长短期记忆神经网络融合多头注意力多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.多维时序 | Matlab…

第六十四天 服务攻防-框架安全CVE复现Apache shiroApache Solr

第六十四天 服务攻防-框架安全&CVE复现Apache shiro&Apache Solr 知识点: 中间件及框架列表: IIS,Apache,Nginx,Tomcat,Docker,K8s,Weblogic.JBoos,WebSphere, Jenkins,GlassFish,Jetty,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Spring, Flask,jQuery等 1、开发框…