好久不写写博客了,最近不是很忙,就给自己充充电,研究研究redis,最近一些项目也有类似的问题出现,用户频繁访问数据库,并且用户需要的很多数据并不频繁更行,没必要每次都去查询数据库,否则数据库亚历山大啊,尤其是手机平板客户端的一些数据需要频繁交互却又不会频繁更新,对于数据库的鸭梨很大,于是就想着把那些常用的数据放到缓存里,对于缓存框架目前我所知道的只有memcached和redis,redis,一下是个人总结的关于两者之间的区别
1.memcached把数据全部存储在内存,断电后数据就真挂了,数据全部丢失,然而redis会把部分数据转存到硬盘,而且转存方式也是可配置的,也就是redis持久化的可配置更加保障了数据的安全性,即使断电了针对redis的持久化数据并不会安全丢失,再次启动时可以将持久化的数据再一次载入使用,数据丢失的代价不是很大
2.redis所支持的数据类型远比memcached要多的多吧
以上两点我想是他们最主要的区别了吧,小弟才疏学浅,若有不对之处请不吝赐教
下面开始配置和整合
1.对于springMVC+jdbc的配置主要在于三个文件applicationContext.xml springmvc-servlet.xml web.xml
@1.首先配置applicationContext.xml。无非就是数据源、事务、以及jdbc模板的配置吧
数据源的配置,此处用了连接池c3p0,引入数据源属性文件
<context:property-placeholder location="classpath:sysconf/*.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${mysql.driverclass}"></property>
<property name="jdbcUrl" value="${mysql.jdbcurl}"></property>
<property name="user" value="${mysql.user}"></property>
<property name="password" value="${mysql.password}"></property>
<property name="acquireIncrement" value="5"></property>
<property name="initialPoolSize" value="10"></property>
<property name="minPoolSize" value="5"></property>
<property name="maxPoolSize" value="20"></property>
<property name="maxIdleTime" value="300"></property>
<property name="idleConnectionTestPeriod" value="60"></property>
<property name="maxStatements" value="20"></property>
</bean>
jdbc模板的配置
<bean id="jdbcTemplate" name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
事务的配置 先配置一个jdbc的事务管理器,然后声明一个事务的切面,也就是事务生效的切面,然后配置对切面下那些方法需要事务拦截,配置均可用通配符如下
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 声明式事务管理 -->
<aop:config>
<aop:advisor pointcut="execution(* com.company.service.impl.*ServiceImpl.*(..))" advice-ref="myAdvice"/>
</aop:config>
<tx:advice id="myAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="edit*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true" rollback-for="com.aokunsang.util.DaoException"/>
</tx:attributes>
</tx:advice>
<!-- 自动扫描组件,需要把controller去掉,否则影响事务管理 -->
<context:component-scan base-package="com.company">
<context:exclude-filter type="regex" expression="com.company.web.*"/>
</context:component-scan>
@2再看springmvc-servlet.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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 启动扫描所有的controller -->
<context:component-scan base-package="com.company.web"/>
<context:component-scan base-package="com.system.redis"/>
<!-- 主要作用于@Controller,激活该模式
下面是一种简写形式,完全可以手动配置替代这种简写形式;
它会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,
是spring MVC为@Controllers分发请求所必须的
-->
<mvc:annotation-driven/>
<!-- 这里拦截器还有一种配置方法【针对路径进行配置】 推荐使用这个,方便直观-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/com/*"/>
<bean class="com.company.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- 全局配置
<mvc:interceptors>
<bean class="com.company.interceptor.MyInterceptor"></bean>
</mvc:interceptors>
-->
<mvc:resources location="/company/source/**" mapping="/company/source/**"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
@3web.xml的配置 此处配置的是一些编码、spring的控制器、以及一些文件的加载配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>springmvc.root</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/sysconf/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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:/sysconf/springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>/company/main/main.jsp</welcome-file>
</welcome-file-list>
</web-app>
以下是导入的jar包
下面看spring-data-redis配置 特别的简单 直接在applicationContext.xml中配置如下即可
<bean id='jedisConnectionFactory' class='org.springframework.data.redis.connection.jedis.JedisConnectionFactory' p:host-name='${redis.host}' p:port='${redis.port}' p:use-pool='${redis.usepool}'/> <bean id='redisTemplate' class='org.springframework.data.redis.core.RedisTemplate' p:connection-factory-ref='jedisConnectionFactory'> <!-- 使用string主要是key 在redis端用命令好读 不然默认的序列化没办法读 --> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> </bean>
看上去和那个jdbcTemplete特别像吧?
下面做两个例子来看看
Controller:
@Controller @RequestMapping("/company/companyModule.do") public class CModuleController {
@RequestMapping(params="method=test1") public void test1(){ CModuleInfo info=new CModuleInfo(); info.setId(1000); info.setModuleCode("1000Code"); info.setModuleIndex("1000"); info.setModuleName("缓存测试"); info.setModulePreCode("#"); info.setModuleStatus("1"); info.setModuleType("1"); info.setModuleUrl("====="); this.redisService.addCommentInfoCache(info); } @RequestMapping(params="method=test2") public void test2(){ List<CModuleInfo> list=this.redisService.getCommentInfoCache("1000Code"); for (CModuleInfo moduleInfo : list) { System.out.println(moduleInfo.getModuleCode()+"====="+moduleInfo.getModuleName()); } }
}
bean:
public class CModuleInfo implements Serializable{ private int id; private String moduleCode; private String moduleName; private String modulePreCode; private String moduleUrl; private String moduleStatus; private String moduleIndex; private String moduleType; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getModuleCode() { return moduleCode; } public void setModuleCode(String moduleCode) { this.moduleCode = moduleCode; } public String getModuleName() { return moduleName; } public void setModuleName(String moduleName) { this.moduleName = moduleName; } public String getModulePreCode() { return modulePreCode; } public void setModulePreCode(String modulePreCode) { this.modulePreCode = modulePreCode; } public String getModuleUrl() { return moduleUrl; } public void setModuleUrl(String moduleUrl) { this.moduleUrl = moduleUrl; } public String getModuleStatus() { return moduleStatus; } public void setModuleStatus(String moduleStatus) { this.moduleStatus = moduleStatus; } public String getModuleIndex() { return moduleIndex; } public void setModuleIndex(String moduleIndex) { this.moduleIndex = moduleIndex; } public String getModuleType() { return moduleType; } public void setModuleType(String moduleType) { this.moduleType = moduleType; } public CModuleInfo(int id, String moduleCode, String moduleName, String modulePreCode, String moduleUrl, String moduleStatus, String moduleIndex, String moduleType) { super(); this.id = id; this.moduleCode = moduleCode; this.moduleName = moduleName; this.modulePreCode = modulePreCode; this.moduleUrl = moduleUrl; this.moduleStatus = moduleStatus; this.moduleIndex = moduleIndex; this.moduleType = moduleType; } public CModuleInfo() { super(); // TODO Auto-generated constructor stub } }
redis服务接口:
public interface RedisService { /** * 添加缓存信息 * @param commentInfo */ public void addCommentInfoCache(CModuleInfo commentInfo); public List<CModuleInfo> getCommentInfoCache(String subjectCommentID); }
redis接口实现类:
@Service("redisService") public class RedisServiceImpl implements RedisService { @Autowired private RedisTemplate<Serializable, Serializable> redisTemplate; private String commentInfoKey="commentInfo"; @Resource(name="redisTemplate") private ListOperations<String,CModuleInfo> commentInfoHash; public void addCommentInfoCache(CModuleInfo commentInfo){ commentInfoHash.leftPush(commentInfoKey+"_"+commentInfo.getModuleCode(), commentInfo); commentInfoHash.trim(commentInfoKey+"_"+commentInfo.getModuleCode(), 0, 1); } public List<CModuleInfo> getCommentInfoCache(String subjectCommentID){ List<CModuleInfo> list= commentInfoHash.range(commentInfoKey+"_"+subjectCommentID, 0, -1);//获取所有 if(list==null) list= new ArrayList<CModuleInfo>(); return list; } }
到这里还应该干一件事情,就是在自己的机子上安装redis服务,并且开启,这个直接去网上下载最新版2.6的redis,解压后,进入解压目录,运行redis-server.exe redis.conf就好了
在这个例子里面 test1是将实体类存到了redis,test2是将存进去的redis取出来 测试是成功的!简单的例子大家可以看看
再抽时间研究研究redis集群,小有成果的话与大家分享