您的位置:首页 > 数据库 > Redis

redis缓存java项目中,配置和使用

2017-03-06 00:00 387 查看
拿项目中的redis,研究了下;

使用方式: 使用jedis操作redis与java代码结合,service层中,每次查询先查redis,如果为空,则去数据库加载数据,之后直接去redis缓存中查询数据即可。

具体有两种实现方式:

1.原生代码

2springxml配置

这里注意下,关于redis密码开启; 默认是没有密码;

改了密码,一定要用密码的方式启动才会生效;

密码的方式启动,则一定要配置密码才可以正确访问;

springxml配置方式

1.创建redis-context.xml 文件

<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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
">

<!-- scanner redis properties -->
<context:property-placeholder location="classpath:property/redis.properties" />

<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxActive" value="${redis.maxActive}" />
<property name="maxWait" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>

<bean id="connectionFactory"
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.StringRedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<!-- 		如果不配置Serializer,那么存储的时候智能使用String,如果用User类型存储,那么会提示错误User can't cast to String!!!
-->		<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
</bean>

</beans>


2.redis.properties文件配置

redis.host=127.0.0.1
redis.port=6379
redis.pass=

redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true


3.存取数据demo

public class UserOperationsServiceImpl implements UserOperationsService {
@Autowired
private RedisTemplate redisTemplate;

@Override
public void add(User user) {
// TODO Auto-generated method stub
/*
* boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
* public Boolean doInRedis(RedisConnection redisConnection) throws
* DataAccessException { RedisSerializer<String> redisSerializer =
* redisTemplate .getStringSerializer(); byte[] key =
* redisSerializer.serialize(user.getId()); byte[] value =
* redisSerializer.serialize(user.getName()); return
* redisConnection.setNX(key, value); } }); return result;
*/
ValueOperations<String, User> valueops = redisTemplate
.opsForValue();
valueops.set(user.getId(), user);
}

@Override
public User getUser(String key) {
ValueOperations<String, User> valueops = redisTemplate
.opsForValue();
User user = valueops.get(key);
return user;
}

}


RedisTemplate API

ZSetOperations:
有序集合,默认按照score升序排列,存储格式K(1)==V(n),V(1)=S(1)(K=key,V=value,S=score)

1.add(K,V,S):添加

2.count(K,Smin,Smax):键为K的集合,Smin<=score<=Smax的元素个数

3.size(K):键为K的集合元素个数

4.score(K,obj):键为K的集合,value为obj的元素分数

5.incrementScore(K,V,delta):元素分数增加,delta是增量

6.intersectAndStore(K,otherK[s],destK):K集合与otherK[s]集合,共同的交集元素存到destK(复制),返回元素个数

unionAndStore(K,otherK[s],destK):K集合与otherK[s]集合,共同的并集元素存到destK(复制),返回元素个数

7.range(K,start,end):键为K的集合,索引start<=index<=end的元素子集,正序

reverseRange(K,start,end):键为K的集合,索引start<=index<=end的元素子集,倒序

8.rangeByScore(K,Smin,Smax,[offset],[count]):键为K的集合,offerset和count是限制条件,从索引1开始找到count个元素=子集,从子集中找到Smin<=score<=Smax的元素集合,返回Set<V>,正序

reverseRangeByScore(K,Smin,Smax,[offset],[count]):键为K的集合,offerset和count是限制条件,从索引1开始找到count个元素=子集,从子集中找到Smin<=score<=Smax的元素集合,返回Set<V>,倒序

9.rangeByScoreWithScores(K,Smin,Smax,[offset],[count]):键为K的集合,offerset和count是限制条件,从索引1开始找到count个元素=子集,从子集中找到Smin<=score<=Smax的元素集合,返回泛型接口(包括score和value),正序

reverseRangeByScoreWithScores(K,Smin,Smax,[offset],[count]):键为K的集合,offerset和count是限制条件,从索引1开始找到count个元素=子集,从子集中找到Smin<=score<=Smax的元素集合,返回泛型接口(包括score和value),倒序

10.rangeWithScores(K,start,end):键为K的集合,索引start<=index<=end的元素子集,返回泛型接口(包括score和value),正序

reverseRangeWithScores(K,start,end):键为K的集合,索引start<=index<=end的元素子集,返回泛型接口(包括score和value),倒序

11.rank(K,obj):键为K的集合,value为obj的元素索引,正序

reverseRank(K,obj):键为K的集合,value为obj的元素索引,倒序

12.remove(K,obj):删除,键为K的集合,value为obj的元素

13.removeRange(K,start,end):删除,键为K的集合,索引start<=index<=end的元素子集

14.removeRangeByScore(K,Smin,Smax):删除,键为K的集合,Smin<=score<=Smax的元素,返回删除个数

SetOperations
无序集合,add的顺序不是存储顺序

1.add(K key, V value)

2.difference(K key, otherK[s]) :差集,返回Set

3.differenceAndStore(K key, otherKey[s], K destKey) :存储差集,返回Long

4.intersect(K key, otherKey[s]):交集,返回Set

5.intersectAndStore(K key, otherKey[s], K destKey)  :存储交集,返回Long

