redis单节点操作封装-功能更新

版权声明:本文为博主原创文章,转载请注明出处,否则予以追究。 https://blog.csdn.net/J_Anson/article/details/79345530

博主曾与之前分享了两篇文章,一篇关于redis单节点数据库在lunix上的安装,一篇为基于redis单节点数据库的操作封装。

CentOS7-源码安装redis单节点

redis单点缓存数据库操作封装

本文基于前文redis单点缓存数据库操作封装,添加redis服务功能。

文件结构

        RedisUtils.java——redis工具类,初始化配置

        RedisService.java——redis服务类,提供多种redis的操作的封装


redis-maven坐标

        <!-- redis -->
        <dependency>
		    <groupId>redis.clients</groupId>
		    <artifactId>jedis</artifactId>
		    <version>2.8.0</version>
        </dependency>

所需依赖包commons-pool2-maven坐标

		<dependency>
		    <groupId>org.apache.commons</groupId>
		    <artifactId>commons-pool2</artifactId>
		    <version>2.4.2</version>
		</dependency>

日志类依赖maven坐标

扫描二维码关注公众号,回复: 3680336 查看本文章
		<dependency>
		    <groupId>log4j</groupId>
		    <artifactId>log4j</artifactId>
		    <version>1.2.17</version>
		</dependency>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-api</artifactId>
		    <version>1.6.6</version>
		</dependency>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-jdk14</artifactId>
		    <version>1.7.25</version>
		</dependency>
RedisUtil.java
package com.es.redis;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * @author Anson
 *	Copyright by EasyShare 2017
 *  
 *  All right reserved
 *
 *  Created on 2017年6月25日 下午4:12:56
 *  
 *  redis工具类
 */
public final class RedisUtil {
    
    /** Redis服务器IP */
    private static String ADDR;
    /** Redis的端口号 */
    private static int PORT;
    /** 访问密码 */
    private static String AUTH;
    /** 可用连接实例的最大数目,默认值为8<br>
     *  如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
     */
    private static int MAX_ACTIVE;
    /** 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8 */
    private static int MAX_IDLE;
    /** 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException */
    private static int MAX_WAIT;
    /** 尝试建立连接的最大等待时间 */
    private static int TIMEOUT;
    /** 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的 */
    private static boolean TEST_ON_BORROW;
    /** redis连接池对象 */
    private static JedisPool jedisPool = null;
    /** 日志 */
    private static Logger logger=LoggerFactory.getLogger(RedisUtil.class.getName());
    
    /**
     * 初始化Redis连接池
     */
    static
    {
        try 
        {
        	//加载参数
           loadProperty();
        } catch (Exception e) 
        {
            e.printStackTrace();
        }
    }
    
