前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Web缓存

Web缓存

作者头像
zy010101
发布于 2022-11-07 06:46:11
发布于 2022-11-07 06:46:11
81600
代码可运行
举报
文章被收录于专栏:程序员程序员
运行总次数:0
代码可运行

Web缓存

Web 缓存是可以自动保存常见文档副本的 HTTP 设备。当 Web 请求抵达缓存时,如果本地有“已缓存的”副本,就可以从本地存储设备而不是原始服务器中提取这个文档。使用缓存有下列优点。

  • 缓存减少了冗余的数据传输,节省了你的网络费用。
  • 缓存缓解了网络瓶颈的问题。不需要更多的带宽就能够更快地加载页面。
  • 缓存降低了对原始服务器的要求。服务器可以更快地响应,避免过载的出现。
  • 缓存降低了距离时延,因为从较远的地方加载页面会更慢一些。

缓存命中和未命中

缓存确实能够解决上面的网络问题,但缓存无法保存世界上每份文档的副本。可以用已有的副本为某些到达缓存的请求提供服务。这被称为缓存命中(cache hit),其他一些到达缓存的请求可能会由于没有副本可用,而被转发给原始服务器。这被称为缓存未命中(cache miss)。

原始服务器的内容可能会发生变化,缓存要不时对其进行检测,看看它们保存的副本是否仍是服务器上最新的副本。这被称为 HTTP 再验证(revalidation)。为了有效地进行再验证,HTTP 定义了一些特殊的请求,不用从服务器上获取整个对象,就可以快速检测出内容是否是最新的。

Web缓存对它自身缓存的副本进行再验证时,会向原始服务器发送一个小的再验证请求。如果内容没有变化,服务器会以一个小的 304 Not Modified 进行响应。只要缓存知道副本仍然有效,就会再次将副本标识为暂时新鲜的,并将副本提供给客户端这被称作再验证命中(revalidate hit)或缓慢命中(slow hit)。这种方式确实要与原始服务器进行核对,所以会比单纯的缓存命中要慢,但它没有从服务器中获取对象数据,所以要比缓存未命中快一些。

HTTP 为我们提供了几个用来对已缓存对象进行再验证的工具,但最常用的是If-Modified-Since 首部。将这个首部添加到 GET 请求中去,就可以告诉服务器,只有在缓存了对象的副本之后,又对其进行了修改的情况下,才发送此对象。

这里列出了在 3 种情况下(服务器内容未被修改,服务器内容已被修改,或者服务器上的对象被删除了)服务器收到 GET If-Modified-Since 请求时会发生的情况:

  • 再验证命中 如果服务器对象未被修改,服务器会向客户端发送一个小的 HTTP 304 Not Modified 响应。
  • 再验证未命中 如果服务器对象与已缓存副本不同,服务器向客户端发送一条普通的、带有完整内容的 HTTP 200 OK 响应。
  • 对象被删除 如果服务器对象已经被删除了,服务器就回送一个 404 Not Found 响应,缓存也会将其副本删除。

缓存命中率

由缓存提供服务的请求所占的比例被称为缓存命中率(cache hit rate,或称为缓存命中比例),有时也被称为文档命中率(document hit rate)。命中率在 0 到 1 之间,但通常是用百分数来描述的,0% 表示每次请求都未命中(要通过网络来获取文档),100% 表示每次请求都命中了(在缓存中有一份副本)。

由于文档并不全是同一尺寸的,所以文档命中率并不能说明一切。有些大型对象被访问的次数可能较少,但由于尺寸的原因,对整个数据流量的贡献却更大。因此,有些人更愿意使用字节命中率(byte hit rate)作为度量值(尤其那些按流量字节付费的人!)。

文档命中率和字节命中率对缓存性能的评估都是很有用的。文档命中率说明阻止了多少通往外部网络的 Web 事务。事务有一个通常都很大的固定时间成分(比如,建立一条到服务器的 TCP 连接),提高文档命中率对降低整体延迟(时延)很有好处。字节命中率说明阻止了多少字节传向因特网。提高字节命中率对节省带宽很有利。

