首先Maven导入
<!--spring整合redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
<!-- redis缓存 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.2</version>
</dependency>
再配置spring.xml文件,我这是已经整合好Spring,Mybatis和struts2的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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
<context:component-scan base-package="com.microblog"></context:component-scan>
<tx:annotation-driven transaction-manager="txManager" />
<!-- 配置数据库连接脚本 -->
<bean id="a"
class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="locations" value="classpath:jdbc.properties"></property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${mysql.driverName}"></property>
<property name="url" value="${mysql.url}"></property>
<property name="username" value="${mysql.uname}"></property>
<property name="password" value="${mysql.pwd}"></property>
</bean>
<!-- 事物触发器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.microblog.bean"></property>
<property name="mapperLocations" value="classpath:com/microblog/dao/mapper/*.xml" ></property>
<property name="configurationProperties">
<props>
<prop key="logImpl">LOG4J</prop>
</props>
</property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory"></constructor-arg>
</bean>
<!-- 创建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>
</beans>
没整合的也可只需加入创建redis工厂部分即可。如果用的联接池则也不需要配置redis工厂
DAO层接口加入一些redis常用方法
//redis start
/**
* 存
* @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
*/
public void decr( 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);
//redis end
DaoImpl实现类进行实现:
private RedisCache client = new RedisCache();
//redis数据库方法 start
@Override
public void setKey(String key, String value) {
this.client.set(key, value);
}
@Override
public Object getKey(String key) {
if(this.client.get(key)==null){
return null;
}
return this.client.get(key);
}
@Override
public void incr(String key) {
this.client.increment(key);
}
@Override
public void decr(String key) {
this.client.decr(key);
}
<pre name="code" class="java">//redis数据库方法 end
因为加入了联接池,所以一些自增自减的方法需要在RedisCache类中进行重写
package com.microblog.dao.mybatis.cache;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ibatis.cache.Cache;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import com.microblog.dao.redis.RedisPool;
public class RedisCache implements Cache {
/*
* 日志对象
*/
private static Logger logger = org.apache.log4j.Logger
.getLogger(RedisCache.class);
private String id;
private Jedis redisClient = createRedis();
// 用于同步的锁
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public RedisCache(String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instance requires an Id");
}
logger.debug("create an cache instance with id:" + id);
this.id = id;
}
public RedisCache() {
}
public String getId() {
return this.id;
}
// 将缓存中的数据删除
public void clear() {
logger.debug("clear redis cache");
this.redisClient.flushDB();
}
// 通过key到缓存redis中取值
public Object getObject(Object key) {
// 缓存穿透.
byte[] values = this.redisClient.get(SerializableUtil.serialize(key));
// System.out.println( values );
if (values == null) {
// this.putObject( SerializableUtil.serialize(key) , null);
return null;
}
Object obj = SerializableUtil.unSerialize(values);
logger.debug("get data:" + key + " from cache,result is:" + obj);
return obj;
}
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
public int getSize() {
Long size = this.redisClient.dbSize();
int s = Integer.valueOf(size + "");
return s;
}
public void putObject(Object key, Object value) {
byte[] keybyte = SerializableUtil.serialize(key);
byte[] valuebyte = SerializableUtil.serialize(value);
this.redisClient.set(keybyte, valuebyte);
}
public Object removeObject(Object key) {
byte[] keybyte = SerializableUtil.serialize(key);
return this.redisClient.expire(keybyte, 0);
}
/**
* TODO:jedis从联接池中取
*
* @return
*/
protected static Jedis createRedis() {
// TODO: 获取jedis实例 -> 这个地址要变
// Jedis jedis = new Jedis("192.168.137.128");
Jedis jedis = RedisPool.getPool().getResource();
return jedis;
}
public void set(String key, String value) {
this.redisClient.set(key, value);
}
public Object get(String key) {
return this.redisClient.get(key);
}
public void increment(String key) {
this.redisClient.incr(key);
}
public void decr(String key) {
this.redisClient.decr(key);
}
}
将对象序列化的类
package com.microblog.dao.mybatis.cache;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializableUtil {
/**
* 将对象序列化
*/
public static byte[] serialize(Object obj) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
byte[] bs = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
bs = baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bs;
}
public static Object unSerialize(byte[] bs) {
ByteArrayInputStream bais = null;
Object obj = null;
try {
bais = new ByteArrayInputStream(bs);
ObjectInputStream ois = new ObjectInputStream(bais);
obj = ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bais != null) {
try {
bais.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return obj;
}
}
然后是读取联接池的配置
package com.microblog.dao.redis;
import java.util.ResourceBundle;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* 以单例模式创建一个jedis的联接池
*/
public class RedisPool {
private static JedisPool pool;
public synchronized static JedisPool getPool() {
if( pool==null ){
new RedisPool();
}
return pool;
}
private RedisPool() {
ResourceBundle bundle = ResourceBundle.getBundle("redis");
if (bundle == null) {
throw new IllegalArgumentException(
"[redis.properties] is not found!");
}
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.valueOf(bundle
.getString("redis.pool.maxActive")));
config.setMaxIdle(Integer.valueOf(bundle
.getString("redis.pool.maxIdle")));
config.setMaxWaitMillis(Long.valueOf(bundle
.getString("redis.pool.maxWait")));
config.setTestOnBorrow(Boolean.valueOf(bundle
.getString("redis.pool.testOnBorrow")));
config.setTestOnReturn(Boolean.valueOf(bundle
.getString("redis.pool.testOnReturn")));
pool = new JedisPool(config, bundle.getString("redis.ip"),
Integer.valueOf(bundle.getString("redis.port")));
}
}
你需要一个redis.properties
redis.pool.maxActive=1024
redis.pool.maxIdle=200
redis.pool.maxWait=1000
redis.pool.testOnBorrow=true
redis.pool.testOnReturn=true
redis.ip=127.0.0.1
redis.password=123
redis.port=6379
再是业务层的实现
package com.microblog.biz.impl;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import com.microblog.bean.Blog;
import com.microblog.biz.BlogBiz;
import com.microblog.dao.BaseDao;
import com.microblog.web.model.BlogModel;
@Service
@Transactional(readOnly = true)
public class BlogBizImpl implements BlogBiz {
private BaseDao baseDao;
@Resource(name = "baseDaoImpl")
public void setBaseDao(BaseDao baseDao) {
this.baseDao = baseDao;
}
/**
* 发布微博存入数据库
*/
@SuppressWarnings("unchecked")
@Transactional(readOnly = false, isolation = Isolation.DEFAULT, rollbackForClassName = "java.lang.RuntimeException", propagation = Propagation.REQUIRED)
public void saveBlog(Blog blog) {
this.baseDao.save(blog, "saveBlog");
}
// 得到总的微博
public BlogModel findAllBlog(BlogModel hs) {
// 查询总记录数
int count = baseDao.getCount(Blog.class, "getBlogCount");
// 计算总页数
int total = count % hs.getSizePage() == 0 ? count / hs.getSizePage()
: count / hs.getSizePage() + 1;
hs.setTotal(total);
// 计算偏移量
int off = (hs.getCurrPage() - 1) * hs.getSizePage();
List<Blog> hh = this.baseDao.findList(Blog.class, null, "getBlog", off,
hs.getSizePage());
// 操作redis数据库 整合关系数据库
for (Blog blog : hh) {
Long id = blog.getId();
// 获取点赞数
String parse = (String) this.baseDao.getKey("user:parse" + id);
blog.setParse(parse);
// 获取转发数
String relay = (String) this.baseDao.getKey("user:relay" + id);
blog.setRelay(relay);
}
hs.setBlogs(hh);
return hs;
}
// 点赞(redis)
@Override
public String parse(Long id, int uid) {
// 当用户没有点赞,则点赞数+1,redis中用户字段+1;点了赞,则点赞数-1,redis中用户字段-1
if (id > 0 && uid > 0) {
if (this.baseDao.getKey(id + "user:id" + uid) == null
|| Integer.parseInt((String) this.baseDao.getKey(id
+ "user:id" + uid)) == 0) {
this.baseDao.incr("user:parse" + id);
this.baseDao.incr(id + "user:id" + uid);
} else {
this.baseDao.decr("user:parse" + id);
this.baseDao.decr(id + "user:id" + uid);
}
String num = (String) this.baseDao.getKey("user:parse" + id);
return num;
} else {
return null;
}
}
// 转发(redis)
@Override
public String relay(Long id, int uid) {
// 当用户没有转发,则转发数+1,redis中用户字段+1;已转发,则不允许转发
if (id > 0 && uid > 0) {
if (this.baseDao.getKey(id + "user:relayid" + uid) == null
|| Integer.parseInt((String) this.baseDao.getKey(id
+ "user:relayid" + uid)) == 0) {
this.baseDao.incr("user:relay" + id);
this.baseDao.incr(id + "user:relayid" + uid);
String num = (String) this.baseDao.getKey("user:relay" + id);
return num;
} else {
return null;
}
} else {
return null;
}
}
}
测试类
//测试redis点赞数的自增
public void testApp09() {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"beans_mybatis.xml");
BlogBiz ub=(BlogBiz) ac.getBean("blogBizImpl");
System.out.println("当前点赞数"+ub.parse(2L,1));
}
//测试redis转发数
public void testApp10() {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"beans_mybatis.xml");
BlogBiz ub=(BlogBiz) ac.getBean("blogBizImpl");
System.out.println("当前转发数"+ub.relay(2L, 1));
}
详细项目 https://github.com/937129397/microBlog/tree/dev/microBlog
参考资料 http://blog.youkuaiyun.com/tanggao1314/article/details/51125199