关于springredis框架的使用,网上有很多很多例子。但是在我最近的使用中,发现这些教程都是入门教程,包括很多使用方法,与springredis丰富的API有很大的不同。真是浪费了这么优秀的框架。spring-data-redis是spring-data模块中redis的支撑部分,简称“SDR”,基于jedisclientAPI提供高度封装,与spring容器集成。其实jedis客户端足够简洁轻量级,但是spring-data-redis有“设计过度”之嫌。jedis客户端在编程和实现上存在以下不足:1)连接管理缺乏自动化,connection-pool的设计缺乏必要的容器支持。2)数据操作需要注意“序列化”/“反序列化”,因为jedis客户端API接受的数据类型是string和byte,需要额外支持结构化数据(json、xml、pojo)操作。3)交易操作纯硬编码4)pub/sub功能缺乏必要的设计模式支持,需要开发者过多关注。一、Redis使用场景Redis是一个开源的、日志型、Key-Value数据库,用ANSIC语言编写,支持网络,可以是基于内存的,也可以是持久化的,提供多种语言的API。众所周知,在日常应用中,最容易出现数据库瓶颈。由于数据量大,查询频繁,磁盘IO性能受限,导致项目性能越来越低。这时候基于内存的缓存框架可以解决我们很多问题。如Memcache、Redis等。将一些经常使用的数据放入缓存中读取,大大减轻了数据库的负担。改进了系统性能。其实hibernate和Mybatis的二级缓存也是一样的。利用内存的高速读写速度解决硬盘的瓶颈。2.配置使用redis项目的整体结构如下:在applicationContext-dao.xml中配置如下:database.properties配置文件如下:redis.maxIdle=10redis.maxActive=20redis.maxWait=10000redis.testOnBorrow=trueredis.host=192.168.1.76redis.port=6379redis.pass=password1spring-data-redis提供了多种序列化策略,对于使用jedis的开发者来说真的很有帮助非常方便的sdr提供了4个内置的序列化器:JdkSerializationRedisSerializer:利用JDK的序列化手段(可序列化接口,ObjectInputStream,ObjectOutputStream),数据以字节流的形式存储,POJO对象访问场景,利用JDK自带的序列化机制,将pojo类进行序列化操作通过ObjectInputStream/ObjectOutputStream,最后redis-server会存储字节序列,这是目前最常用的序列化策略。StringRedisSerializer:字符串编码,数据存储在string中,Key或value为字符串场景,将数据的字节序列按照指定的charset编码成string,即"newString(bytes,charset)"和"string.getBytes(charset)”直接封装。是最轻量级和最有效的策略。JacksonJsonRedisSerializer:以json格式存储,jackson-json工具提供javabean和json之间的转换能力。可以将pojo实例序列化成json格式存储到redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化的时候需要显式指定Class类型,所以这种策略封装起来稍微复杂一些。【需要jackson-mapper-asl工具支持】OxmSerializer:xml格式存储,提供javabean与xml的转换能力,目前可用的三方支持包括jaxb、apache-xmlbeans;存储在redis中的数据将是一个xml工具。但是,使用这种策略,编程会有些难度和效率;不推荐。【需要spring-oxm模块的支持】其中JdkSerializationRedisSerializer和StringRedisSerializer是最基本的序列化策略,其中“JacksonJsonRedisSerializer”和“OxmSerializer”是基于stirng存储的,所以比较“高级”的序列化(最后使用string解析和构建java对象)。对于“序列化和序列化”,JdkSerializationRedisSerializer和StringRedisSerializer是最基本的策略。原则上我们可以存储任何格式的数据供应用程序访问和分析(应用程序包括app、hadoop等其他工具),但仍然不建议在设计时直接使用“JacksonJsonRedisSerializer”和“OxmSerializer”,因为是否是json还是xml,还是String。如果你的数据需要第三方工具解析,那么数据应该使用StringRedisSerializer,而不是JdkSerializationRedisSerializer。RedisTemplate需要声明4种序列化器,默认为“JdkSerializationRedisSerializer”:1)keySerializer:对于普通的K-V操作,key采用的序列化策略2)valueSerializer:value采用的序列化策略3)hashKeySerializer:hash中datastructure,Hash-keyserializationstrategy4)hashValueSerializer:hash-value序列化策略无论如何,推荐key/hashKey使用StringRedisSerializer。spring-data-redis为jedis提供了以下功能:1.自动连接池管理,提供高度封装的“RedisTemplate”类2.对jedisclients中大量的API进行分类封装,封装与operation同类型的操作interfaceValueOperations:简单的K-V操作SetOperations:set类型的数据操作ZSetOperations:zset类型的数据操作HashOperations:map类型的数据操作ListOperations:list类型的数据操作operationAPI可以通过bound封装指定的key,然后进行一系列的操作无需再次“显式”指定Key,即BoundKeyOperations:BoundValueOperationsBoundSetOperationsBoundListOperationsBoundSetOperationsBoundHashOperations3。RedisTemplate使用该类作为模板类,提供了很多快速使用redis的API,不需要自己维护连接和事务。最初,我创建的BaseRedisDao就是继承自这个类。继承的好处是在我的每一个Dao中,我都可以自由控制serializer,自由控制是否需要事务。这个我先不用理解,按照我现在的配置方式就行了。模板提供了valueOperation、HashOperation、ListOperation、SetOperation等一系列操作,用于操作不同数据类型的Redis。而且RedisTemplate还提供了对应的*OperationsEditor,用于直接通过RedisTemplate注入对应的Operation。核心代码:packagecom.npf.dao.impl;importjava.util.ArrayList;importjava.util.List;importjava.util.Map;importjava.util.Map.Entry;importjavax.annotation.Resource;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.core.HashOperations;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.stereotype.Repository;importcom.npf.dao.StudentDao;importcom.npf.model.Student;@RepositorypublicclassStudentDaoImplimplementsStudentDao{@AutowiredprivateRedisTemplateredisTemplate;@Resource(name="redisTemplate")privateHashOperationsopsForHash;publicstaticfinalStringSTUDENT="student";@Overridepublicvoidsave(Studentstudent){opsForHash.put(学生,student.getId(),student);}@OverridepublicStudentfind(Stringid){Studentstudent=opsForHash.get(STUDENT,id);returnstudent;}@Overridepublicvoiddelete(Stringid){opsForHash.delete(STUDENT,id);}@Overridepublicvoidupdate(Studentstudent){opsForHash.put(STUDENT,student.getId(),student);}@OverridepublicListfindAll(){Mapentries=opsForHash.entries(STUDENT);ListstuList=newArrayList();for(Entryentry:entries.entrySet()){stuList.add(entry.getValue());}returnstuList;}}控制层代码如下:packagecom.npf.控制器;importjava.util.List;importjava.util.UUID;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind。annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestParam;importcom.npf.model.Student;importcom.npf.service.StudentService;@ControllerpublicclassStudentController{@AutowiredprivateStudentServicestudentService;@RequestMapping("/student/save")publicStringsaveStudent(Studentstudent){Stringid=UUID.randomUUID().toString();System.out.println(id);student.setId(id);studentService.save(student);return"redirect:/student/find/all";}@RequestMapping("/student/update")publicStringupdateStudent(Studentstudent){studentService.update(student);return"redirect:/student/find/all";}@RequestMapping("/student/to/save/form")publicStringtoSaveStudentForm(){return"save";}@RequestMapping("/student/delete")publicStringdeleteStudent(@RequestParam("id")Stringid){studentService.delete(id);return"redirect:/student/find/all";}@RequestMapping("/student/to/更新/形式”)publicStringtoUpdateStudentForm(@RequestParam(“id”)Stringid,Modelmodel){Studentstu=studentService.find(id);model.addAttribute(“stu”,stu);返回“更新”;}@RequestMapping(“/student/find/all")publicStringfindStudents(Modelmodel){ListstuList=studentService.findAll();model.addAttribute("stuList",stuList);返回"列表";}}