HTTP 没有为用户提供一种手段来区分响应是缓存命中的,还是访问原始服务器得到的。在这两种情况下,响应码都是 200 OK,说明响应有主体部分。有些商业代理缓存会在 Via 首部附加一些额外信息,以描述缓存中发生的情况。

客户端有一种方法可以判断响应是否来自缓存,就是使用 Date 首部。将响应中Date 首部的值与当前时间进行比较,如果响应中的日期值比较早,客户端通常就可以认为这是一条缓存的响应。客户端也可以通过 Age 首部来检测缓存的响应,通过这个首部可以分辨出这条响应的使用期。

私有缓冲和公有缓存

缓存可以是单个用户专用的,也可以是数千名用户共享的。专用缓存被称为私有缓存(private cache)。私有缓存是个人的缓存,包含了单个用户最常用的页面。共享的缓存被称为公有缓存(public cache)。公有缓存中包含了某个用户团体的常用页面。

私有缓存

私有缓存不需要很大的动力或存储空间,这样就可以将其做得很小,很便宜。Web 浏览器中有内建的私有缓存——大多数浏览器都会将常用文档缓存在你个人电脑的磁盘和内存中,并且允许用户去配置缓存的大小和各种设置。还可以去看看浏览器的缓存中有些什么内容。

公有缓存

公有缓存是特殊的共享代理服务器,被称为缓存代理服务器(caching proxy server),或者更常见地被称为代理缓存(proxy cache)。代理缓存会从本地缓存中提供文档,或者代表用户与服务器进行联系。公有缓存会接受来自多个用户的访问,所以通过它可以更好地减少冗余流量。每个客户端都会重复地访问一个(不在私有缓存中的)新的“热门”文档。每个私有缓存都要获取同一份文档,这样它就会多次穿过网络。而使用共享的公有缓存时,对于这个流行的对象,缓存只要取一次就行了,它会用共享的副本为所有的请求服务,以降低网络流量。

缓存的层次化结构

在实际中,实现层次化(hierarchy)的缓存是很有意义的,在这种结构中,在较小缓存中未命中的请求会被导向较大的父缓存(parent cache),由它来为剩下的那些“提炼过的”流量提供服务。其基本思想是在靠近客户端的地方使用小型廉价缓存,而更高层次中,则逐步采用更大、功能更强的缓存来装载多用户共享的文档。在缓存层次结构很深的情况下,请求可能要穿过很长一溜缓存,但每个拦截代理都会添加一些性能损耗,当代理链路变得很长的时候,这种性能损耗会变得非常明显。

网状缓存、内容路由以及对等缓存

有些网络结构会构建复杂的网状缓存(cache mesh),而不是简单的缓存层次结构。网状缓存中的代理缓存之间会以更加复杂的方式进行对话,做出动态的缓存通信决策,决定与哪个父缓存进行对话,或者决定彻底绕开缓存,直接连接原始服务器。这种代理缓存会决定选择何种路由对内容进行访问、管理和传送,因此可将其称为内容路由器(content router)。 网状缓存中为内容路由设计的缓存(除了其他任务之外)要完成下列所有功能。

  • 根据 URL 在父缓存或原始服务器之间进行动态选择。
  • 根据 URL 动态地选择一个特定的父缓存。
  • 前往父缓存之前,在本地缓存中搜索已缓存的副本。
  • 允许其他缓存对其缓存的部分内容进行访问,但不允许因特网流量通过它们的缓存。

缓存之间这些更为复杂的关系允许不同的组织互为对等(peer)实体,将它们的缓存连接起来以实现共赢。提供可选的对等支持的缓存被称为兄弟缓存(sibling cache)HTTP 并不支持兄弟缓存,所以人们通过一些协议对 HTTP 进行了扩展,比如因特网缓存协议(Internet Cache Protocol,ICP)和超文本缓存协议(HyperText Caching Protocol,HTCP)。