    /**
     * 加载redis配置参数
     */
    private final static void loadProperty() {
		Properties prop=new Properties();
		try {
			prop.load(new FileInputStream(new File(Thread.currentThread().getContextClassLoader().getResource("").getPath()+"redis.properties")));
			ADDR=prop.getProperty("ADDR").trim();
			PORT=Integer.parseInt(prop.getProperty("PORT").trim());
			AUTH=prop.getProperty("AUTH");
			MAX_ACTIVE=Integer.parseInt(prop.getProperty("MAX_ACTIVE").trim());
			MAX_IDLE=Integer.parseInt(prop.getProperty("MAX_IDLE").trim());
			MAX_WAIT=Integer.parseInt(prop.getProperty("MAX_WAIT").trim());
			TIMEOUT=Integer.parseInt(prop.getProperty("TIMEOUT").trim());
			TEST_ON_BORROW=prop.getProperty("TEST_ON_BORROW").trim().toLowerCase().equals("true");
		
			logger.info("redis参数加载成功,"
					+ "参数:ADDR="+ADDR+" PORT="+PORT+" AUTH="+AUTH+
					"MAX_ACTIVE="+MAX_ACTIVE+"  MAX_IDLE="+MAX_IDLE+"  MAX_WAIT="+MAX_WAIT+"  TIMEOUT="+TIMEOUT+"  TEST_ON_BORROW="+TEST_ON_BORROW);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

    
    /**
     * 创建redis池
     */
    private final static void initJedisPool() {
    	try
    	{
    		JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
           // logger.info(jedisPool!=null?"redis池创建成功":"redis池创建失败,位置:"+RedisUtil.class.getName());	
            logger.info(jedisPool!=null?"redis连接池创建成功":"");	
    	}catch(Exception e)
    	{
    		logger.error("第一次尝试创建jedis连接池错误,位置:"+RedisUtil.class.getName());
    		try
    		{
    			JedisPoolConfig config = new JedisPoolConfig();
                config.setMaxIdle(MAX_ACTIVE);
                config.setMaxIdle(MAX_IDLE);
                config.setMaxWaitMillis(MAX_WAIT);
                config.setTestOnBorrow(TEST_ON_BORROW);
                jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
                logger.info(jedisPool!=null?"redis连接池创建成功":"");
    		}catch(Exception e1)
    		{
    			logger.error("第二次尝试创建jedis连接池错误,位置:"+RedisUtil.class.getName());
    		}
    	}
  	}
    
    /**
     * 多线程下同步初始化
     */
    private synchronized static void loadPool()
    {
    	if(jedisPool==null)
    	{
    		initJedisPool();
    	}
    }
    
    
	/**
     * 同步获取Jedis实例,通过参数index选择不同数据库<br>
     * 可选数据库编号index范围:0-16<br>
     * @param index
     * 		数据库编号
     * @return
     * 		Jedis - redis操作实例
     */
    public synchronized static Jedis getJedis(int index){
    	if(jedisPool==null)
    	{
    		//未创建连接池是创建连接池
    		loadPool();
    	}
    	Jedis jedis=null;
        try
        {
            if (jedisPool != null) 
            {
                 jedis= jedisPool.getResource();
                 //选择数据库
                 jedis.select(index);
            }
        } catch (Exception e) 
        {
        	logger.info("获取redis对象失败,位置:"+RedisUtil.class.getName());
            e.printStackTrace();
        }
        return jedis;
    }
    

	/**
     * 释放jedis资源
     * @param jedis
     * 		Jedis - redis操作实例
     */
	public synchronized static void close(final Jedis jedis){
        if (jedis!=null) 
        {
        	jedis.close();
        }
    }
}

RedisService.java

package com.es.redis;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;


/**
 * @author Anson
 *	Copyright by EasyShare 2017
 *  
 *  All right reserved
 *
 *  Created on 2017年6月25日 下午4:12:38
 *  
 *  redis服务类
 */
public class RedisService {
	
	private static Logger logger=LoggerFactory.getLogger(RedisService.class.getName());
	/** 数据库编号,默认为0号数据库 **/
	private static int INDEX=0;
	
	/**
	 * 获取当前使用的数据库编号,若未设置,则默认为0号<br>
	 * @return
	 * 		index-数据库编号
	 */
	public synchronized static int index() {
		return INDEX;
	}

	/**
	 * 设置所需使用的数据库编号,若不设置,则默认为0号<br>
	 * 可使用的数据库编号index范围:0-16<br>
	 * @param index
	 * 		数据库编号
	 */
	public synchronized static void select(int index) {
		INDEX = index;
	}

	/**
	 * 通过key值获取redis中的value,获取后释放链接
	 * @param key
	 * 		String - 键
	 * @return
	 * 		object - 值
	 */
	public synchronized static Object get(String key)
	{
		Jedis jedis=null;
		byte[] value=null;
		Object obj=null;
		jedis=RedisUtil.getJedis(INDEX);
		value=jedis.get(key.getBytes());
		if(value!=null)
		{
			obj=deSerialize(value);
		}
		RedisUtil.close(jedis);
		return obj;
	}
	
	/**
	 * 缓存一个对象,key存在则覆盖
	 * @param key
	 * 		String - 需保存的的键
	 * @param value
	 * 		Object - 需保存的值
	 * @return
	 * 		boolean
	 */
	public synchronized static boolean set(String key, Object obj)
	{
		Jedis jedis=null;
		String code=null;
		jedis=RedisUtil.getJedis(INDEX);
		code=jedis.set(key.getBytes(), serialize(obj));
		RedisUtil.close(jedis);
		return code.toLowerCase().equals("ok");
	}
	
	/**
	 * 缓存带有存活时间的Object,key存在则覆盖
	 * @param key
	 * 			String - 缓存对象的键
	 * @param obj
	 * 			Object - 缓存对象
	 * @param expire
	 * 			int - 存活时间,单位秒
	 * @return
	 * 		boolean
	 */
	public synchronized static boolean set(String key, Object obj, int expire)
	{
		Jedis jedis=null;
		String code=null;
		jedis=RedisUtil.getJedis(INDEX);
		code=jedis.set(key.getBytes(), serialize(obj));
		jedis.expire(key.getBytes(), expire);//key存活s
		RedisUtil.close(jedis);
		return code.toLowerCase().equals("ok");
	}
	
	/**
	 * 缓存一个键值对,key-value,key存在则覆盖
	 * @param key
	 * 		String - 键
	 * @param value
	 * 		String - 值
	 * @return
	 * 		boolean
	 */
	public synchronized static boolean set(String key, String value)
	{
		Jedis jedis=null;
		String code=null;
		jedis=RedisUtil.getJedis(INDEX);
		code=jedis.set(key.getBytes(), serialize(value));
		RedisUtil.close(jedis);
		return code.toLowerCase().equals("ok");
	}
	
	/**
	 * 缓存一个键值对,key-value,并设置缓存存活时间,key存在则覆盖
	 * @param key
	 * 		String - 键
	 * @param value
	 * 		String - 值
	 * @param expire
	 * 		int - 存活时间,秒
	 * @return
	 * 		boolean
	 */
	public synchronized static boolean set(String key, String value, int expire)
	{
		Jedis jedis=null;
		String code=null;
		jedis=RedisUtil.getJedis(INDEX);
		code=jedis.set(key.getBytes(), serialize(value));
		jedis.expire(key.getBytes(), expire);//key存活时间
		RedisUtil.close(jedis);
		return code.toLowerCase().equals("ok");
	}
	
	/**
	 * redis批量写入
	 * 事物操作
	 * 当前进行的事物操作,若对应的数据被其他进程修改,则该事物将被打断
	 * @param objects
	 * 		Map<String, Object> - Map键值对组成的待存储对象
	 * @return
	 * 		boolean
	 */
	public synchronized static boolean tset(Map<String, Object> objects)
	{
		Jedis jedis=null;
		List<Object> result=null;
		jedis=RedisUtil.getJedis(INDEX);
		Transaction t=null;
		try {
			t=jedis.multi();
			for(Entry<String, Object> entry:objects.entrySet())
			{
				//监视数据
				t.watch(entry.getKey().getBytes());
				//保存数据
				t.set(entry.getKey().getBytes(), serialize(entry.getValue()));
			}
			result=t.exec();
		} catch (Exception e) {
			//回滚操作
			t.discard();
			logger.error("Redis事物操作被打断,位置:{},抛出异常:{}", RedisService.class.getName(),e);
		}
		RedisUtil.close(jedis);
		return result!=null;
	}
	
	/**
	 * redis批量写入
	 * 事物操作
	 * 当前进行的事物操作,若对应的数据被其他进程修改,则该事物将被打断
	 * @param objects
	 * 		Map<String, Object> - Map键值对组成的待存储对象
	 * @param expire
	 * 		数据失效时间
	 * @return
	 * 		boolean
	 */
	public synchronized static boolean tset(Map<String, Object> objects, int expire)
	{
		Jedis jedis=null;
		List<Object> result=null;
		jedis=RedisUtil.getJedis(INDEX);
		Transaction t=null;
		try {
			t=jedis.multi();
			for(Entry<String, Object> entry:objects.entrySet())
			{
				//监视数据
				t.watch(entry.getKey().getBytes());
				//保存数据
				t.set(entry.getKey().getBytes(), serialize(entry.getValue()));
				t.expire(entry.getKey().getBytes(), expire);//每个key存活expire秒
			}
			result=t.exec();
		} catch (Exception e) {
			//回滚操作
			t.discard();
			logger.error("Redis事物操作被打断,位置:{},抛出异常:{}", RedisService.class.getName(),e);
		}
		RedisUtil.close(jedis);
		return result!=null;
	}
	
	/**
	 * 模糊检索key
	 * @param pattern
	 * 		key匹配模板
	 * @return
	 * 		匹配的key集合
	 */
	public synchronized static Set<String> keys(String pattern)
	{
		Jedis jedis=null;
		jedis=RedisUtil.getJedis(INDEX);
		Set<String> keys=new HashSet<String>();
		keys=jedis.keys(pattern);
		RedisUtil.close(jedis);
		return keys;
	}
	
	/**
	 * 删除key对应的缓存数据
	 * @param key
	 * 		String-可变数量的key
	 * @return
	 * 		boolean
	 */
	public synchronized static long del(String ...  keys)
	{
		Jedis jedis=null;
		long code=0;
		jedis=RedisUtil.getJedis(INDEX);
		code=jedis.del(keys);
		RedisUtil.close(jedis);
		return code;
	}
	
	/**
	 * 批量删除操作
	 * @param key
	 * 		String - 键
	 * @return
	 * 		boolean
	 */
	public synchronized static long delbat(String key)
	{
		Jedis jedis=null;
		long code=0;
		jedis=RedisUtil.getJedis(INDEX);
		Set<String> keySet=jedis.keys(key+"*");
		if(keySet!=null&&keySet.size()>0)
		{
			//将获得的keys转换成数组类型
			String[] keys=new String[keySet.size()];
			keySet.toArray(keys);
			code=jedis.del(keys);
		}
		RedisUtil.close(jedis);
		return code;
	}
	
	/**
	 * 清空数据库
	 * @param isClearAll
	 * 		是否清空所有数据库<br>
	 * 		<p>false-清空当前使用的数据库,默认为0</p>
	 * @return
	 * 		true||false
	 */
	public synchronized static boolean clear(boolean isClearAll)
	{
		Jedis jedis=null;
		String code=null;
		jedis=RedisUtil.getJedis(INDEX);
		if(isClearAll)
		{
			code=jedis.flushAll();
		}else
		{
			code = jedis.flushDB();
		}
		RedisUtil.close(jedis);
		return code.toLowerCase().equals("ok");
	}
	
	/**
	 * 批量获取操作
	 * @param key
	 * 		String - 键
	 * @return
	 * 		List<Object> - 获取的对象列表
	 */
	public synchronized static List<Object> getbat(String key)
	{
		Jedis jedis=null;
		List<Object> objects=new ArrayList<Object>();
		Object object=null;
		jedis=RedisUtil.getJedis(INDEX);
		Set<String> keySet=jedis.keys(key+"*");
		RedisUtil.close(jedis);
		if(keySet!=null&&keySet.size()>0)
		{
			Iterator<String> it=keySet.iterator();
			while(it.hasNext())
			{
				String item=it.next();
				object=get(item);
				if(object!=null)
				{
					objects.add(object);
				}
			}
		}
		return objects;
	}
	
	
	/**
	 * 序列化存储对象
	 * @param obj
	 * 		Object - 待序列化对象
	 * @return
	 * 		byte[] - 序列化结果
	 */
	private synchronized static byte[] serialize(Object obj)
	{
		byte[] serialObj=null;
		ObjectOutputStream oos=null;
		ByteArrayOutputStream baos=null;
		try {
			baos=new ByteArrayOutputStream();
			oos=new ObjectOutputStream(baos);
			oos.writeObject(obj);
			serialObj=baos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}finally
		{
			try {
				if(baos!=null)
				{
					baos.close();
				}
				if(oos!=null)
				{
					oos.close();
				}
			} catch (IOException e) {
				logger.error("释放序列化资源失败,位置:{},排除异常:{}",RedisService.class.getName(),e);
			}
		}
		return serialObj;
	}
	
	/**
	 * 反序列化对象
	 * @param serialObj
	 * 		byte[] - 序列化对象
	 * @return
	 * 		Object - 反序列化结果
	 */
	private synchronized static Object deSerialize(byte[] serialObj)
	{
		Object object=null;
		ObjectInputStream ois=null;
		ByteArrayInputStream bais=null;
		try {
			if(serialObj!=null&&serialObj.length>0)
			{
				bais=new ByteArrayInputStream(serialObj);
				ois=new ObjectInputStream(bais);
				object=ois.readObject();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally
		{
			try {
				if(bais!=null)
				{
					bais.close();
				}
				if(ois!=null)
				{
					ois.close();
				}
			} catch (IOException e) {
				logger.error("释放反序列化资源失败,位置:{},抛出异常:{}",RedisService.class.getName(),e);
			}
		}
		return object;
	}
}

猜你喜欢

转载自blog.csdn.net/J_Anson/article/details/79345530