好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用Spring Data Redis实现数据缓存的方法

引言

目前很多系统为了解决数据读写的性能瓶颈,在系统架构设计中使用redis实现缓存,spring框架为了让开发人员更加方便快捷的使用redis实现缓存,对redis的操作进行了包装。

0.缓存

个人理解的缓存是指用于存储频繁使用的数据的空间,关注点是存储数据的空间和使用频繁的数据。缓存技术,简单的说就是先从缓存中查询数据是否存在,存在则直接返回,不存在再执行相应的操作获取数据,并将获取的数据存储到缓存中,它是一种提升系统性能的重要方法。

1.redis

redis是一个开源的、内存存储key-value类型的数据结构服务器,可用作数据库、高速缓存和消息队列代理。它支持的数据类型有字符串、哈希表、列表、集合、有序集合等,同时通过redis sentinel提供高可用,通过redis cluster提供分区功能。

2.jedis

jedis是redis的java版客户端实现,也是官方推荐的java版客户端。它封装了对redis的各种操作,并且支持事务、管道及有jedis自身实现的分布式。

3.spring data redis

spring data是spring框架中的一个主要项目,目的是为了简化构建基于spring框架应用的数据访问,包括非关系数据库、map-reduce框架、云数据服务等,另外也包含对关系数据库的访问支持。
spring data redis是spring data项目中的一个主要模块,实现了对jedis客户端api的高度封装,使对redis的操作更加便捷。

4.关系图

redis、jedis、spring data redis三者之间的关系图如下所示。

5.spring cache

从spring3.1开始,spring框架提供了对cache的支持,提供了一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的作用。提供的主要注解有@cacheable、@cacheput、@cacheevict和@caching,具体见表1。

@cacheable的常用属性及说明如表2所示。

@cacheevict的常用属性见表4。@cacheput的常用属性同@cacheable。

当需要在类上或方法上同时使用多个注解时,可以使用@caching,如@caching(cacheable = @cacheable("user"), evict = {@cacheevict("member"), @cacheevict(value = "customer", allentries = true)})

6.使用示例

下面使用spring data reds、redis和jedis实现一个简单的数据缓存。

1)依赖配置

示例使用了gradle,所以需要在build.gradle中加入如下依赖配置来管理所需要的jar。

?

1

2

3

compile "org.springframework.data:spring-data-redis:1.7.2.release"

compile "redis.clients:jedis:2.7.2"

testcompile "junit:junit:4.12"

2)redis配置

示例连接的是本地的redis,redis.properties配置如下。

?

1

2

3

4

5

6

7

8

9

10

# redis settings

redis.host= 127.0 . 0.1

redis.port= 6379

redis.pass=

redis.dbindex= 0

redis.expiration= 3000

redis.maxidle= 300

redis.maxactive= 600

redis.maxwait= 1000

redis.testonborrow= true

3)spring配置

spring的配置文件如下。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

<?xml version= "1.0" encoding= "utf-8" standalone= "no" ?>

<beans xmlns:xsi= "http://HdhCmsTestw3.org/2001/xmlschema-instance"

     xmlns= "http://HdhCmsTestspringframework.org/schema/beans"

     xmlns:context= "http://HdhCmsTestspringframework.org/schema/context"

     xmlns:cache= "http://HdhCmsTestspringframework.org/schema/cache"

     xsi:schemalocation="http: //HdhCmsTestspringframework.org/schema/beans

     http: //HdhCmsTestspringframework.org/schema/beans/spring-beans.xsd

     http: //HdhCmsTestspringframework.org/schema/context http://HdhCmsTestspringframework.org/schema/context/spring-context.xsd

     http: //HdhCmsTestspringframework.org/schema/cache http://HdhCmsTestspringframework.org/schema/cache/spring-cache.xsd">

   <context:component-scan base- package = "redis.cache" />

   <context:annotation-config/>

   <cache:annotation-driven cache-manager= "rediscachemanager" />

   <bean class = "org.springframework.beans.factory.config.propertyplaceholderconfigurer" >

     <property name= "locations" >

       <list>

         <value>classpath:redis.properties</value>

       </list>

     </property>

   </bean>

   <!-- 配置jedispoolconfig实例 -->

   <bean id= "poolconfig" class = "redis.clients.jedis.jedispoolconfig" >

     <property name= "maxidle" value= "${redis.maxidle}" />

     <property name= "maxtotal" value= "${redis.maxactive}" />

     <property name= "maxwaitmillis" value= "${redis.maxwait}" />

     <property name= "testonborrow" value= "${redis.testonborrow}" />

   </bean>

   <!-- 配置jedisconnectionfactory -->

   <bean id= "jedisconnectionfactory" class = "org.springframework.data.redis.connection.jedis.jedisconnectionfactory" >

     <property name= "hostname" value= "${redis.host}" />

     <property name= "port" value= "${redis.port}" />

     <property name= "password" value= "${redis.pass}" />

     <property name= "database" value= "${redis.dbindex}" />

     <property name= "poolconfig" ref= "poolconfig" />

   </bean>

   <!-- 配置redistemplate -->

   <bean id= "redistemplate" class = "org.springframework.data.redis.core.redistemplate" >

     <property name= "connectionfactory" ref= "jedisconnectionfactory" />

   </bean>

   <!-- 配置rediscachemanager -->

   <bean id= "rediscachemanager" class = "org.springframework.data.redis.cache.rediscachemanager" >

     <constructor-arg name= "redisoperations" ref= "redistemplate" />

     <property name= "defaultexpiration" value= "${redis.expiration}" />

   </bean>