缓存的处理步骤

  1. 接收 在第一步中,缓存检测到一条网络连接上的活动,读取输入数据。高性能的缓存会同时从多条输入连接上读取数据,在整条报文抵达之前开始对事务进行处理。
  2. 解析 缓存将请求报文解析为片断,将首部的各个部分放入易于操作的数据结构中。这样,缓存软件就更容易处理首部字段并修改它们了。
  3. 查找 缓存获取了 URL,查找本地副本。本地副本可能存储在内存、本地磁盘,甚至附近的另一台计算机中。专业级的缓存会使用快速算法来确定本地缓存中是否有某个对象。如果本地没有这个文档,它可以根据情形和配置,到原始服务器或父代理中去取,或者返回一条错误信息。 已缓存对象中包含了服务器响应主体和原始服务器响应首部,这样就会在缓存命中时返回正确的服务器首部。已缓存对象中还包含了一些元数据(metadata),用来记录对象在缓存中停留了多长时间,以及它被用过多少次等
  4. 新鲜度检测 HTTP 通过缓存将服务器文档的副本保留一段时间。在这段时间里,都认为文档是“新鲜的”,缓存可以在不联系服务器的情况下,直接提供该文档。但一旦已缓存副本停留的时间太长,超过了文档的新鲜度限值(freshness limit),就认为对象“过时”了,在提供该文档之前,缓存要再次与服务器进行确认,以查看文档是否发生了变化。客户端发送给缓存的所有请求首部自身都可以强制缓存进行再验证,或者完全避免验证。 HTTP 有一组非常复杂的新鲜度检测规则,缓存产品支持的大量配置选项,以及与非 HTTP 新鲜度标准进行互通的需要则使问题变得更加严重了。
  5. 创建响应 我们希望缓存的响应看起来就像来自原始服务器的一样,缓存将已缓存的服务器响应首部作为响应首部的起点。然后缓存对这些基础首部进行了修改和扩充。缓存负责对这些首部进行改造,以便与客户端的要求相匹配。比如,服务器返回的可能是一条 HTTP/1.0 响应(甚至是 HTTP/0.9 响应),而客户端期待的是一条HTTP/1.1 响应,在这种情况下,缓存必须对首部进行相应的转换。缓存还会向其中插入新鲜度信息(Cache-Control、Age 以及 Expires 首部),而且通常会包含一个 Via 首部来说明请求是由一个代理缓存提供的。注意,缓存不应该调整 Date 首部。Date首部表示的是原始服务器最初产生这个对象的日期。
  6. 发送 一旦响应首部准备好了,缓存就将响应回送给客户端。和所有代理服务器一样,代理缓存要管理与客户端之间的连接。高性能的缓存会尽力高效地发送数据,通常可以避免在本地缓存和网络 I/O 缓冲区之间进行文档内容的复制。
  7. 日志 大多数缓存都会保存日志文件以及与缓存的使用有关的一些统计数据。每个缓存事务结束之后,缓存都会更新缓存命中和未命中数目的统计数据。

保持缓存的新鲜度

可能不是所有的已缓存副本都与服务器上的文档一致。毕竟,这些文档会随着时间发生变化。报告可能每个月都会变化。在线报纸每天都会发生变化。财经数据可能每过几秒钟就会发生变化。如果缓存提供的总是老的数据,就会变得毫无用处。已缓存数据要与服务器数据保持一致。

通过特殊的 HTTP Cache-Control 首部和 Expires 首部,HTTP 让原始服务器向每个文档附加了一个“过期日期”。就像一夸脱牛奶上的过期日期一样,这些首部说明了在多长时间内可以将这些内容视为新鲜的。服务器用 HTTP/1.0+ 的 Expires 首部或 HTTP/1.1 的 Cache-Control: max-age 响应首部来指定过期日期,同时还会带有响应主体。Expires 首部和Cache-Control:max-age 首部所做的事情本质上是一样的,但由于 Cache-Control 首部使用的是相对时间而不是绝对日期,所以我们更倾向于使用比较新的 Cache-Control 首部。绝对日期依赖于计算机时钟的正确设置。

