为什么百度知道上改不了steam修改个人资料料,求解!

您还可以使用以下方式登录
当前位置:&>&&>& > 缓存怎么实现?
缓存怎么实现?
相关解答一:hibernate怎么实现缓存 一、why(为什么要用Hibernate缓存?)Hibernate是一个持久层框架,经常访问物理数据库。为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。二、what(Hibernate缓存原理是怎样的?)Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存。1.Hibernate一级缓存又称为“Session的缓存”。Session内置不能被卸载,Session的缓存是事务范围的缓存(Session对象的生命周期通常对应一个数据库事务或者一个应用事务)。一级缓存中,持久化类的每个实例都具有唯一的OID。2.Hibernate二级缓存又称为“SessionFactory的缓存”。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。第二级缓存是可选的,是一个可配置的插件,默认下SessionFactory不会启用这个插件。Hibernate提供了org.hibernate.cache.CacheProvider接口,它充当缓存插件与Hibernate之间的适配器。什么样的数据适合存放到第二级缓存中?1) 很少被修改的数据2) 不是很重要的数据,允许出现偶尔并发的数据3) 不会被并发访问的数据4) 常量数据不适合存放到第二级缓存的数据?1) 经常被修改的数据2) 绝对不允许出现并发访问的数据,如财务数据,绝对不允许出现并发3) 与其他应用共享的数据。3.Session的延迟加载实现要解决两个问题:正常关闭连接和确保请求中访问的是同一个session。Hibernate session就是java.sql.Connection的一层高级封装,一个session对应了一个Connection。http请求结束后正确的关闭session(过滤器实现了session的正常关闭);延迟加载必须保证是同一个session(session绑定在ThreadLocal)。4.Hibernate查找对象如何应用缓存?当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据的时候,同时更新缓存。5.一级缓存与二级缓存的对比图。一级缓存二级缓存存放数据的形式相互关联的持久化对象对象的散装数据缓存的范围事务范围,每个事务都拥有单独的一级缓存进程范围或集群范围,缓存被同一个进程或集群范围内所有事务共享并发访问策略由于每个事务都拥有单独的一级缓存不会出现并发问题,因此无须提供并发访问策略由于多个事务会同时访问二级缓存中的相同数据,因此必须提供适当的并发访问策略,来保证特定的事务隔离级别数据过期策略处于一级缓存中的对象永远不会过期,除非应用程序显示清空或者清空特定对象必须提供数据过期策略,如基于内存的缓存中对象的最大数目,允许对象处于缓存中的最长时......余下全文>>相关解答二:android内存缓存怎么实现的 二级缓存工作机制所谓二级缓存实际上并不复杂,当Android端需要获得数据时比如获取网络中的图片,我们首先从内存中查找(按键查找),内存中没有的再从磁盘文件或sqlite中去查找,若磁盘中也没有才通过网络获取;当获得来自网络的数据,就以key-value对的方式先缓存到内存(一级缓存),同时缓存到文件或sqlite中(二级缓存)。注意:内存缓存会造成堆内存泄露,所有一级缓存通常要严格控制缓存的大小,一般控制在系统内存的1/4。理解了二级缓存大家可能会有个问题网络中的数据是变化的,数据一旦放入缓存中,再取该数据就是从缓存中获得,这样岂不是不能体现数据的变化?我们在缓存数据时会设置有效时间,比如说30分钟,若超过这个时间数据就失效并释放空间,然后重新请求网络中的数据。有的童鞋就问30分钟内咋办?那好吧,我也没招了,只有下拉刷新了, 实际上这不是问题。二级缓存的实现如何实现二级缓存,有很多技术方案,在这里我们使用 ASimpleCache框架来给大家演示一下,通过名字就可以看出它是很容易实现的。1、ACache介绍ASimpleCache是一个轻量级的开源cache框架,实际上就是一个叫ACache的java类。已经在商业项目中使用,运行效果不错。2、ACache使用我们先做一个实现数据缓存的案例,然后再归纳一下主要的方法编写NewsListActivity主要代码如下:创建ACache组件ACache
acache=ACache.get(context)或ACache
acache=ACache.get(context,max_size,max_count)参数说明:max_size:设置限制缓存大小,默认为50Mmax_count:设置缓存数据的数量,默认不限制设置缓存数据acache.put(key,data,time)或acache.put(key,data)将数据同时上存入一级缓存(内存Map)和二级缓存(文件)中参数说明:Key:为存入缓存的数据设置唯一标识,取数据时就根据key来获得的Data:要存入的数据,acache支持的数据类型如图所示:有String、可序列化的对象、字节数组、Drawable等  Time:设置缓存数据的有效时间,单位秒从缓存中取数据提供一系列getAsXXX()方法,如图所示。根据不同存入数据,调用不同的方法取数据相关解答三:html5 离线缓存怎么实现的 HTML5离线存储和本地缓存一.离线存储
有一个web应用有三个文件index.html,a.js,b.css,现在需要把js和css文件缓存起来
1.在index.html里加上
2.manifest清单格式如下CACHE MANIFEST#上面一句必须#v1.0.0#需要缓存的文件CACHE:a.jsb.css#不需要缓存的文件NETWORK:*#无法访问页面FALLBACK:404.html
3.manifest文件的mime-type必须是 text/cache-manifest类型
  1.对于每个index.html?id=1或index.html?id=2都会分别缓存index.html页面,可以通过chrome浏览器Resources/Application Cache观察
  2.如果想更新缓存内容,只要修改下manifest文件即可,如改版本号v1.0.1 4.离线存储如果资源有更新,可以通过如下代码来监听,但第一次加载还会是原来的版本window.applicationCache.addEventListener('updateready',function(e){
if(window.applicationCache.status == window.applicationCache.UPDATEREADY){
window.applicationCache.swapCache();
if(confirm("loding new?")){
window.location.reload()
二.本地缓存localStorage.setItem("key","value")localStorage.getItem("key","value")localStorage.removeItem("key")localStorage.clear()
1.本地存储永不过期,除非自己去清除
2.可以通过chrome浏览器Resources/Local Storage来查看
3.不同域下就算key相同取不到的值也不同,如localhost和127.0.0.1相关解答四:memcache怎么实现分布式缓存 memcached 虽然称为 “ 分布式 ” 缓存服务器,但服务器端并没有 “ 分布式 ” 功能。每个服务器都是完全独立和隔离的服务。 memcached 的分布式,则是完全由客户端程序库实现的。 这种分布式是 memcached 的最大特点。分布式原理这里多次使用了 “ 分布式 ” 这个词,但并未做详细解释。 现在开始简单地介绍一下其原理,各个客户端的实现基本相同。下面假设 memcached 服务器有 node1 ~ node3 三台, 应用程序要保存键名为“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据。相关解答五:关于新浪微博缓存的功能是怎么实现的 这个应该是除图片的数据都存放在sqlite数据库中,图片就缓存在一个特定文件夹,根据图片名与sqlite数据库信息对应相关解答六:如何实现分布式缓存技术 分布式缓存概述1.1 分布式缓存的特性分布式缓存具有如下特性:1) 高性能:当传统数据库面临大规模数据访问时,磁盘I/O 往往成为性能瓶颈,从而导致过高的响应延迟.分布式缓存将高速内存作为数据对象的存储介质,数据以key/value 形式存储,理想情况下可以获得DRAM 级的读写性能;2) 动态扩展性:支持弹性扩展,通过动态增加或减少节点应对变化的数据访问负载,提供可预测的性能与扩展性;同时,最大限度地提高资源利用率;3) 高可用性:可用性包含数据可用性与服务可用性两方面.基于冗余机制实现高可用性,无单点失效(single point of failure),支持故障的自动发现,透明地实施故障切换,不会因服务器故障而导致缓存服务中断或数据丢失.动态扩展时自动均衡数据分区,同时保障缓存服务持续可用;4) 易用性:提供单一的数据与管理视图;API 接口简单,且与拓扑结构无关;动态扩展或失效恢复时无需人工配置;自动选取备份节点;多数缓存系统提供了图形化的管理控制台,便于统一维护;5) 分布式代码执行(distributed code execution):将任务代码转移到各数据节点并行执行,客户端聚合返回结果,从而有效避免了缓存数据的移动与传输.最新的Java 数据网格规范JSR-347中加入了分布式代码执行与Map/reduce 的API 支持,各主流分布式缓存产品,如IBM WebSphere eXtreme Scale,VMware GemFire,GigaSpaces XAP 和Red Hat Infinispan 等也都支持这一新的编程模型.相关解答七:java内存或者是缓存管理怎么实现? 晕, 你确定你是用Java,OK,不管Java还是C#1. 定义你的mapHashMap map
= new HashMap();2. 存入你的信息, 反正你得要有个唯一标识的key,以及你想存的对象map.put("userid", "userMessage");....3. 每次存入后,判断一下当前大小,java
的hashmap是size()方法,如果大于你的最大数,把原来存的前进前出删掉if(map.size()>100){//map.remove(arg0)....}更高级内容:如果对map中的cache内容有过访问,给该内容的权重+1,每次删除的时候先将权重由小至大删除。 这就是命中率缓存,一般缓存都是按这种算法做的,只是具体算法有改进相关解答八:代理服务器缓存的如何实现 5分你要做正向代理还是反向代理,正向代理需要用户浏览器进行配置,反向代理需要先配置DNS服务器,然后接受用户浏览请求,转发请求给远程服务器,当然,转发过程中可以进行访问控制操作,缓存部分我们最近也碰到了问题,现功的想法是用哈希表进行存储,利用MD5加密进行哈希函数设计相关解答九:java 缓存机制 实现的原理? 所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。缓存机制的实现有很多中,这里讲一种。public class CacheImmutale{//声明要缓存的类名;private final String classN//声明10个缓存池private static CacheImmutale[] cache= new CachImmutale[10];&#4俯;/记录缓存的位置,最新位置为[pos-1]private static int pos=0;//构造器public CacheImmutale(String className){this.className=classN}//返回方法public String getName(){return classN}//返回对象实例名,传进要使用的实例名,由该方法去判断缓存池中是否存在public static CacheImmutale valueOf(String className){//遍历缓存池,若存在,返回for(int i=0;iif(cache[i]!=null&&cache[i].getName().equals(className)){return cache[i];}}//如果缓存池满,则采取先进先出if(pos==10){cache[0]=new CacheImmutale(className);pos=1;return cache[0];}else{cache[pos++]=new CacheImmutale(className);return cache[pos-1];}}public boolean equals(Object obj){if(obj instanceof CacheImmutale){C......余下全文>>相关解答十:在页面上进行缓存后又要保证局部的数据不缓存,如何实现 页面部分缓存是指输出缓存页面的某些部分,而不是缓存整个页面内容。实现页面部分缓存有两种机制:一种是将页面中需要缓存的部分置于用户控件(.ascx文件)中,并且为用户控件设置缓存功能(包含用户控件的ASP.NET页面可设置也可不设置缓存)。这就是通常所说的“控件缓存”。设置控件缓存的实质是对用户控件进行缓存配置。主要包括以下3种方法:一是使用@ OutputCache指令以声明方式为用户控件设置缓存功能,二是在代码隐藏文件中使用PartialCachingAttribute类设置用户控件缓存;三是使用ControlCachePolicy类以编程方式指定用户控件缓存设置。另外,还有一种称为“缓存后替换”的方法。该方法与控件缓存正好相反,将页面中的某一部分设置为不缓存,因此,尽管缓存了整个页面,但是当再次请求该页时,将重新处理那些没有设置为缓存的内容。使用@ OutputCache指令控件缓存与页面输出缓存的@ OutputCache指令既有相似之处,又有不同的方面。二者的共同点在于它们的设置方法基本相同,都是文件顶部设置包含属性的@ OutputCache指令字符串。不同点包括以下两个方面:一是控件缓存的@ OutputCache指令设置在用户控件文件中,而页面输出缓存的@ OutputCache设置在普通ASP.NET文件中。二是控件缓存的@ OutputCache指令只能设置6个属性,Duration、Shared、SqlDependency、VaryByControl、VaryByCustom和VaryByParam。而在页面输出缓存的@ OutputCache指令字符串中设置的属性多达10个。以上是设置控件缓存时需要注意的问题。下面列举了一些利用@ OutputCache指令设置控件缓存的示例,其中重点说明了VaryByParam和VaryByControl等属性应用。用户控件中的@ OutputCache指令设置源代码<%@ OutputCache Duration="120" VaryByParam="CategoryID;SelectedID"%>以上代码设置用户控件缓存有效期时间是120秒,并且允许使用CategoryID和SelectedID参数来改变缓存。通过VaryByParam属性设置,在服务器缓存中可能存储多个用户控件的实例。例如,对于一个包含用户控件的页面,可能存在如下的URL链接。包含用户控件的页面的URL链接localhost/...edid=0localhost/...edid=1当请求如上URL地址的页面时,由于控件中@ OutputCache指令的设置,尤其是属性VaryByParam的设置,那么在服务器缓存中就会存储两个版本的用户控件缓存实例。控件缓存设置除了支持以上所述Va......余下全文>>百度搜索“就爱阅读”,专业资料,生活学习,尽在就爱阅读网,您的在线图书馆
欢迎转载:
推荐:    本帖子已过去太久远了,不再提供回复功能。基于Spring的Web应用缓存详解 - 知乎专栏
{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"title":"基于Spring的Web应用缓存详解","author":"tianmaying","content":"由发表在缓存的基本思想其实是以空间换时间。我们知道,IO的读写速度相对内存来说是非常比较慢的,通常一个web应用的瓶颈就出现在磁盘IO的读写上。那么,如果我们在内存中建立一个存储区,将数据缓存起来,当浏览器端由请求到达的时候,直接从内存中获取相应的数据,这样一来可以降低服务器的压力,二来,可以提高请求的响应速度,提升用户体验。缓存的分类数据库数据缓存一般来说,web应用业务逻辑业务逻辑比较复杂,数据库繁多,要获取某个完整的数据,往往要多次读取数据库,或者使用极其复杂效率较低的SQL查询语句。为了提高查询的性能,将查询后的数据放到内存中进行缓存,下次查询时,直接从内存缓存直接返回,提高响应效率。应用层缓存应用层缓存主要针对某个业务方法进行缓存,有些业务对象逻辑比较复杂,,可能涉及到多次数据库读写或者其他消耗较高的操作,应用层缓存可以将复杂的业务逻辑解放出来,降低服务器压力。页面缓存除了IO外,web应用的另一大瓶颈就是页面模板的渲染。每次请求都需要从业务逻辑层获取相应的model,并将其渲染成对应的HTML。一般来说,web应用读取数据的需求比更新数据的需求大很多,大多数情况下,某个请求返回的HTML是一样的,因此直接将HTML缓存起来也是缓存的一个主流做法。代理服务器缓存代理服务器是浏览器和源服务器之间的中间服务器,浏览器先向这个中间服务器发起Web请求,经过处理后(比如权限验证,缓存匹配等),再将请求转发到源服务器。代理服务器缓存的运作原理跟浏览器的运作原理差不多,只是规模更大。可以把它理解为一个共享缓存,不只为一个用户服务,一般为大量用户提供服务,因此在减少相应时间和带宽使用方面很有效,同一个副本会被重用多次。CDN缓存CDN( Content delivery networks )缓存,也叫网关缓存、反向代理缓存。浏览器先向CDN网关发起Web请求,网关服务器后面对应着一台或多台负载均衡源服务器,会根据它们的负载请求,动态将请求转发到合适的源服务器上。虽然这种架构负载均衡源服务器之间的缓存没法共享,但却拥有更好的处扩展性。基于spring的缓存spring作为一个成熟的java web 框架,自身有一套完善的缓存机制,同时,spring还未其他缓存的实现提供了扩展。接下来,让我们在一个简单的学生管理系统中尝试spring的数据库缓存、应用层缓存、页面缓存的实现。基于spring的Web缓存源程序简介本节课我们来看看一个简单的学生管理系统,改系统使用了Spring+JPA+EhCache的架构对数据库进行了缓存。大家可以直接下载源码进行学习。数据库准备测试程序使用了mysql作为数据库,安装好mysql后,建立一个空白的 数据库,例如cache。建好数据库后,修改src/main/resources/application.properties的数据库配置spring.datasource.url=jdbc:mysql://localhost/cache?useUnicode=true&characterEncoding=utf8\nspring.datasource.username=root\nspring.datasource.password=\n利用maven启动程序该系统利用maven作为构建工具,如果对maven没有了解的同学可以自行了解一下,我们会利用maven进行整个项目的构建以及运行。因此需要大家下载安装maven。安装完成后,打开命令行,进入程序所在目录,输入以下命令:mvn spring-boot:run\n打开浏览器,访问以下即可看到最初的博客列表页面直接运行 com.tmy.App.java如果你成功的将项目作为一个maven项目导入进eclipse,直接运行com.tmy.App.java也可以将项目启动起来。注意,如果希望将项目导入进eclipse,需要为eclipse添加maven插件,否则会出现依赖的类找不到的问题。页面列表以下是程序所提供的所有页面以及相关说明:http://localhost:8111/blogs //没有加缓存的博客列表页面\n\nhttp://localhost:8111/blogs/dao //添加了数据层缓存\n\nhttp://localhost:8111/blogs/service?test=test //添加了服务层缓存\nhttp://localhost:8111/blogs/service/update?test=test //更新服务层缓存\nhttp://localhost:8111/blogs/service/evict?test=test //删除服务层缓存\nhttp://localhost:8111/blogs/service/test?test=test //删除服务层缓存的同时更新缓存\n\nhttp://localhost:8111/blogs/page //添加了页面缓存\nhttp://localhost:8111/blogs/page/update //清空页面缓存\nhttp://localhost:8111/blogs/page/delete //清空页面缓存\n涉及到的技术mavenmaven是目前主流java的构建工具之一,如果对maven没有了解的同学可以自行了解一下,接下来我们会利用maven进行整个项目的构建以及运行。spring bootspring boot是spring的一个子项目,其目的是spring应用的初始搭建以及开发过程,如果你想自己搭建一个基于spring的应用,强烈建议学习一下在《》这门课程,教你如何从对spring零基础到搭建好一个完整的spring web应用。这里,我们只需知道mvn spring-boot:run命令可以将系统run起来即可。SpringSpring作为目前主流的java web框架,大家应该都很了解,这里不做过多介绍。JPAJPA全称Java Persistence API,JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。本门课程主要讲基于spring的数据库缓存,对于JPA的内容不做过多的涉及。EhCacheEhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点。我们的学生管理系统将利用EhCache对数据库层进行缓存。配置EhCache对EhCache的依赖上一节我们讲到很多技术,这里我们主要的依赖是指对EhCache的依赖,需要在Spring项目中引入EhCache,在pom.xml中加入以下代码即可:
&dependency&\n
&groupId&org.hibernate&/groupId&\n
&artifactId&hibernate-ehcache&/artifactId&\n
&/dependency&\n配置CacheManager添加ehcache配置文件在src/main/resources下添加文件ehcache.xml:&?xml version=\"1.0\" encoding=\"UTF-8\"?&\n&ehcache xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n
xsi:noNamespaceSchemaLocation=\"http://ehcache.org/ehcache.xsd\"\n
name=\"CM1\"\n
updateCheck=\"false\"\n
maxBytesLocalHeap=\"16M\"&\n\n
&diskStore path=\"/data/app/cache/ehcache\"/&\n\n
&defaultCache\n
eternal=\"false\"\n
overflowToDisk=\"false\"\n
maxElementsInMemory=\"10000\"\n
timeToIdleSeconds=\"3600\"\n
timeToLiveSeconds=\"36000\"\n
/&\n&/ehcache&\nencache可以对以下参数进行配置:name缓存名称maxElementsInMemory内存中最大缓存对象数maxElementsOnDisk硬盘中最大缓存对象数,若是0表示无穷大eternaltrue表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为falseoverflowToDisktrue表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。diskSpoolBufferSizeMB磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。diskPersistent是否缓存虚拟机重启期数据diskExpiryThreadIntervalSeconds磁盘失效线程运行时间间隔,默认为120秒timeToIdleSeconds设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态timeToLiveSeconds设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义memoryStoreEvictionPolicy当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。添加cacheManager首先,我们要通过@EnableCaching标注将Spring通过标注进行缓存管理的功能打开,以方便我们之后通过标注添加数据库缓存。然后,为CacheConfiguration添加@Configuration标注,打开CacheConfiguration内@Bean的功能。生成一个CacheManager的实例。最后,在web app销毁的时候销毁cacheManager。@Configuration\n@EnableCaching\npublic class CacheConfiguration {\n\n
private net.sf.ehcache.CacheManager cacheM\n\n
@PreDestroy\n
public void destroy() {\n
cacheManager.shutdown();\n
public CacheManager cacheManager() {\n
cacheManager = net.sf.ehcache.CacheManager.create();\n
EhCacheCacheManager ehCacheManager = new EhCacheCacheManager();\n
ehCacheManager.setCacheManager(cacheManager);\n
return ehCacheM\n
}\n\n}\n数据层缓存实现添加ehcache设置首先,我们需要在EhCache中设置一块区域来存放缓存,在src/main/resources/ehcache.xml中添加如下配置:&cache name=\"com.tmy.model.User\"&&/cache&\n&cache name=\"com.tmy.model.Blog\"&&/cache&\nHibernate的一级缓存和二级缓存Hibernate提供了两级缓存,第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,hibernate会默认提供好。第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集群范围的缓存。这个缓存中存放的对象的松散数据第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。打开二级缓存我们可以通过为entry对象添加标注的方式打开二级缓存:@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)\n二级缓存一共有以下5种策略:CacheConcurrencyStrategy.NONE不使用缓存,默认的缓存策略CacheConcurrencyStrategy.READ_ONLY只读模式,在此模式下,如果对数据进行更新操作,会有异常CacheConcurrencyStrategy.READ_WRITE读写模式在更新缓存的时候会把缓存里面的数据换成一个锁,其它事务如果去取相应的缓存数据,发现被锁了,直接就去数据库查询CacheConcurrencyStrategy.NONSTRICT_READ_WRITE不严格的读写模式则不会的缓存数据加锁CacheConcurrencyStrategy.TRANSACTIONAL事务模式指缓存支持事务,当事务回滚时,缓存也能回滚指定cache region factory然后,在src/main/resources/application.properties中为cache指定一个factory:spring.jpa.properties. =org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory\n性能对比第一次访问第一次访问时,waiting也就是服务器响应的时间为2.82秒,耗时较多。注意:这里消耗2.82秒的原因是:在Blog对象中添加了对成员creator添加了@ManyToOne的标注,因此,当通过JPA获取blog对象后,JPA还会请求一次SQL查询,去user表中获取user信息,将user填充进来,而为了效果更加明显,系统在添加测试数据时为每个blog都添加了不同的user,导致sql请求大大增加,处理时间也大大增加多次访问未缓存页面多次访问后,服务器响应时间大大减少,基本保持在700毫秒左右:这是因为mysql实际上帮我们做了缓存的工作,因此,多次访问后,服务器响应时间会大大减少。如果大家有兴趣,可以自行搜索mysql缓存相关的内容。多次访问已缓存页面那么,在多次访问后,访问时间基本保持在100多毫秒,比没有缓存的页面效率高了5倍左右,比第一次访问效率高了20倍以上。服务层缓存实现Spring缓存的相关标注Spring 提供了一套标注来保住我们快速的实现缓存系统:@Cacheable 触发添加缓存的方法@CacheEvict 触发删除缓存的方法@CachePut 在不干涉方法执行的情况下更新缓存@Caching 组织多个缓存标注的标注@CacheConfig 在class的层次共享缓存的设置接下来我们来看缓存的具体实现。添加ehcache设置和数据层缓存一样,需要在内存中设置一块区域来存放service的缓存,在src/main/resources/ehcache.xml中添加如下配置:&cache name=\"com.tmy.service.allBlogs\"&&/cache&\n为某个方法添加缓存首先,在BlogWithCacheService上添加@CacheConfig(cacheNames = \"com.tmy.service.allBlogs\")标注,表明在BlogWithCacheService中的方法的缓存都是放在com.tmy.service.allBlogs区域中。在需要缓存的方法上添加@Cacheable标注:@Cacheable(key = \"#justTest\")\npublic List&BlogWithoutCache& findAll(String justTest){\n
return blogRepository.findAll();\n}\n当第一次调用该方法后,其返回值就会添加进缓存当中,当第二次调用时就能直接从缓存中获取对象了。为了测试缓存功能,我们为findAll方法添加了一个参数,这里我们将这个参数作为缓存的key。除了用参数之外,Spring还提供了其他解析方式来生成key:被调用方法的名称 #root.methodName被调用的方法 #root.method.name被调用的目标对象 #root.target被调用的对象的类名 #root.targetClass被调用方法的参数 #root.args[0]被调用方法所用的缓存 #root.caches[0].name被调用方法的参数名 #arg调用后的结果(该参数只在unless参数或者@CachePut标注中才能使用) #result更新缓存添加进缓存后,在update方法中添加@CachePut标注可以更新相应的缓存,同样,我们还是使用传进来的参数来更新相应的缓存:@CachePut(key = \"#justTest\")\npublic List&BlogWithoutCache& updateAll(String justTest){\n
BlogWithoutCache blog = new BlogWithoutCache();\n
blog.setContent(\"这是不存在的博客\");\n
blog.setTitle(\"谨慎使用这个方法\");\n
return Lists.newArrayList(blog);\n}\n删除缓存在某些情况下,我们还需要删除缓存,@CacheEvict可以干这件事情:@CacheEvict(key = \"#justTest\")\npublic void evictAll(String justTest){\n}\n组织多种缓存操作如果你想在一个方法中同时对缓存做多种操作,Spring支持使用@Caching来组织这些操作:@Caching(evict = @CacheEvict(key=\"#justTest\"), put = @CachePut(key=\"test\"))\npublic List&BlogWithoutCache& testForCaching(String justTest){\n
BlogWithoutCache blog = new BlogWithoutCache();\n
blog.setContent(\"这是不存在的博客\");\n
blog.setTitle(\"谨慎使用这个方法\");\n
return Lists.newArrayList(blog);\n}\n性能对比多次访问service层缓存页面在多次访问后,服务器的访问时间基本保持在100毫秒以下,根据上次实验可以发现,其效率甚至比加了数据层缓存后还要高。更新缓存更新缓存前,访问页面,看下以下博客:访问,将发现数据库没有变化,但是返回的博客列表发生了变化:删除缓存现在缓存对象已经被玩坏了,让我们访问缓存的对象给删掉,再次访问,我们发现博客列表重新变为正确的列表,同时服务器响应时间变成和没有做缓存时一致:页面缓存的实现添加缓存空间同样,第一件事情让我们添加一下缓存的空间:&cache name=\"com.tmy.mapper.allBlogs\"&&/cache&\nPageCachingFilterehcache为我们提供了几个缓存页面的filter,使用这些filter实现缓存:SimplePageCachingFilter最基本的页面缓存filter实现,其满足大部分页面缓存的需求,该filter只缓存页面,不会修改herder的 ETag、Last-Modified、Expires属性SimplePageCachingFilterWithBlankPageProblem当response没有提交时写入缓存,否则不写缓存,该缓存可能导致空白页的错误,需要特别注意!SimplePageFragmentCachingFilter专门针对那些不独立存在,只是被include到其他页面的页面缓存SimpleCachingHeadersPageCachingFilterSimplePageCachingFilter的扩展,会填写herder的 ETag、Last-Modified、Expires属性,可以进一步减少浏览器的访问次数自定义的PageCachingFilter以上filter会在filter初始化的时候通过FilterConfig对缓存进行初始化,为了在SpringBoot中方便的通过注解去实例化这些Filter,我们将CacheName的获取做一个定制:public class CustomPageCachingFilter extends SimpleCachingHeadersPageCachingFilter {\n\n
private final String customCacheN\n\n
public CustomPageCachingFilter(String name){\n
this.customCacheName =\n
@Override\n
protected String getCacheName() {\n
return customCacheN\n
}\n\n}\n这样,我们就能很方便的注入cacheName了。EhCache只提供了添加缓存的Filter,但是并没有提供删除缓存的Filter,没关系,让我们来自己实现一个:public class ClearPageCachingFilter implements Filter {\n\n
private final CacheManager cacheM\n\n
private final String customCacheN\n\n
public ClearPageCachingFilter(String name){\n
this.customCacheName =\n
cacheManager = CacheManager.getInstance();\n
assert cacheManager !=\n
@Override\n
public void init(FilterConfig filterConfig) throws ServletException {}\n\n
@Override\n
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,\n
ServletException {\n
Ehcache ehcache = cacheManager.getEhcache(customCacheName);\n
ehcache.removeAll();\n
@Override\n
public void destroy() {}\n}\n现实情况URL的设计是极其复杂的,我们在这里就简单粗暴的将所有cache直接删除,如果缓存设计的比较好,最好可以通过ehcache.remove(key);的方式对cache进行管理。添加Filter我们目前使用标注的方式对Filter以及Filter mapping进行管理,目前我们只缓存/blogs/page这一个页面:@Configuration\n@AutoConfigureAfter(CacheConfiguration.class)\npublic class PageCacheConfiguration {\n\n
public FilterRegistrationBean registerBlogsPageFilter(){\n
CustomPageCachingFilter customPageCachingFilter = new CustomPageCachingFilter(\"com.tmy.mapper.allBlogs\");\n
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();\n
filterRegistrationBean.setFilter(customPageCachingFilter);\n
filterRegistrationBean.setUrlPatterns(Lists.newArrayList(\"/blogs/page\"));\n
return filterRegistrationB\n
public FilterRegistrationBean registerClearBlogsPageFilter(){\n
ClearPageCachingFilter clearPageCachingFilter = new ClearPageCachingFilter(\"com.tmy.mapper.allBlogs\");\n
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();\n
filterRegistrationBean.setFilter(clearPageCachingFilter);\n
filterRegistrationBean.setUrlPatterns(Lists.newArrayList(\"/blogs/page/update\", \"/blogs/page/delete\"));\n
return filterRegistrationB\n
}\n\n}\n从以上配置可以看出,我们为/blogs/page注册了一个添加缓存的Filter,/blogs/page请求将被缓存到内存当中。同时,为/blogs/page/update以及/blogs/page/delete注册了清空缓存的Filter,当访问这两个url时,将清空所有的缓存。性能对比访问被缓存的页面访问,刷新,我们可以看到,服务器的响应时间只需要4毫秒,是mysql缓存、数据层缓存、服务层缓存当中最好的。清空缓存后第一次访问我们可以将以上几种缓存结合起来一起使用,,该请求已经结合了以上三种缓存的实现。因此,当我们访问清空页面缓存时,再次访问也只需要100多毫秒,此时页面缓存没有命总结就实践看来,数据层缓存、服务层缓存、页面缓存一层比一层更加高效,但是由于其实现越来越复杂,需要考虑的情况也越来越多,因此,其设计也越来越复杂。从服务层缓存的实现@CachePut实现来看,在这一层需要我们配置的东西越来越多,已经有很大可能出现数据不一致的现象。而页面缓存的复杂性相对服务层缓存又高了一个层级,因此在针对缓存进行设计的时候,不仅仅考虑缓存所带来的性能提升,还要考虑到更新缓存所带来的性能损失。而且在实践当中,不是数据层缓存、服务层缓存、页面缓存越多越好,需要根据实际情况做出选择。欢迎关注天码营微信公众号: TMY-EDU小编重点推荐:更多精彩内容请访问","updated":"T14:33:15.000Z","canComment":false,"commentPermission":"anyone","commentCount":0,"collapsedCount":0,"likeCount":9,"state":"published","isLiked":false,"slug":"","isTitleImageFullScreen":false,"rating":"none","titleImage":"/90a01c74e98c2fa2e82bd68de4f623f5_r.png","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"Spring"},{"url":"/topic/","id":"","name":"Java Web"},{"url":"/topic/","id":"","name":"缓存"}],"adminClosedComment":false,"titleImageSize":{"width":1058,"height":640},"href":"/api/posts/","excerptTitle":"","column":{"slug":"tianmaying","name":"David教你学Java Web开发"},"tipjarState":"inactivated","annotationAction":[],"sourceUrl":"","pageCommentsCount":0,"snapshotUrl":"","publishedTime":"T22:33:15+08:00","url":"/p/","lastestLikers":[{"bio":"对大型分布式系统的设计与实践有着浓厚的兴趣","isFollowing":false,"hash":"47da5dfcafeb2e45777fc3","uid":992400,"isOrg":false,"slug":"bu-neng-shuo-de-mi-mi-50","isFollowed":false,"description":"","name":"不能说的秘密","profileUrl":"/people/bu-neng-shuo-de-mi-mi-50","avatar":{"id":"df9fa45d0b63fe682c5dde32b971402b","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"我在未来等你。","isFollowing":false,"hash":"8c8f1e77f2fde6e1881b78","uid":016400,"isOrg":false,"slug":"du-xiao-dong-45","isFollowed":false,"description":"Java爱好者:p\nBlog: \nGithub: /shildondu","name":"冬非我冬","profileUrl":"/people/du-xiao-dong-45","avatar":{"id":"4b7cb374d6edc9bda836b","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"java开发","isFollowing":false,"hash":"38e750b8c98a89a03b53e","uid":92,"isOrg":false,"slug":"calebzhao","isFollowed":false,"description":"","name":"Caleb","profileUrl":"/people/calebzhao","avatar":{"id":"c310bb009b50ae68c9329e99ffa44ba4","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"","isFollowing":false,"hash":"87b309a1b659ebda4e306c49caa170d2","uid":16,"isOrg":false,"slug":"herowzz","isFollowed":false,"description":"","name":"herowzz","profileUrl":"/people/herowzz","avatar":{"id":"cf3b10529","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"","isFollowing":false,"hash":"22ea4ba02b8bfda3603623a","uid":468400,"isOrg":false,"slug":"e-wu-liao-wu-liao-dao","isFollowed":false,"description":"","name":"听故事的","profileUrl":"/people/e-wu-liao-wu-liao-dao","avatar":{"id":"d7d66d27a3e710e0c5bbfd89ef175ef3","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"由发表在缓存的基本思想其实是以空间换时间。我们知道,IO的读写速度相对内存来说是非常比较慢的,通常一个web应用的瓶颈就出现在磁盘IO的读写上。那么,如果我们在内存中建立一个存储区,将数据缓存起来,当浏览器端由请求到达的时候,直接从内…","reviewingCommentsCount":0,"meta":{"previous":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/28baf25bd9e6e0f6cda9667_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"jQuery"},{"url":"/topic/","id":"","name":"Java Web"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"天码营-实战开发技术学习平台-创始人","isFollowing":false,"hash":"acd41dfe43fcc818e301fef16a0c008c","uid":437300,"isOrg":false,"slug":"tianmaying","isFollowed":false,"description":"天码营创始人(官方网站:),致力于打造新一代的技术学习服务平台,提供创新并且专业的内容、工具与服务,帮助学习者与从业者实现个人价值。","name":"David","profileUrl":"/people/tianmaying","avatar":{"id":"799df728d7d9e8e52b9eb","template":"/{id}_{size}.png"},"isOrgWhiteList":false},"column":{"slug":"tianmaying","name":"David教你学Java Web开发"},"content":"由发表在jQuery入门jQuery是一个快速简单的JavaScript工具库,为快速开发提供了DOM遍历、事件处理、动画、AJAX交互几个方面的工具。jQuery会改变你写JavaScript的方式。先来看看jQuery用起来是怎样的:// 给拥有continue类的&button&元素设置文本为:Next Step...\n$( \"button.continue\" ).html( \"Next Step...\" )\n\n// 监听拥有btn-next ID的元素的点击事件\n$( \"#btn-next\" ).on( \"click\", function( event ) {\n
alert('clicked!')\n});\n引入jQueryjQuery是一种JavaScript库,应当使用&script&标签加以引入。可以有两种方式:使用jQuery CDN。在HTML中加入下面的代码: &script src=\"/jquery-2.2.3.min.js\"&&/script&\n也有很多其他CDN可选,参见:使用本地文件。首先在这里:下载jquery.min.js。然后在HTML中加以引入: &script src=\"your/path/to/jquery.min.js\"&&/script&\n名称选择器jQuery最常用的特性便是DOM操作。使用$()进行DOM元素的选择,其参数成为选择符(selector)。返回值为jQuery集合,该集合是DOM元素集合的一个包装,可以更方便地进行DOM操作。顾名思义,名称选择器是根据DOM元素的名称进行选择的。例如下面的HTML:&div&harttle&/div&\n&p&My name is harttle.&/p&\n&div&harttleland&/div&\n运行下列jQuery操作:$('div').html('David');\n你的HTML将会变成这样:&div&David&/div&\n&p&My name is harttle.&/p&\n&div&David&/div&\njQuery选中了所有的&div&标签并设置了它的内容。ID选择符ID选择符是以#起始的字符串,例如对下面的HTML:&div id=\"name\"&&/div&\n&div&&/div&\n运行下列jQuery操作:$('#name').html('Harttle');\n其中html()函数用来设置jQuery集合中DOM元素的HTML内容,操作后HTML会变成这样:&div id=\"name\"&Harttle&/div&\n&div&&/div&\n其他选择器到这里想必你会发现jQuery选择器和CSS选择器很像,这是jQuery故意设计的(CSS Compliance)。这样才方便前端人员的工作。其他的一些CSS风格选择符都是可用的,例如:Class选择符:.active。后代元素选择符:div #name。子元素选择符:div&#name。属性选择符:a[href=\"/foo.html\"]。更多的jQuery选择器等着你去探索:事件监听DOM事件处理在不同浏览器中一直没有一致的实现,包括attachEvent、addEventListener、onclick等方法。jQuery提供了一致的DOM事件处理方式,最常用的包括on和click方法:&button class=\"next\"&下一步&/button&\n$('button.next').click(function(){\n
alert('clicked 1!');\n});\n\n$('button.next').on('click', function(){\n
alert('clicked 2!');\n});\n在鼠标点击那个具有next类的&button&时,便会弹出两个提示。其实.click()只是.on('click')的快捷方式,本质上还是调用后者来实现的。不同的是.on还可以绑定其他事件,比如:.on('hover'),.on('touch')等等。DOM创建jQuery还提供了DOM创建和插入的工具,不需要再用繁琐的DOM API了!&div class=\"name\"&&/div&\n&button&Remove&/button&\n将$()函数传入参数的选择符替换成一段HTML即可创建HTML元素,然后使用.append()方法将新创建的元素插入到DOM中对应的位置。使用.remove()方法可以移除当前选择符选中的元素。var element = $('&p&Harttle&/p&');\n$('.name').append(element);\n$('button').click(function(){\n
element.remove();\n});\n在页面初始化后,jQuery在&div class=\"name\"&里面插入了一个&p&标签。点击&button&,jQuery会去移除刚刚插入的&p&标签。动画jQuery集合还有一个.animate方法,可以让某个属性的值产生渐变。例如:&div style=\"background:height:20width:20\"&&/div&\n&button&Am Button&/button&\n.animate的第一个参数是一个CSS属性列表,可以包含任意多的键值对。第二个参数是渐变的时间,这里没有设置采用默认值normal。$(\"button\").click(function(){\n
$(\"div\").animate({height:\"300px\"});\n});\n点击按钮后会逐渐变高。.animate还有很多更好玩的参数,比如时间函数、结束回调等,可以在这里查阅:一个例子上面详细介绍了jQuery的各种使用方式,包括DOM创建与遍历、事件监听、动画效果等。其实当你开始使用jQuery后会发现更多的特性,比你想象中还要好用!还是那句话:jQuery会改变你写JavaScript的方式。下面给一个例子,看看用jQuery写的JavaScript是怎样的:// 选择 id 为 fruits 的元素集合(该集合中只有一个元素,即 ul )\nvar $ul = $('#fruits');\n// 找到该元素的第一个子元素(即 li)并将其移除\n$ul.find(':first-child').remove();\n// 创建一个 li 元素,并设置其 color 样式为 red,其内容为 pear\nvar $pear = $('&li&')\n
.css('color', 'red')\n
.html('pear');\n// 将 pear 添加到 ul 中\n$ul.append($pear);\n欢迎关注天码营微信公众号: TMY-EDU小编重点推荐:更多精彩内容请访问","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T00:29:05+08:00","url":"/p/","title":"JavaScript框架jQuery入门","summary":"由发表在jQuery入门jQuery是一个快速简单的JavaScript工具库,为快速开发提供了DOM遍历、事件处理、动画、AJAX交互几个方面的工具。jQuery会改变你写JavaScript的方式。先来看看jQuery用起来是怎样的:// 给拥有continue类的&button&元素设置…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":0,"likesCount":0},"next":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/ed675226bad7f6ced2a60aed26ce14fb_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"Spring"},{"url":"/topic/","id":"","name":"Java Web"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"天码营-实战开发技术学习平台-创始人","isFollowing":false,"hash":"acd41dfe43fcc818e301fef16a0c008c","uid":437300,"isOrg":false,"slug":"tianmaying","isFollowed":false,"description":"天码营创始人(官方网站:),致力于打造新一代的技术学习服务平台,提供创新并且专业的内容、工具与服务,帮助学习者与从业者实现个人价值。","name":"David","profileUrl":"/people/tianmaying","avatar":{"id":"799df728d7d9e8e52b9eb","template":"/{id}_{size}.png"},"isOrgWhiteList":false},"column":{"slug":"tianmaying","name":"David教你学Java Web开发"},"content":"由发表在数据库操作是我们搭建应用的基本操作,今天我们来学习一下如何利用Spring Data Jpa访问关系型数据库吧。环境准备一个称手的文本编辑器(例如Vim、Emacs、Sublime Text)或者IDE(Eclipse、Idea Intellij)Java环境(JDK 1.7或以上版本)构建工具Gradle 2.3关系型数据库使用Gradle作为项目构建工具首先创建一个项目目录,在目录中创建一个Gradle项目描述文件build.gradle:buildscript {\n
repositories {\n
jcenter()\n
dependencies {\n
classpath \"org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE\"\n
classpath \"com.github.adrianbk:gradle-jvmsrc-plugin:0.6.1\"\n
}\n}\n\napply plugin: 'java'\napply plugin: 'eclipse'\napply plugin: 'idea'\napply plugin: 'spring-boot'\napply plugin: 'com.github.adrianbk.jvmsrc'\n\njvmsrc {\n
packageName \"tmy\"\n}\n\njar {\n
baseName = 'spring-boot-guides'\n
'1.0.0'\n}\n\nrepositories {\n
jcenter()\n}\n\ndependencies {\n
compile(\"org.springframework.boot:spring-boot-starter-data-jpa\")\n}\n\ntask wrapper(type: Wrapper) {\n
gradleVersion = '2.4'\n}\n在这个文件中,使用到了来帮助我们简化一些配置工作:提供了Spring Boot框架的依赖定义,在dependencies标签中直接使用它们即可(不需要声明版本号)将应用的代码及所有的依赖打包成一个单独的jar文件自动搜索main函数并作为jar文件的启动函数,jar文件是一个独立可执行的文件spring-boot-starter-data-jpa引入了项目的依赖另外由于Gradle的默认特性——例如源代码放在src/main/java文件夹下,我们引入插件,通过配置:apply plugin: 'com.github.adrianbk.jvmsrc'\n\njvmsrc {\n
packageName \"tmy\"\n}\n并运行gradle createJvmSrcDirs,src/main/java/tmy等目录就被创建出来,省去我们手动创建的麻烦。定义实体对象这节课中我们将定义一个实体对象User并将其存储到关系型数据库中,并使用JPA注解:src/main/java/tmy/User.java\n\nimport javax.persistence.E\nimport javax.persistence.GeneratedV\nimport javax.persistence.GenerationT\nimport javax.persistence.Id;\n\n@Entity\npublic class User {\n\n
@GeneratedValue(strategy=GenerationType.AUTO)\\n
private String firstN\n
private String lastN\n\n
protected User() {}\n\n
public User(String firstName, String lastName) {\n
this.firstName = firstN\n
this.lastName = lastN\n
@Override\n
public String toString() {\n
return String.format(\n
\"User[id=%d, firstName='%s', lastName='%s']\",\n
id, firstName, lastName);\n
}\n\n}\nUser对象包含三个字段:id作为唯一标识符,这里用到了JPA注解@GeneratedValue(strategy=GenerationType.AUTO)表明它是一个自增字段firstName和lastName没有任何注解,但User注解为@Entity所以它们也被映射为同名的字段提示User对象各个字段都是private的,所以还需要为它们加上Getter/Setter方法,限于篇幅,本课程中都省略这些方法创建对象访问方法Spring Data JPA项目使用JPA注解将Java对象转化为关系型数据库中的记录。它最大的特点是能够自动创建数据访问对象的实现,例如现在我们创建一个访问User对象的接口:src/main/java/tmy/UserRepository.java\n\nimport java.util.L\n\nimport org.springframework.data.repository.CrudR\n\npublic interface UserRepository extends CrudRepository&User, Long& {\n\n
List&User& findByLastName(String lastName);\n}\nUserRepository继承了Spring Data JPA中的CrudRepository,已经包含了保存(save()),删除(delete()),查询(findOne(), findAll())等预定义方法,同时开发者还能够根据命名约定来扩展,上例中的findByLastName(String lastName)实际上等价于SQL语句select * from user where lastName=?。在接口中定义这个方法后,无需实现它,Spring Data JPA会根据方法的名字自动实现这个方法,很方便吧!创建Application类运行应用src/main/java/tmy/Application.java\n\nimport org.springframework.beans.factory.annotation.A\nimport org.mandLineR\nimport org.springframework.boot.SpringA\nimport org.springframework.boot.autoconfigure.SpringBootA\n\n@SpringBootApplication\npublic class Application implements CommandLineRunner {\n\n
@Autowired\n
public static void main(String[] args) {\n
SpringApplication.run(Application.class);\n
@Override\n
public void run(String... strings) throws Exception {\n
// save a couple of users\n
repository.save(new User(\"Jack\", \"Bauer\"));\n
repository.save(new User(\"Chloe\", \"O'Brian\"));\n
repository.save(new User(\"Kim\", \"Bauer\"));\n
repository.save(new User(\"David\", \"Palmer\"));\n
repository.save(new User(\"Michelle\", \"Dessler\"));\n\n
// fetch all users\n
System.out.println(\"User found with findAll():\");\n
System.out.println(\"-------------------------------\");\n
for (User user : repository.findAll()) {\n
System.out.println(user);\n
System.out.println();\n\n
// fetch an individual user by ID\n
User user = repository.findOne(1L);\n
System.out.println(\"User found with findOne(1L):\");\n
System.out.println(\"--------------------------------\");\n
System.out.println(user);\n
System.out.println();\n\n
// fetch customers by last name\n
System.out.println(\"User found with findByLastName('Bauer'):\");\n
System.out.println(\"--------------------------------------------\");\n
for (User user : repository.findByLastName(\"Bauer\")) {\n
System.out.println(user);\n
}\n\n}\n总结这节课中我们使用Spring Data JPA对关系型数据库进行访问,在实现过程中借助Spring Boot框架很轻易的配置了Spring Data JPA。这让我们更加专注于业务并且能够编写出质量更高、可维护性更好的代码。欢迎关注天码营微信公众号: TMY-EDU小编重点推荐:更多精彩内容请访问","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T10:15:49+08:00","url":"/p/","title":"使用Spring Data JPA访问关系型数据库","summary":"由发表在数据库操作是我们搭建应用的基本操作,今天我们来学习一下如何利用Spring Data Jpa访问关系型数据库吧。环境准备一个称手的文本编辑器(例如Vim、Emacs、Sublime Text)或者IDE(Eclipse、Idea Intellij)Java环境(JDK 1.7或以上版本)…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":0,"likesCount":0}},"annotationDetail":null,"commentsCount":0,"likesCount":9,"FULLINFO":true}},"User":{"tianmaying":{"isFollowed":false,"name":"David","headline":"天码营创始人(官方网站:),致力于打造新一代的技术学习服务平台,提供创新并且专业的内容、工具与服务,帮助学习者与从业者实现个人价值。","avatarUrl":"/799df728d7d9e8e52b9eb_s.png","isFollowing":false,"type":"people","slug":"tianmaying","bio":"天码营-实战开发技术学习平台-创始人","hash":"acd41dfe43fcc818e301fef16a0c008c","uid":437300,"isOrg":false,"description":"天码营创始人(官方网站:),致力于打造新一代的技术学习服务平台,提供创新并且专业的内容、工具与服务,帮助学习者与从业者实现个人价值。","profileUrl":"/people/tianmaying","avatar":{"id":"799df728d7d9e8e52b9eb","template":"/{id}_{size}.png"},"isOrgWhiteList":false,"badge":{"identity":null,"bestAnswerer":null}}},"Comment":{},"favlists":{}},"me":{},"global":{},"columns":{"tianmaying":{"following":false,"canManage":false,"href":"/api/columns/tianmaying","name":"David教你学Java Web开发","creator":{"slug":"tianmaying"},"url":"/tianmaying","slug":"tianmaying","avatar":{"id":"327efd931bc33","template":"/{id}_{size}.jpeg"}}},"columnPosts":{},"postComments":{},"postReviewComments":{"comments":[],"newComments":[],"hasMore":true},"favlistsByUser":{},"favlistRelations":{},"promotions":{},"switches":{"couldAddVideo":false},"draft":{"titleImage":"","titleImageSize":{},"isTitleImageFullScreen":false,"canTitleImageFullScreen":false,"title":"","titleImageUploading":false,"error":"","content":"","draftLoading":false,"globalLoading":false,"pendingVideo":{"resource":null,"error":null}},"config":{"userNotBindPhoneTipString":{}},"recommendPosts":{"articleRecommendations":[],"columnRecommendations":[]},"env":{"isAppView":false,"appViewConfig":{"content_padding_top":128,"content_padding_bottom":56,"content_padding_left":16,"content_padding_right":16,"title_font_size":22,"body_font_size":16,"is_dark_theme":false,"can_auto_load_image":true,"app_info":"OS=iOS"},"isApp":false},"sys":{}}}

我要回帖

更多关于 千牛更改个人资料 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信