redis和spring集成(注解实现,方便,快捷)

    xiaoxiao2021-12-14  21

    前言:

             spring和redis集成有很多方式,看到网上很多都是使用redistemplate自己去做redis 的一些操作,但是对于我们开发来说,肯定是使用越方便越好,于是乎就有了spring的对redis或者memcahe这些换成框架的封装,只需要引入spring的spring-data-redis的jar。 

             好了,废话不多说,我们开始上代码。

    工程目录结构

            我们先预览一下这个项目的工程目录结构先:

    启动redis

            还没安装的redis 的同学可以自己去安装redis,我自己是在window上安装的,其实也不是安装,解压一下就可以使用了,不过需要注意的是它的启动方式,直接点击redis-server启动会直接闪退的,正确的启动方式使用命令【redis-server.exe  redis.windows.conf】,详细请参考:Windows 64位下安装Redis详细教程

    创建数据库

    配置pom文件

    pom文件就没什么好说的了,直接贴配置给大家吧

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ylink.com</groupId> <artifactId>spring-redis-test</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <build /> <properties> <spring.version>4.2.6.RELEASE</spring.version> <slf4j.version>1.6.4</slf4j.version> <logback.version>1.0.0</logback.version> <junit.version>4.9</junit.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.1.1</version> </dependency> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- memcached <dependency> <groupId>com.whalin</groupId> <artifactId>Memcached-Java-Client</artifactId> <version>3.0.1</version> </dependency> --> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.2</version> </dependency> <!-- log --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.2.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.31</version> </dependency> <dependency> <groupId>com.jolbox</groupId> <artifactId>bonecp</artifactId> <version>0.7.1.RELEASE</version> </dependency> </dependencies> </project>

    配置spring文件

    下面是spring-mvc.xml的配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd"> <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 --> <context:component-scan base-package="com.cn" /> <!-- 引入同文件夹下的redis属性配置文件 --> <import resource="spring-redis.xml"/> <import resource="spring-datasource-bonecp.xml"/> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.cn.dao"/> </bean> </beans> 下面是spring-redis.xml的配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd"> <context:property-placeholder location="classpath:redis-config.properties" /> <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 --> <cache:annotation-driven cache-manager="cacheManager" /> <!-- redis 相关配置 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <bean id="JedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="JedisConnectionFactory" /> </bean> <!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <!-- 这里可以配置多个redis --> <!-- <bean class="com.cn.util.RedisCache"> <property name="redisTemplate" ref="redisTemplate" /> <property name="name" value="default"/> </bean> --> <bean class="com.cn.util.RedisCache"> <property name="redisTemplate" ref="redisTemplate" /> <property name="name" value="common"/> <!-- common名称要在类或方法的注解中使用 --> </bean> </set> </property> </bean> </beans> 下面是spring-datasource-bonecp.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> <!--用于连接boneCp数据源 --> <bean id="commonDataSourceConfig" class="com.jolbox.bonecp.BoneCPDataSource" abstract="true" destroy-method="close"> <!-- 每个分区最大的连接数 --> <property name="maxConnectionsPerPartition" value="100" /> <!-- 每个分区最小的连接数 --> <property name="minConnectionsPerPartition" value="10" /> <!-- 分区数 ,默认值2,最小1,推荐3-4,视应用而定--> <property name="partitionCount" value="3" /> <!-- 每次去拿数据库连接的时候一次性要拿几个,默认值:2 --> <property name="acquireIncrement" value="2" /> <!-- 测试连接有效性的间隔时间,单位分钟 <property name="idleConnectionTestPeriod" value="40" />--> <!-- 空闲存活时间 分钟 <property name="idleMaxAge" value="10"/>--> <!-- 连接超时时间 毫秒--> <property name="connectionTimeout" value="10000"/> </bean> <!-- 数据源配置 --> <bean id="dataSource" parent="commonDataSourceConfig"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/test" /> <property name="username" value="root"/> <property name="password" value=""/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:cfg.xml"/> <property name="dataSource" ref="dataSource"/> </bean> </beans>

    编写java类

    直接上service,其他的大家可以自己去我上传的源码去下载查看,至于对spring的缓存的注解不太了解怎么使用的,可以参考下这边博客园博主写的博文:Spring Cache使用详解

    package com.cn.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.cn.bean.User; import com.cn.dao.UserDao; /** * @类名称: UserServiceImpl * @类描述: * @创建人: 1603254 * @创建时间: 2016-12-2 上午11:10:33 * * @修改人: 1603254 * @操作时间: 2016-12-2 上午11:10:33 * @操作原因: * */ @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Cacheable(value="common",key="'id_'+#id") public User selectByPrimaryKey(Integer id) { System.out.println("======================"); System.out.println("======================"); System.out.println("======================"); return userDao.selectByPrimaryKey(id); } @CachePut(value="common",key="#user.getUserName()") public void insertSelective(User user) { // userDao.insertSelective(user); System.out.println("########################"); System.out.println("########################"); System.out.println("########################"); } @CacheEvict(value="common",key="'id_'+#id") public void deleteByPrimaryKey(Integer id) { // userDao.deleteByPrimaryKey(id); System.out.println("******************************"); System.out.println("******************************"); System.out.println("******************************"); } }

    编写mybatis配置文件

    下面是cfg.xml配置文件

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- mapping 文件路径配置 --> <mappers> <mapper resource="mapper/UserMapper.xml" /> </mappers> <!-- <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <property name="dialect" value="oracle"/> 该参数默认为false 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 和startPage中的pageNum效果一样 <property name="offsetAsPageNum" value="true"/> 该参数默认为false 设置为true时,使用RowBounds分页会进行count查询 <property name="rowBoundsWithCount" value="true"/> 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 (相当于没有执行分页查询,但是返回结果仍然是Page类型) <property name="pageSizeZero" value="true"/> 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 <property name="reasonable" value="true"/> 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 <property name="params" value="pageNum=start;pageSize=limit;pageSizeZero=zero;reasonable=heli;count=contsql"/> </plugin> </plugins> --> </configuration>

    下面是UserMapper.xml配置

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.cn.dao.UserDao" > <resultMap id="resultMap" type="com.cn.bean.User" > <result column="id" property="id" jdbcType="CHAR" /> <result column="name" property="name" jdbcType="CHAR" /> </resultMap> <!--添加--> <insert id="insertSelective" parameterType="com.cn.bean.User"> insert into user(id,name) values(#{id,jdbcType=CHAR},#{name,jdbcType=VARCHAR}) </insert> <!--查询--> <select id="selectByPrimaryKey" resultMap="resultMap"> select * from user where id=#{id} </select> <!--删除--> <select id="deleteByPrimaryKey" resultMap="resultMap"> delete from user where id=#{id} </select> </mapper>

    配置web.xml

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app id="WebApp_ID"> <display-name>spring-redis-test</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> </web-app>

    编写测试用例

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import com.cn.bean.User; import com.cn.service.UserService; @ContextConfiguration(locations="classpath:spring-mvc.xml") public class Test extends AbstractJUnit4SpringContextTests { @Autowired private UserService userService; @org.junit.Test public void add(){ User user=new User(); user.setName("wen"); user.setId("1"); userService.insertSelective(user); } @org.junit.Test public void query(){ User user=userService.selectByPrimaryKey(1); System.out.println(user.toString()); } } 上面我是这样执行校验的:  1)先把数据库的操作打开,插入一条数据,插入的时候,数据库会插入一条数据,redis里面也会有一条数据。 2)然后执行查询的测试用例,第一次查询会将数据库的数据查到redis,然后第二次直接从redis里面去查询,你可以把数据库的数据删掉,结果显示是可以从redis里面查询出来 上面代码我都测试过,无措执行,部分缺少的java类,可以直接下载demo查看,有问题大家可以提出来讨论一下,谢谢~

    源代码下载

    下载地址是:spring集成redis源码+表结构

    其实说实话,用起来还是蛮简单的,而且方便,快捷,真正想要了解深入一点的话,还是建议有时间去看看源代码。

    后面大家评论说RedisCache类没写给出来,下面给一下(链接里面的demo 有Override 注解删除就可以使用了):

    package com.cn.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.springframework.cache.Cache; import org.springframework.cache.support.SimpleValueWrapper; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; public class RedisCache implements Cache{ private RedisTemplate<String, Object> redisTemplate; private String name; public RedisTemplate<String, Object> getRedisTemplate() { return redisTemplate; } public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } public void setName(String name) { this.name = name; } public String getName() { // TODO Auto-generated method stub return this.name; } public Object getNativeCache() { // TODO Auto-generated method stub return this.redisTemplate; } public ValueWrapper get(Object key) { // TODO Auto-generated method stub System.out.println("get key"); final String keyf = key.toString(); Object object = null; object = redisTemplate.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = keyf.getBytes(); byte[] value = connection.get(key); if (value == null) { return null; } return toObject(value); } }); return (object != null ? new SimpleValueWrapper(object) : null); } public void put(Object key, Object value) { // TODO Auto-generated method stub System.out.println("put key"); final String keyf = key.toString(); final Object valuef = value; final long liveTime = 86400; redisTemplate.execute(new RedisCallback<Long>() { public Long doInRedis(RedisConnection connection) throws DataAccessException { byte[] keyb = keyf.getBytes(); byte[] valueb = toByteArray(valuef); connection.set(keyb, valueb); if (liveTime > 0) { connection.expire(keyb, liveTime); } return 1L; } }); } private byte[] toByteArray(Object obj) { byte[] bytes = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(obj); oos.flush(); bytes = bos.toByteArray(); oos.close(); bos.close(); }catch (IOException ex) { ex.printStackTrace(); } return bytes; } private Object toObject(byte[] bytes) { Object obj = null; try { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); obj = ois.readObject(); ois.close(); bis.close(); } catch (IOException ex) { ex.printStackTrace(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } return obj; } public void evict(Object key) { // TODO Auto-generated method stub System.out.println("del key"); final String keyf = key.toString(); redisTemplate.execute(new RedisCallback<Long>() { public Long doInRedis(RedisConnection connection) throws DataAccessException { return connection.del(keyf.getBytes()); } }); } public void clear() { // TODO Auto-generated method stub System.out.println("clear key"); redisTemplate.execute(new RedisCallback<String>() { public String doInRedis(RedisConnection connection) throws DataAccessException { connection.flushDb(); return "ok"; } }); } public <T> T get(Object key, Class<T> type) { // TODO Auto-generated method stub return null; } public ValueWrapper putIfAbsent(Object key, Object value) { // TODO Auto-generated method stub return null; } }

    转载请注明原文地址: https://ju.6miu.com/read-962325.html

    最新回复(0)