在缓存文档过期之前,缓存可以以任意频率使用这些副本,而无需与服务器联系——当然,除非客户端请求中包含有阻止提供已缓存或未验证资源的首部。但一旦已缓存文档过期,缓存就必须与服务器进行核对,询问文档是否被修改过,如果被修改过,就要获取一份新鲜(带有新的过期日期)的副本。

仅仅是已缓存文档过期了并不意味着它和原始服务器上目前处于活跃状态的文档有实际的区别;这只是意味着到了要进行核对的时间了。这种情况被称为“服务器再验证”,说明缓存需要询问原始服务器文档是否发生了变化。

  • 如果再验证显示内容发生了变化,缓存会获取一份新的文档副本,并将其存储在旧文档的位置上,然后将文档发送给客户端。
  • 如果再验证显示内容没有发生变化,缓存只需要获取新的首部,包括一个新的过期日期,并对缓存中的首部进行更新就行了。

条件GET

HTTP 的条件方法可以高效地实现再验证。HTTP 允许缓存向原始服务器发送一个“条件 GET”,请求服务器只有在文档与缓存中现有的副本不同时,才回送对象主体。通过这种方式,将新鲜度检测和对象获取结合成了单个条件 GET。向 GET 请求报文中添加一些特殊的条件首部,就可以发起条件 GET。只有条件为真时,Web服务器才会返回对象。

If-Modified-Since

最常见的缓存再验证首部是 If-Modified-Since。If-Modified-Since 再验证请求通常被称为 IMS 请求。只有自某个日期之后资源发生了变化的时候,IMS 请求才会指示服务器执行请求:

  • 如果自指定日期后,文档被修改了,If-Modified-Since 条件就为真,通常GET 就会成功执行。携带新首部的新文档会被返回给缓存,新首部除了其他信息之外,还包含了一个新的过期日期。
  • 如果自指定日期后,文档没被修改过,条件就为假,会向客户端返回一个小的 304 Not Modified 响应报文,为了提高有效性,不会返回文档的主体。这些首部是放在响应中返回的,但只会返回那些需要在源端更新的首部。比如,Content-Type 首部通常不会被修改,所以通常不需要发送。一般会发送一个新的过期日期。

If-Modified-Since 首部可以与 Last-Modified 服务器响应首部配合工作。原始服务器会将最后的修改日期附加到所提供的文档上去。当缓存要对已缓存文档进行再验证时,就会包含一个 If-Modified-Since 首部,其中携带有最后修改已缓存副本的日期:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
If-Modified-Since: <cached last-modified date>

如果在此期间内容被修改了,最后的修改日期就会有所不同,原始服务器就会回送新的文档。否则,服务器会注意到缓存的最后修改日期与服务器文档当前的最后修改日期相符,会返回一个 304 Not Modified 响应。

有些 Web 服务器并没有将 If-Modified-Since 作为真正的日期来进行比对。相反,它们在 IMS 日期和最后修改日期之间进行了字符串匹配。这样得到的语义就是“如果最后的修改不是在这个确定的日期进行的”,而不是“如果在这个日期之后没有被修改过”。将最后修改日期作为某种序列号使用时,这种替代语义能够很好地识别出缓存是否过期,但这会妨碍客户端将If-Modified-Since 首部用于真正基于时间的一些目的。

If-None-Match

有些情况下仅使用最后修改日期进行再验证是不够的。

  • 有些文档可能会被周期性地重写(比如,从一个后台进程中写入),但实际包含的数据常常是一样的。尽管内容没有变化,但修改日期会发生变化。
  • 有些文档可能被修改了,但所做修改并不重要,不需要让世界范围内的缓存都重装数据(比如对拼写或注释的修改)。
  • 有些服务器无法准确地判定其页面的最后修改日期。
  • 有些服务器提供的文档会在亚秒间隙发生变化(比如,实时监视器),对这些服务器来说,以一秒为粒度的修改日期可能就不够用了。