</beans>

4)service

示例代码的servicer如下。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@service ( "userservice" )

public class userservice {

   @cacheable (value = "user" , key = "'userid_' + #id" ,condition = "#id<=110" )

   public string queryfullnamebyid( long id) {

     system.out.println( "execute queryfullnamebyid method" );

     return "zhangsanfeng" ;

   }

 

   @cacheevict (value = "user" , key = "'userid_' + #id" )

   public void deletebyid( long id) {

     system.out.println( "execute deletebyid method" );

   }

 

   @cacheput (value = "user" , key = "'userid_' + #id" )

   public string modifyfullnamebyid( long id, string newname) {

     system.out.println( "execute modifyfullnamebyid method" );

     return newname;

   }

}

5)测试

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

@test

public void test() {

   applicationcontext context = new classpathxmlapplicationcontext( "rediscachecontext.xml" );

   userservice userservice = (userservice) context.getbean( "userservice" );

   system.out.println( "第一次执行查询:" + userservice.queryfullnamebyid(110l));

   system.out.println( "----------------------------------" );

 

   system.out.println( "第二次执行查询:" + userservice.queryfullnamebyid(110l));

   system.out.println( "----------------------------------" );

 

   userservice.deletebyid(110l);

   system.out.println( "----------------------------------" );

 

   system.out.println( "清除缓存后查询:" + userservice.queryfullnamebyid(110l));

   system.out.println( "----------------------------------" );

 

   system.out.println(userservice.modifyfullnamebyid(110l, "zhangjunbao" ));

   system.out.println( "----------------------------------" );

 

   system.out.println( "修改数据后查询:" + userservice.queryfullnamebyid(110l));

   system.out.println( "----------------------------------" );

 

   system.out.println( "第一次执行查询:" + userservice.queryfullnamebyid(112l));

   system.out.println( "----------------------------------" );

 

   system.out.println( "第二次执行查询:" + userservice.queryfullnamebyid(112l));

   system.out.println( "----------------------------------" );

}

6)测试结果

输出结果如下。

execute queryfullnamebyid method
第一次执行查询:zhangsanfeng
----------------------------------
第二次执行查询:zhangsanfeng
----------------------------------
execute deletebyid method
----------------------------------
execute queryfullnamebyid method
清除缓存后查询:zhangsanfeng
----------------------------------
execute modifyfullnamebyid method
zhangjunbao
----------------------------------
修改数据后查询:zhangjunbao
----------------------------------
execute queryfullnamebyid method
第一次执行查询:zhangsanfeng
----------------------------------
execute queryfullnamebyid method
第二次执行查询:zhangsanfeng
----------------------------------

从结果可以看到,使用缓存后,第二次查询没有执行查询方法体,直接返回了缓存中的数据;清除缓存后,再次查询就执行了查询方法体;修改数据后,相应的缓存数据也被修改了;不符合缓存条件的数据没有被缓存。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://HdhCmsTestjianshu测试数据/p/0dbe0a616898

查看更多关于使用Spring Data Redis实现数据缓存的方法的详细内容...

  阅读:16次