有关redis的介绍我就不说了,可以参看我前几篇文章, redis快速入门
首先来看一下redis的应用场景
下面是我这个项目的的运行的场景截图
这是我们经常在各博客见到的顶和踩的画面,对于这种场景,我们用非关系型数据库来操作是非常不方便地,不光是查询不方便(写sql语句),而且在高并发的时候,可能会使系统假死,所以redis就派上用场了,它属于非关系型数据库,它直接操作内存,非常快速。
下面直接看代码
首先看看所需的包
除了Spring和Struts2所需的包外 还需连接redis的包 这里是spring-data-redis
本项目是模拟用户实现顶和踩的功能
所以先创一个实体类User
package com.yc.beans; public class User { private int ding;//顶 private int cai;//踩 public int getCai() { return cai; } public void setCai(int cai) { this.cai = cai; } public int getDing() { return ding; } public void setDing(int ding) { this.ding = ding; } }
因为是spring+Struts2一起,所以要改web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" id="WebApp_9" version="2.4"> <!-- spring的配置文件的路径, --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext*.xml</param-value> </context-param> <!-- 配置spring的上下文临听器: 当应用程序一加载到服务器上时,就会调用这个 ContextLoaderListerner, 这个临听器会读取contextConfigLocation配置的spring配置文件,完成 spring容器的初始化. --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- struts2的前端过滤器 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
首先看一下客户端请求页面 index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <style> #head { font-family: cursive; font-size: 25px; color: orange; cursor: pointer; } #content {height =300px; font-family: cursive; font-size: 20px; } .ding { border: 1px solid blue; height: 60px; width: 70px; margin-left: 150px; padding-left10px; float: left; background: #FFF; } .ding img { display: inline-block; margin-top: 15px; margin-left: 10px; cursor: pointer; } .sding { float: left; margin-top: 16px; font-family: cursive; text-decoration: underline; } </style> <script src="js/jquery-1.11.3.js"></script> <script type="text/javascript"> //当这个页面加载完毕 则给 loginbtn绑定单击事件 $(function() { $.ajax({ type : "POST", url : "User_Find.action", dataType : 'JSON', success : function(data) { if (data.code == 1) { $("#num").text(data.obj.ding); $("#numcai").text(data.obj.cai); } else { alert(data); } } }); }); function addDing() { $.ajax({ type : "POST", url : "User_Ding.action", dataType : 'JSON', success : function(data) { if (data.code == 1) { $("#num").text(data.obj.ding) } else { alert(data); } } }); } function addCai(){ $.ajax({ type:"POST", url:"User_Cai.action", dataType:'JSON', success: function(data){ if(data.code==1){ $("#numcai").text(data.obj.cai); }else{ alert(data); } } }); } </script> </head> <body> <center> <div style="background: #0F0; height: 400px; width: 600px;"> <table CELLPADDING="0" border="1px" bordercolor="yellow" height="400px" width="600px"> <tr> <th id="head" align="left" height="50px" colspan="3">年度最热门博客</th> </tr> <tr id="content"> <td height="200" colspan="3">都说飞得越高,摔得越惨,但是我想看看我到底会摔得有多惨,落地了,只要没死,那么爬起来,每走一步都是向上! <br> </br> 时间并不会真的帮我们解决什么问题,它只是把原来怎么也想不通的问题,变得不再重要了。 </td> </tr> <tr> <td colspan="3"> <div class="ding"> <span class="sding">顶</span><img alt="tup" src="images/ding.gif" onclick="addDing()"><span id="num"></span> </div> <div class="ding"> <span class="sding">踩</span><img alt="tup" src="images/cai.gif" onclick="addCai()"><span id="numcai"></span> </div> </td> </tr> </table> </div> </center> </body> </html>
它发请求到UserAction, 请后台传递数据用JSON
所以再看看Struts.xml,
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 关闭动态方法调用 actionid!方法名.action --> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <!-- 启用开发模式 --> <constant name="struts.devMode" value="true" /> <!-- action的创建由spring来完成,而不由struts完成. --> <constant name="struts.objectFactory" value="spring" /> <package name="default" namespace="/" extends="json-default"> <action name="User_*" class="userAction" method="{1}"> <result name="success" type="json"> <param name="root"> jsonModel </param> </result> </action> </package> </struts>
再看UserAction之前,我们先看看一个帮助类
package com.yc.utils; import java.io.Serializable; public class JsonModel implements Serializable { /** * */ private static final long serialVersionUID = -7830500053112045585L; private Integer code; private String message; private Object obj; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } }
通过这个帮助类将数据转为JSON数据发给前台,具体看后面的代码
我们连接redis服务都是通过spring来完成的,所以我们看看spring 的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 启用注解解析器 --> <context:annotation-config /> <!-- 因为采用了混合解析方式( 有一部分配置在xml中,有一部分在java类中,所以要让spring的注解解析器去扫描包 --> <context:component-scan base-package="com.yc" /> <!-- 启用aspectj的注解方式的代理 --> <aop:aspectj-autoproxy /> <!-- 创建redis工厂 --> <bean id="jedisFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="localhost" /> <property name="port" value="6379" /> <property name="usePool" value="true" /> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisFactory" /> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> </bean> <bean id="springRedisClientImpl" class="com.yc.redis.spring.clients.SpringRedisClientImpl"> <property name="redisTemplate" ref="redisTemplate" /> </bean> </beans>
这样我们就可以来操作redis数据库了
再看看操作redis的帮助类,,它里面封装了我们一些基本的操作redis的方法
package com.yc.redis.spring.clients; import java.util.Set; public interface SpringRedisClient { /** * 存 * @param key * @param value */ public void setKey( String key, String value); /** * 根据键取值 * @param key * @return */ public Object getKey( String key); /** * 自增 * @param key */ public void incr( String key); /** * 在上一个元素的左边存 * @param key * @param value */ public void lPush( String key, String value); /** * 查看是否有这个键 * @param key * @return */ public boolean checkKey( String key); /** * 按键取 * @param key * @return */ public Object lIndex( String key); /** * 求长度 * @param key * @return */ public Long lLength( String key); /** * 从上一个元素的左边取值 * @param key * @return */ public String lPop( String key); /** * 按正则表达式匹配的键取值 * @param pattern * @return */ public Set<String> getKeys( String pattern); }
看看它的实现,里面通过spring注入了一个RedisTemplate,这在spring的配置文件里面已经注册了,这样就可以访问redis数据库了
package com.yc.redis.spring.clients; import java.io.Serializable; import java.util.Set; import org.springframework.data.redis.core.RedisTemplate; public class SpringRedisClientImpl implements SpringRedisClient,Serializable { /** * */ private static final long serialVersionUID = -4213002642362857373L; private RedisTemplate redisTemplate; public void setRedisTemplate(RedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } @Override public void setKey(String key, String value) { this.redisTemplate.opsForValue().set(key, value); } @Override public Object getKey(String key) { return this.redisTemplate.opsForValue().get(key); } @Override public void incr(String key) { this.redisTemplate.opsForValue().increment(key, 1); } @Override public void lPush(String key, String value) { this.redisTemplate.opsForList().leftPush(key, value); } @Override public boolean checkKey(String key) { return this.redisTemplate.hasKey(key); } @Override public Object lIndex(String key) { return this.redisTemplate.opsForList().index(key, 0); } @Override public Long lLength(String key) { return this.redisTemplate.opsForList().size(key); } @Override public String lPop(String key) { return (String) this.redisTemplate.opsForList().leftPop(key); } @Override public Set<String> getKeys(String pattern) { return this.redisTemplate.keys(pattern); } }
首先看看业务层,定义了三个接口方法,分别是顶,踩和刷新时查找顶和踩的数量
package com.yc.service; public interface UserService { public String Ding(); public String Cai() ; public String[] Find() ; }
下面看它的实现类
package com.yc.service.impl; import java.io.Serializable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.yc.redis.spring.clients.SpringRedisClientImpl; import com.yc.service.UserService; import redis.clients.jedis.Jedis; @Service("userServiceImpl") public class UserServiceImpl implements UserService ,Serializable { /** * */ private static final long serialVersionUID = 1304876423677235894L; @Autowired private SpringRedisClientImpl springRedisClientImpl;//通过spring注入 @Override public String Ding() { springRedisClientImpl.incr("User:ding"); String num=(String) springRedisClientImpl.getKey("User:ding"); return num; } public SpringRedisClientImpl getSpringRedisClientImpl() { return springRedisClientImpl; } public void setSpringRedisClientImpl(SpringRedisClientImpl springRedisClientImpl) { this.springRedisClientImpl = springRedisClientImpl; } @Override public String Cai() { springRedisClientImpl.incr("User:cai"); String num=(String) springRedisClientImpl.getKey("User:cai"); return num; } @Override public String[] Find() { String s[]=new String[2]; s[0]= (String) springRedisClientImpl.getKey("User:ding"); s[1]= (String) springRedisClientImpl.getKey("User:cai"); return s; } }
最后大家可以看UserAction类了
package com.yc.web.actions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionSupport; import com.yc.beans.User; import com.yc.service.UserService; import com.yc.service.impl.UserServiceImpl; import com.yc.utils.JsonModel; import com.yc.utils.JsonModel; import redis.clients.jedis.Jedis; @Controller("userAction") public class UserAction extends ActionSupport { /** * */ private static final long serialVersionUID = 1825223373127715747L; private JsonModel jsonModel = new JsonModel(); @Autowired private UserServiceImpl userServiceImpl; public JsonModel getJsonModel() { return jsonModel; } public void setJsonModel(JsonModel jsonModel) { this.jsonModel = jsonModel; } public String Ding() { User user = new User(); String num = userServiceImpl.Ding(); if (num != null && !"".equals(num)) { user.setDing(Integer.parseInt(num)); jsonModel.setCode(1); jsonModel.setObj(user); } return SUCCESS; } public String Cai() { User user = new User(); String num = userServiceImpl.Cai(); if (num != null && !"".equals(num)) { user.setCai(Integer.parseInt(num)); jsonModel.setCode(1); jsonModel.setObj(user); } return SUCCESS; } public String Find() { User user = new User(); System.out.println(userServiceImpl); String num[] = userServiceImpl.Find(); user.setDing(Integer.parseInt(num[0])); user.setCai(Integer.parseInt(num[1])); jsonModel.setCode(1); jsonModel.setObj(user); return SUCCESS; } }
这样所有的代码就都已经分析完了,搭建好redis服务后,就可以跑了,
整个项目的代码有需要的朋友可以下载
http://download.csdn.net/detail/tanggao1314/9487851