为了解决这些问题,HTTP 允许用户对被称为实体标签(ETag)的“版本标识符”进行比较。实体标签是附加到文档上的任意标签(引用字符串)。它们可能包含了文档的序列号或版本名,或者是文档内容的校验和及其他指纹信息。当发布者对文档进行修改时,可以修改文档的实体标签来说明这个新的版本。这样,如果实体标签被修改了,缓存就可以用 If-None-Match 条件首部来 GET 文档的新副本了。

强弱验证器

有时,服务器希望在对文档进行一些非实质性或不重要的修改时,不要使所有的已缓存副本都失效。HTTP/1.1 支持“弱验证器”,如果只对内容进行了少量修改,就允许服务器声明那是“足够好”的等价体。只要内容发生了变化,强验证器就会变化。弱验证器允许对一些内容进行修改,但内容的主要含义发生变化时,通常它还是会变化的。有些操作不能用弱验证器来实现(比如有条件地获取部分内容),所以,服务器会用前缀“W/”来标识弱验证器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ETag: W/"v2.6"
If-None-Match: W/"v2.6"

不管相关的实体值以何种方式发生了变化,强实体标签都要发生变化。而相关实体在语义上发生了比较重要的变化时,弱实体标签也应该发生变化。

如果服务器回送了一个实体标签,HTTP/1.1 客户端就必须使用实体标签验证器。如果服务器只回送了一个 Last-Modified 值,客户端就可以使用 If-ModifiedSince 验证。如果实体标签和最后修改日期都提供了,客户端就应该使用这两种再验证方案,这样 HTTP/1.0 和 HTTP/1.1 缓存就都可以正确响应了。

控制缓存

服务器可以通过 HTTP 定义的几种方式来指定在文档过期之前可以将其缓存多长时间。按照优先级递减的顺序,服务器可以:

  • 附加一个 Cache-Control: no-store 首部到响应中去;
  • 附加一个 Cache-Control: no-cache 首部到响应中去;
  • 附加一个 Cache-Control: must-revalidate 首部到响应中去;
  • 附加一个 Cache-Control: max-age 首部到响应中去;
  • 附加一个 Expires 日期首部到响应中去;
  • 不附加过期信息,让缓存确定自己的过期日期。

HTTP/1.1 提供了几种限制对象缓存,或限制提供已缓存对象的方式,以维持对象的新鲜度。no-store 首部和 no-cache 首部可以防止缓存提供未经证实的已缓存对象。

标识为 no-store 的响应会禁止缓存对响应进行复制。缓存通常会像非缓存代理服务器一样,向客户端转发一条 no-store 响应,然后删除对象。

标识为 no-cache 的响应实际上是可以存储在本地缓存区中的。只是在与原始服务器进行新鲜度再验证之前,缓存不能将其提供给客户端使用。

HTTP/1.1 中提供 Pragma: no-cache 首部是为了兼容于 HTTP/1.0+。除了与只理解 Pragma: no-cache 的 HTTP/1.0 应用程序进行交互时,HTTP 1.1 应用程序都

应该使用 Cache-Control: no-cache。

Cache-Control: max-age 首部表示的是从服务器将文档传来之时起,可以认为此文档处于新鲜状态的秒数。还有一个 s-maxage 首部(注意 maxage 的中间没有连字符),其行为与 max-age 类似,但仅适用于共享(公有)缓存。服务器可以要求缓存服务器不要进行缓存,或者将最大使用期设置为零,从而在每次访问的时候都进行刷新。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Cache-Control: max-age=0
Cache-Control: s-maxage=0

Expires 响应首部