6.isMember(K key, Java.lang.Object o) :对象是否存在

7.members(K key) :所有元素,返回Set

8.move(K key, V value, K destKey) :转移一个元素到另一个key(剪切)

9.pop(K key) :出队,size减1

10.randomMember(K key) :随即元素

11.remove(K key, java.lang.Object o) :移除元素

12.size(K key)

13.union(K key, otherKey[s]):并集

14.unionAndStore(K key, otherKey[s], K destKey): 存储并集到destKey


原生代码方式

1.RedisPool.java

package com.chr.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public final class RedisPool {

//Redis服务器IP
private static String ADDR = "192.168.18.202";

//Redis的端口号
private static int PORT = 6379;

//访问密码
private static String AUTH = "123456";

//可用连接实例的最大数目,默认值为8;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
private static int MAX_ACTIVE = 1024;

//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private static int MAX_IDLE = 200;

//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
private static int MAX_WAIT = 10000;

private static int TIMEOUT = 10000;

//在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
private static boolean TEST_ON_BORROW = true;

private static JedisPool jedisPool = null;

/**
* 初始化Redis连接池
*/
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxActive(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWait(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 获取Jedis实例
* @return
*/
public synchronized static Jedis getJedis() {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

/**
* 释放jedis资源
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
}


2.RedisUtils.java

package com.chr.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Map;

import redis.clients.jedis.Jedis;

public class RedisUtils {

public static final int HOUR = 60 * 60;		//一小时
public static final int DAY = 24 * 60 * 60;	//一天,24小时 * 60分钟 * 60秒
public static final int WEEK = DAY * 7;		//一周,7天
public static final int MONTH = DAY * 30;	//一月,30天

/**
* 缓存单个值
* @param key
* @param value
*/
public static void setVal(String key,String value,int expireTime){
Jedis redis = RedisPool.getJedis();
redis.set(key, value);
redis.expire(key, expireTime);	//设置过期时间,单位秒
RedisPool.returnResource(redis);
}
/**
* <p class="detail">
* 功能:缓存单个值(Vo对象类型),默认一个星期
*  redis存的是序列化字符串
* </p>
* @throws
*/
public static void setVal(byte [] key,Object value){
Jedis redis = RedisPool.getJedis();
redis.set(key, serialize(value));
redis.expire(key, WEEK);	//设置过期时间,单位秒
RedisPool.returnResource(redis);
}

/**
* 获取单个值 (vo对象类型)
* redis取的是序列化字符串
* @param key
* @return
*/
public static Object  getVal(byte [] key){
Jedis redis = RedisPool.getJedis();
byte [] tempValue = redis.get(key);
Object  value  = unserizlize(tempValue);
RedisPool.returnResource(redis);
return value;
}
/**
* 获取单个值
* @param key
* @return
*/
public static String getVal(String key){
Jedis redis = RedisPool.getJedis();
String value = redis.get(key);
RedisPool.returnResource(redis);
return value;
}

/**
* 缓存map
* @param key
* @param map
*/
public static void setMap(String key,Map<String,String> map,int expireTime){
if( map!=null && map.size()>0 ){
Jedis redis = RedisPool.getJedis();
redis.hmset(key, map);
redis.expire(key, expireTime);	//设置过期时间,单位秒
RedisPool.returnResource(redis);
}
}

/**
* 获取整个map
* @param key
* @return
*/
public static Map<String,String> getMap(String key){
Jedis redis = RedisPool.getJedis();
Map<String,String> map = redis.hgetAll(key);
RedisPool.returnResource(redis);
return map;
}

/**
* 获取map 指定key列表的值
* @param key
* @param valKey
* @return
*/
public static List<String> getMap(String key,String...valKey){
Jedis redis = RedisPool.getJedis();
List<String> value = null;
if( redis.exists(key) ){
value = redis.hmget(key, valKey);
}
RedisPool.returnResource(redis);
return value;
}

/**
* 获取map指定key的值
* @param key
* @param valKey
* @return
*/
public static String getMapVal(String key,String valKey){
Jedis redis = RedisPool.getJedis();
String value = null;
if( redis.exists(key) ){
List<String> list = redis.hmget(key, valKey);
if( list!=null && list.size()>0 ){
value = list.get(0);
}
}
RedisPool.returnResource(redis);
return value;
}

/**
* 缓存List
* @param key
* @param list
*/
public static void setList(String key,List<String> list,int expireTime){
if( list!=null && list.size()>0 ){
String[] listgroup = new String[list.size()];
Jedis redis = RedisPool.getJedis();
redis.lpush(key, list.toArray(listgroup));
redis.expire(key, expireTime);	//设置过期时间,单位秒
RedisPool.returnResource(redis);
}
}

/**
* 获取List
* @param key
* @return
*/
public static List<String> getList(String key){
Jedis redis = RedisPool.getJedis();
List<String> value = null;
if( redis.exists(key) ){
value = redis.lrange(key, 0, -1);
}
RedisPool.returnResource(redis);
return value;
}

/**
* 升序排序后输出List
* @param key
* @return
*/
public static List<String> sortList(String key){
Jedis redis = RedisPool.getJedis();
List<String> value = null;
if( redis.exists(key) ){
value = redis.sort(key);
}
RedisPool.returnResource(redis);
return value;
}

/**
* 删除指定缓存对象
* @param key
*/
public static void del(String...key){
Jedis redis = RedisPool.getJedis();
redis.del(key);
RedisPool.returnResource(redis);
}

/**
* 序列化 <p class="detail">
* 功能:存储对象
* </p>
* @return
* @throws
*/
public static byte [] serialize(Object obj){
ObjectOutputStream obi=null;
ByteArrayOutputStream bai=null;
try {
bai=new ByteArrayOutputStream();
obi=new ObjectOutputStream(bai);
obi.writeObject(obj);
byte[] byt=bai.toByteArray();
return byt;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

/**
* 反序列化<p class="detail">
* 功能:反序列化存储对象
* </p>
* @return
* @throws
*/
public static Object unserizlize(byte[] byt){
ObjectInputStream oii=null;
ByteArrayInputStream bis=null;
bis=new ByteArrayInputStream(byt);
try {
oii=new ObjectInputStream(bis);
Object obj=oii.readObject();
return obj;
} catch (Exception e) {

e.printStackTrace();
}

return null;
}

}


3.Jredis API

<一>. 使用list:
可以使用列表模拟队列(queue)、堆栈(stack),并且支持双向的操作(L或者R)。
1. 右边入队:

jedis.rpush("userList", "James");
2. 左边出队:右边出栈(rpop),即为对堆栈的操作。

jedis.lpop("userList");
3. 返回列表范围:从0开始,到最后一个(-1) [包含]

List<String> userList = jedis.lrange("userList", 0, -1);
Redis的TopN操作,即使用list完成:lrange
4. 删除:使用key

jedis.del("userList");
5. 设置:位置1处为新值

jedis.lset("userList", 1, "Nick Xu");
6. 返回长度:

Long size = jedis.llen("userList");
7. 进行裁剪:包含

jedis.ltrim("userList", 1, 2);

<二>. 使用set:和列表不同,集合中的元素是无序的,因此元素也不能重复。
1. 添加到set:可一次添加多个

jedis.sadd("fruit", "apple");
jedis.sadd("fruit", "pear", "watermelon");
jedis.sadd("fruit", "apple");
2. 遍历集合:

Set<String> fruit = jedis.smembers("fruit");
3. 移除元素:remove

jedis.srem("fruit", "pear");
4. 返回长度:

Long size = jedis.scard("fruit");
5. 是否包含:

Boolean isMember = jedis.sismember("fruit", "pear");
6. 集合的操作:包括集合的交运算(sinter)、差集(sdiff)、并集(sunion)

jedis.sadd("food", "bread", "milk");
Set<String> fruitFood = jedis.sunion("fruit", "food");

<三>. 使用sorted set:有序集合在集合的基础上,增加了一个用于排序的参数。
1. 有序集合:根据“第二个参数”进行排序。

jedis.zadd("user", 22, "James");
2. 再次添加:元素相同时,更新为当前的权重。

jedis.zadd("user", 24, "James");
3. zset的范围:找到从0到-1的所有元素。

Set<String> user = jedis.zrange("user", 0, -1);
4. 说明:我们可能还有一个疑虑,集合是怎么做到有序的呢?
实际上,上述user的数据类型为java.util.LinkedHashSet

<四>. 使用hash:
1. 存放数据:使用HashMap

Map<String, String>  capital = new HashMap<String, String>();
capital.put("shannxi", "xi'an");
...
jedis.hmset("capital", capital);
2. 获取数据:

List<String> cities = jedis.hmget("capital", "shannxi", "shanghai");

<五>. 其他操作:
1. 对key的操作:
@ 对key的模糊查询:

Set<String> keys = jedis.keys("*");
Set<String> keys = jedis.keys("user.userid.*");
@ 删除key:

jedis.del("city");
@ 是否存在:

Boolean isExists = jedis.exists("user.userid.14101");
2. 失效时间:
@ expire:时间为5s

jedis.setex("user.userid.14101", 5, "James");
@ 存活时间(ttl):time to live

Long seconds = jedis.ttl("user.userid.14101");
@ 去掉key的expire设置:不再有失效时间

jedis.persist("user.userid.14101");
3. 自增的整型:
@ int类型采用string类型的方式存储:

jedis.set("amount", 100 + "");
@ 递增或递减:incr()/decr()

jedis.incr("amount");
@ 增加或减少:incrBy()/decrBy()

jedis.incrBy("amount", 20);
4. 数据清空:
@ 清空当前db:

jedis.flushDB();
@ 清空所有db:

jedis.flushAll();
5. 事务支持:
@ 获取事务:

Transaction tx = jedis.multi();
@ 批量操作:tx采用和jedis一致的API接口

for(int i = 0;i < 10;i ++) {
tx.set("key" + i, "value" + i);
System.out.println("--------key" + i);
Thread.sleep(1000);
}
@ 执行事务:针对每一个操作,返回其执行的结果,成功即为Ok

List<Object> results = tx.exec();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Redis Java
相关文章推荐