不推荐使用 Expires 首部,它指定的是实际的过期日期而不是秒数。HTTP 设计者后来认为,由于很多服务器的时钟都不同步,或者不正确,所以最好还是用剩余秒数,而不是绝对时间来表示过期时间。可以通过计算过期值和日期值之间的秒数差来计算类似的新鲜生存期:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Expires: Fri, 05 Jul 2002, 05:00:00 GMT

有些服务器还会回送一个 Expires:0 响应首部,试图将文档置于永远过期的状态,但这种语法是非法的,可能给某些软件带来问题。应该试着支持这种结构的输入,但不应该产生这种结构的输出。

must-revalidate响应首部

Cache-Control: must-revalidate 响应首部告诉缓存,在事先没有跟原始服务器进行再验证的情况下,不能提供这个对象的陈旧副本。缓存仍然可以随意提供新鲜的副本。如果在缓存进行 must-revalidate 新鲜度检查时,原始服务器不可183 用,缓存就必须返回一条 504 Gateway Timeout 错误。

客户端的新鲜度限制

Web 浏览器都有 Refresh(刷新)或 Reload(重载)按钮,可以强制对浏览器或代理缓存中可能过期的内容进行刷新。Refresh 按钮会发布一个附加了 CacheControl 请求首部的 GET 请求,这个请求会强制进行再验证,或者无条件地从服务器获取文档。Refresh 的确切行为取决于特定的浏览器、文档以及拦截缓存的配置。客户端可以用 Cache-Control 请求首部来强化或放松对过期时间的限制。有些应用程序对文档的新鲜度要求很高(比如人工刷新按钮),对这些应用程序来说,客户端可以用 Cache-Control 首部使过期时间更严格。另一方面,作为提高性能、可靠性或开支的一种折衷方式,客户端可能会放松新鲜度要求。下表展示了Cache-Control请求指令。

缓存和广告

缓存可以提高性能并减少流量。知道缓存可以帮助用户,并为用户提供更好的使用体验,而且缓存也可以帮助网络运营商减少流量。

发布广告者的两难处境

你可能认为内容提供商会喜欢缓存。毕竟,如果到处都是缓存的话,内容提供商就不需要购买大型的多处理器 Web 服务器来满足用户需求了——他们不需要付过高的网络服务费,一遍一遍地向用户发送同样的数据。更好的一点是,缓存可以将那些漂亮的文章和广告以更快,甚至更好看的方式显示在用户的显示器上,鼓励他们去浏览更多的内容,看更多的广告。这就是内容提供商所希望的!吸引更多的眼球和更多的广告!

但这就是困难所在。很多内容提供商的收益都是通过广告实现的——具体来说,每向用户显示一次广告内容,内容提供商就会得到相应的收益。(可能还不到一两便士,但如果一天显示数百万条广告的话,这些钱就会叠加起来!)这就是缓存的问题——它们会向原始服务器隐藏实际的访问次数。如果缓存工作得很好,原始服务器可能根本收不到任何 HTTP 访问,因为这些访问都被因特网缓存吸收了。但如果你的收益是基于访问次数的话,你就高兴不起来了。

解决方法

一种解决方案就是配置缓存,每次访问时都与原始服务器进行再验证。这样,每次访问时都会将命中推向原始服务器,但通常不会传送任何主体数据。当然,这样会降低事务处理的速度。

理想的解决方案是不需要将命中传递给服务器的。毕竟,缓存就可以记录下所有的命中。缓存只要将命中日志发送给服务器就行了。实际上,为了保持内容提供商们的满意度,有些大型缓存的提供商已经在对缓存日志进行人工处理,并将其传送给受影响的内容提供商了。但是,命中日志很大,很难移动。而缓存日志并没有被标准化或被组织成独立的日志,以传送给单独的内容提供商。而且,这里面还存在着认证和隐私问题。

RFC 2227,“HTTP 的简单命中计数和使用限制”中定义了一种简单得多的方案。这个协议向 HTTP 中添加了一个称为 Meter 的首部,这个首部会周期性地将对特定URL 的命中次数回送给服务器。通过这种方式,服务器可以从缓存周期性地获取对已缓存文档命中次数的更新。而且,服务器还能控制在缓存必须向服务器汇报之前,其中的文档还可以使用多少次,或者为缓存文档设置一个时钟超时值。这种控制方式被称为使用限制;通过这种方式,服务器可以对缓存向原始服务器汇报之前,已缓存资源的使用次数进行控制。

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Mybatis传多个参数(三种解决方案)
其中,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
似水的流年
2018/01/14
7170
SpringBoot 系列教程 Mybatis+xml 整合篇
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
一灰灰blog
2020/02/11
9590
SpringBoot 系列教程 Mybatis+xml 整合篇
Spring Boot从入门到精通-集成mybatis
在上一节中我们简单的使用了spring的JdbcTemplate来进行数据库操作,但是在实际的项目中使用mybatis来连接数据库是更好的选择。接下来我们将在项目中集成mybatis。 首先在pom.xml中加入mybatis的依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <vers
我的小熊不见了丶
2019/05/22
5990
Spring Boot从入门到精通-集成mybatis
SpringBoot使用Mybatis-Generator
Mybatis-Generator是Mybatis提供的一个便捷型插件,自动可以为项目生产对应的实体类,Mapper,dao层。
dalaoyang
2018/09/18
1.4K0
SpringBoot使用Mybatis-Generator
Spring boot Mybatis 整合(完整版)
7.项目不使用application.properties文件 而使用更加简洁的application.yml文件: 将原有的resource文件夹下的application.properties文件删除,创建一个新的application.yml配置文件, 文件的内容如下:
全栈程序员站长
2022/08/10
4850
Spring boot Mybatis 整合(完整版)
mybatis中collection association优化使用及多参数传递
注意:JsonIgnoreProperties请忽略,这是解决对象间循环依赖在json序列化时出错的,不在本次内容中
肖哥哥
2019/09/28
3.5K0
Spring Boot:实现MyBatis动态创建表
在有些应用场景中,我们会有需要动态创建和操作表的需求。比如因为单表数据存储量太大而采取分表存储的情况,又或者是按日期生成日志表存储系统日志等等。这个时候就需要我们动态的生成和操作数据库表了。而我们都知道,以往我们使用MyBatis是需要提前生成包括Model,Mapper和XML映射文件的,显然因为动态生成和操作表的需求一开始表都是不存在的,所以也就不能直接通过MyBatis连接数据库来生成我们的数据访问层代码并用来访问数据库了。还好MyBatis提供了动态SQL,我们可以通过动态SQL,传入表名等信息然组装成建表和操作语句,接下来,我们就通过一个具体的案例来了解一下。
朝雨忆轻尘
2019/06/19
6.9K0
Spring Boot:实现MyBatis动态创建表
使用idea快速实现spring boot(1.5*版本) 与mybatis的整合
7.项目不使用application.properties文件 而使用更加简洁的application.yml文件: 将原有的resource文件夹下的application.properties文件删除,创建一个新的application.yml配置文件, 文件的内容如下:
凯哥Java
2019/06/30
3.2K0
SpringBoot教程(十一) | SpringBoot集成Mybatis
上一篇文章我们介绍了SpringBoot集成JdbcTemplate.简单体验了一下JdbcTemplate框架的用法,今天的内容比较重要,我们来介绍一下SpringBoot集成Mybatis的步骤。
一缕82年的清风
2022/04/08
7710
SpringBoot教程(十一) | SpringBoot集成Mybatis
Spring Boot Mybatis 搞反向工程,太方便咯。。
1.拷贝 Mybatis 反向工程配置文件到项目的根目录下 2. 根据项目及表的情况,修改 GeneratorMapper.xml 配置 如果使用 高版本 , 驱动类变为:com.mysql.cj
Java小咖秀
2021/02/20
3340
Spring Boot Mybatis 搞反向工程,太方便咯。。
关注微信公众号:Java技术栈,在后台回复:Mybatis,可以获取我整理的 N 篇 Mybatis 教程,都是干货。
Java技术栈
2020/11/23
7950
Spring Boot Mybatis 搞反向工程,太方便咯。。
mybatis逆向工程
就是我们可以根据数据库表,自动生成javabean,mapper接口和其对应的maaper.xml文件。
西西嘛呦
2020/08/26
5530
mybatis逆向工程
牛逼!在IDEA里搞Spring Boot Mybatis反向工程,太爽咯~
Java 的知识面非常广,面试问的涉及也非常广泛,重点包括:Java 基础、Java 并发,JVM、MySQL、数据结构、算法、Spring、微服务、MQ 等等,涉及的知识点何其庞大,所以我们在复习的时候也往往无从下手,今天小编给大家带来一套 Java 面试题,题库非常全面,包括 Java 基础、Java 集合、JVM、Java 并发、Spring全家桶、Redis、MySQL、Dubbo、Netty、MQ 等等,包含 Java 后端知识点 2000 +
程序员白楠楠
2020/11/27
4710
springboot之mybatis
Orm 框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句 Sql 的 Hibernate,一个是可以灵活调试动态 Sql 的 Mybatis ,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用 Hibernate ,互联网行业通常使用 Mybatis 。
Vincent-yuan
2020/10/27
3730
SpringBoot集成mybatis配置
一个有趣的现象:传统企业大都喜欢使用hibernate,互联网行业通常使用mybatis;之所以出现这个问题感觉与对应的业务有关,比方说,互联网的业务更加的复杂,更加需要进行灵活性的处理,所以mybatis的灵活性特点更为适合其
小勇DW3
2018/09/29
2.5K0
从零开始做网站2-springboot整合mybatis
昨天把项目建好了,底子有了然后就是进行下一步开发了,先整合下Mybatis,使用Mybatis框架做数据持久化操作。
sunonzj
2022/06/21
2610
从零开始做网站2-springboot整合mybatis
mybatis配置文件模板(增删查改)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
用户1220053
2018/02/09
1.2K0
【Mybatis系列】Mybatis入门
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
框架师
2022/03/08
5880
【Mybatis系列】Mybatis入门
Spring+SpringMVC+Mybatis(开发必备技能)04、mybatis自动生成mapper_dao_model(包含工具与视频讲解) 纯绿色版本、配套使用视频,100%运行成功
百度网盘链接:链接:https://pan.baidu.com/s/11cO4roAQ108D9E06IHrmGw 提取码:h63e
红目香薰
2022/11/30
3430
Spring+SpringMVC+Mybatis(开发必备技能)04、mybatis自动生成mapper_dao_model(包含工具与视频讲解) 纯绿色版本、配套使用视频,100%运行成功
springboot(六):如何优雅的使用mybatis
这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis。到网上找了一下关于spring boot和mybatis组合的相关资料,各种各样的形式都有,看的人心累,结合了mybatis的官方demo和文档终于找到了最简的两种模式,花了一天时间总结后分享出来。 orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sq
纯洁的微笑
2018/04/19
1.4K0
推荐阅读
相关推荐
Mybatis传多个参数(三种解决方案)
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • Web缓存
    • 缓存命中和未命中
      • 缓存命中率
    • 私有缓冲和公有缓存
      • 私有缓存
      • 公有缓存
    • 缓存的层次化结构
    • 网状缓存、内容路由以及对等缓存
    • 缓存的处理步骤
    • 保持缓存的新鲜度
      • 条件GET
      • If-Modified-Since
      • If-None-Match
    • 强弱验证器
    • 控制缓存
      • Expires 响应首部
      • must-revalidate响应首部
      • 客户端的新鲜度限制
    • 缓存和广告
      • 发布广告者的两难处境
    • 解决方法
    • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档