java连接redis存取数据(详细)
声明:本文章仅供参考,学无止境,若有不足之处请指出,非常感谢!
源代码+相关工具下载:https://download.csdn.net/download/corleone_4ever/10811258
目录
一.相关工具
二.准备工作
三.新建jedis项目
四.编写代码
五.连接测试
六.注意事项
一.相关工具
如果没有服务器的同学,可以在自己的电脑安装虚拟机,我这里使用的是:VMware10+centos7+redis5.0
贴出 VMware10+centos7 下载地址:https://download.csdn.net/download/corleone_4ever/10812834
开发工具用的myeclipse2014
jdk版本为1.7
java连接redis所需依赖jar包:
jedis-2.9.0.jar (redis连接工具)
commons-pool2-2.6.0.jar (jedis连接池)
fastjson-1.2.2.jar (阿里的json序列化工具)
junit-4.12.jar (单元测试)
贴出demo下载地址(包含vm10+centos7+redis5.0+jedis连接依赖jar包及其相关工具文档):
https://download.csdn.net/download/corleone_4ever/10811258
二.准备工作
在通过java连接redis之前,首先得配置好java环境
安装好redis,并且能通过外部访问(需要关闭对应防火墙)
1.启动redis

2.输入ifconfig获取本机ip,通过外部连接测试,我这里使用的是RedisDesktopManager

3.新建连接,输入你自己的ip,redis端口和密码,没有密码就不输入

4.连接成功

三.新建jedis项目
1.新建项目:右键→new→other→选择web下的Dynamic Web Project

2.这里项目名称为jedis

3.引入相关jar包,直接把依赖jar包复制到WEB-INF下的lib目录下

4.引入 junit:右键项目→properties-→ava build parh→Libraries→ADD Library→Junit→Finish
这里也可以直接引用junit包,我是用的myeclipse自带的

5.新建包com.redis.test 项目结构如下

四.编写代码
这里直接贴出代码
1.redis.properties : redis连接配置文件
连接池配置参考:https://blog.csdn.net/wx5040257/article/details/78474157
#redis服务器ipredis.ip=192.168.10.21#redis服务器端口号redis.port=6379#redis密码redis.passWord=#与服务器建立连接的超时时间redis.timeout=3000#jedis的最大活跃连接数pool.maxTotal=10#jedis最大空闲连接数pool.maxIdle=3#jedis池没有连接对象返回时,等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。#如果超过等待时间,则直接抛出JedisConnectionExceptionpool.maxWaitMillis=3000
2.RedisPoolUtil : 连接池配置工具
这里使用单例模式+双重锁定写的一个redis连接池配置工具(如需xml配置连接池,自行百度,原理相同)
package com.redis.test;import java.util.Properties;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;import redis.clients.jedis.exceptions.JedisConnectionException;/*** jedis连接池工具* @author corleone* @date 2018年11月27日*/public class RedisPoolUtil {private volatile static JedisPool jedisPool = null;private static String redisConfigFile = "redis.properties";//把redis连接对象放到本地线程中private static ThreadLocal<Jedis> local=new ThreadLocal<Jedis>();private RedisPoolUtil() {}/*** 初始化连接池* @author corleone* @date 2018年11月27日*/public static void initialPool() {try {Properties props = new Properties();//加载连接池配置文件props.load(RedisPoolUtil.class.getClassLoader().getResourceAsStream(redisConfigFile));// 创建jedis池配置实例JedisPoolConfig config = new JedisPoolConfig();// 设置池配置项值config.setMaxTotal(Integer.valueOf(props.getProperty("pool.maxTotal")));config.setMaxIdle(Integer.valueOf(props.getProperty("pool.maxIdle")));config.setMaxWaitMillis(Long.valueOf(props.getProperty("pool.maxWaitMillis")));// 根据配置实例化jedis池jedisPool = new JedisPool(config, props.getProperty("redis.ip"),Integer.valueOf(props.getProperty("redis.port")),Integer.valueOf(props.getProperty("redis.timeout")),"".equals(props.getProperty("redis.passWord"))?null:props.getProperty("redis.passWord"));System.out.println("连接池初始化成功");} catch (Exception e) {e.printStackTrace();System.err.println("连接池初始化失败");}}/*** 获取连接* @return* @author corleone* @date 2018年11月27日*/public static Jedis getInstance() {//Redis对象Jedis jedis =local.get();if(jedis==null){if (jedisPool == null) {synchronized (RedisPoolUtil.class) {if (jedisPool == null) {initialPool();}}}try{jedis = jedisPool.getResource();}catch(JedisConnectionException e){e.printStackTrace();}local.set(jedis);}return jedis;}/*** 关闭连接* @author corleone* @date 2018年11月27日*/public static void closeConn(){Jedis jedis =local.get();if(jedis!=null){jedis.close();}local.set(null);}}
3.SerializeUtil : java序列化/反序列化封装工具
package com.redis.test;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;/*** java序列化/反序列化工具* @author corleone* @date 2018年11月27日*/public class SerializeUtil {/*** 序列化* @param object* @author corleone* @date 2018年11月27日*/public static byte[] serizlize(Object object){ObjectOutputStream oos = null;ByteArrayOutputStream baos = null;try {baos = new ByteArrayOutputStream();oos = new ObjectOutputStream(baos);oos.writeObject(object);byte[] bytes = baos.toByteArray();return bytes;} catch (Exception e) {e.printStackTrace();}finally {try {if(baos != null){baos.close();}if (oos != null) {oos.close();}} catch (Exception e2) {e2.printStackTrace();}}return null;}/*** 反序列化* @param bytes* @author corleone* @date 2018年11月27日*/public static Object deserialize(byte[] bytes){ByteArrayInputStream bais = null;ObjectInputStream ois = null;try{bais = new ByteArrayInputStream(bytes);ois = new ObjectInputStream(bais);return ois.readObject();}catch(Exception e){e.printStackTrace();}finally {try {} catch (Exception e2) {e2.printStackTrace();}}return null;}}
4.MapUtil : 对象与map相互转换封装工具
能够转换的对象需要该对象的属性必须是String或int类型,我这里只做演示,其他类型需要自己扩展
package com.redis.test;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.HashMap;import java.util.Map;/*** java反射机制* 对象与map相互转换* @author corleone* @date 2018年11月14日*/public class MapUtil {/*** map转对象(目前只支持对象中含有String和int类型的属性,其他类型需要自己扩展)* @param map* @param beanClass* @throws Exception* @author corleone* @date 2018年11月27日*/public static <T> Object mapToObject(Map<String, String> map, Class<?> beanClass)throws Exception {if (map == null)return null;Object obj = beanClass.newInstance();Field[] fields = obj.getClass().getDeclaredFields();for (Field field : fields) {int mod = field.getModifiers();if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {continue;}field.setAccessible(true);if(field.getType().equals(int.class)){field.set(obj, Integer.parseInt(map.get(field.getName())));}else{field.set(obj, (Object)map.get(field.getName()));}}return obj;}/*** 对象转map(目前只支持对象属性为基本类型)* @param obj* @throws Exception* @author corleone* @date 2018年11月27日*/public static Map<String, String> objectToMap(Object obj) throws Exception {if (obj == null) {return null;}Map<String, String> map = new HashMap<String, String>();Field[] declaredFields = obj.getClass().getDeclaredFields();for (Field field : declaredFields) {field.setAccessible(true);map.put(field.getName(), field.get(obj).toString());}return map;}}
5.ReflectUtil : 通过反射根据对象属性名称获取对应属性的值(在实际项目中用aop实现连接redis的时候有用到,本次演示没有用到该工具类,所以不贴出代码,有兴趣可以下载demo自己研究下:一.相关工具)
6.RedisOps : jedis存取常用数据封装工具类
这里写了String类型和hash类型两种数据存取,如需要存取其他数据类型可以自己扩展
package com.redis.test;import com.alibaba.fastjson.JSON;import redis.clients.jedis.Jedis;/*** redis存取工具类* @author corleone* @date 2018年11月15日*/public class RedisOps {/*** kv字符串存* @param key* @param value* @author corleone* @date 2018年11月15日*/public static void set(String key,String value){Jedis jedis = RedisPoolUtil.getInstance();jedis.set(key, value);RedisPoolUtil.closeConn();}/*** kv字符串取* @param key* @return 字符串* @author corleone* @date 2018年11月15日*/public static String get(String key){Jedis jedis = RedisPoolUtil.getInstance();String value = jedis.get(key);RedisPoolUtil.closeConn();return value;}/*** kv对象存(java序列化方式)* @param key* @param object 对象类必须实现序列化* @author corleone* @date 2018年11月15日*/public static void setObjectSerialize(String key,Object object){Jedis jedis = RedisPoolUtil.getInstance();if(jedis==null){return;}jedis.set(key.getBytes(), SerializeUtil.serizlize(object));RedisPoolUtil.closeConn();}/*** kv对象取(java反序列化)* @param key* @return 对象* @author corleone* @date 2018年11月15日*/public static Object getObjectSerialize(String key){Jedis jedis = RedisPoolUtil.getInstance();if(jedis==null){return null;}byte[] bytes = jedis.get(key.getBytes());RedisPoolUtil.closeConn();if(bytes==null){return null;}return SerializeUtil.deserialize(bytes);}/*** 删除key* @param key* @author corleone* @date 2018年11月15日*/public static void del(String key){Jedis jedis = RedisPoolUtil.getInstance();if(jedis==null){return;}jedis.del(key.getBytes());RedisPoolUtil.closeConn();}/*** kv对象存(json方式)* @param key* @param object* @author corleone* @date 2018年11月15日*/public static void setObjectJson(String key,Object object){Jedis jedis = RedisPoolUtil.getInstance();if(jedis==null){return;}jedis.set(key, JSON.toJSONString(object));RedisPoolUtil.closeConn();}/*** kv对象取(json方式)* @param key* @param clazz反序列化对象类型* @return 对象* @author corleone* @date 2018年11月15日*/@SuppressWarnings({ "unchecked" })public static <T> Object getObjectJson(String key,Class<?> clazz){Jedis jedis = RedisPoolUtil.getInstance();if(jedis==null){return null;}String result= jedis.get(key);RedisPoolUtil.closeConn();if(result==null){return null;}T obj=(T)JSON.parseObject(result,clazz);return obj;}/*** kv对象存(map形势)* @param key* @param u* @throws Exception* @author corleone* @date 2018年11月27日*/public static void setObjectHash(String key, Object u) throws Exception {Jedis jedis = RedisPoolUtil.getInstance();if(jedis==null){return ;}jedis.hmset(key, MapUtil.objectToMap(u));RedisPoolUtil.closeConn();}/*** kv对象取(map形势)* @param key* @param clazz* @throws Exception* @author corleone* @date 2018年11月27日*/public static Object getObjectHash(String key,Class<?> clazz) throws Exception {Jedis jedis = RedisPoolUtil.getInstance();if(jedis==null){return null;}Object obj = MapUtil.mapToObject(jedis.hgetAll(key), clazz);RedisPoolUtil.closeConn();if(obj==null){return null;}return obj;}}
7.User Vehicle两个实体类 后者没有实现Serializable,不能用于java序列化存取
User
package com.redis.test;import java.io.Serializable;/*** 用户实体类* @author corleone* @date 2018年11月27日*/public class User implements Serializable {private static final long serialVersionUID = -3210884885630038713L;private int id;private String name;private int age;public User(){}public User(int id,String name,int age){this.id = id;this.name = name;this.age=age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + ", age=" + age + "]";}}
Vehicle
package com.redis.test;/*** 车辆实体类* @author corleone* @date 2018年11月27日*/public class Vehicle {private int id;private String platenumber;private String color;public Vehicle(){}public int getId() {return id;}public Vehicle(int id, String platenumber, String color) {this.id = id;this.platenumber = platenumber;this.color = color;}public void setId(int id) {this.id = id;}public String getPlatenumber() {return platenumber;}public void setPlatenumber(String platenumber) {this.platenumber = platenumber;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overridepublic String toString() {return "Vehicle [id=" + id + ", platenumber=" + platenumber+ ", color=" + color + "]";}}
8.JTest : jedis存取数据测试类
package com.redis.test;import org.junit.Test;import redis.clients.jedis.Jedis;/*** jedis存取测试* @author corleone* @date 2018年11月27日*/public class JTest {/*** 测试连接* @author corleone* @date 2018年11月27日*/@Testpublic void TestPing(){Jedis jedis = RedisPoolUtil.getInstance();System.out.println(jedis.ping());}/*** 测试java序列化存取* @author corleone* @date 2018年11月27日*/@Testpublic void TestSerialize(){User u = new User(1,"小明",6);RedisOps.setObjectSerialize(User.class.getName().toString()+":"+1, u);User u2 = (User)RedisOps.getObjectSerialize(User.class.getName().toString()+":"+1);System.out.println(u2.toString());}/*** 测试json序列化存取* @author corleone* @date 2018年11月27日*/@Testpublic void TestJson(){User u = new User(1,"小明",6);Vehicle v = new Vehicle(1,"渝A00000","蓝色");RedisOps.setObjectJson(User.class.getName().toString()+":"+1, u);RedisOps.setObjectJson(Vehicle.class.getName().toString()+":"+1, v);User u2 = (User)RedisOps.<User>getObjectJson(User.class.getName().toString()+":"+1,User.class);Vehicle v2 = (Vehicle)RedisOps.<Vehicle>getObjectJson(Vehicle.class.getName().toString()+":"+1,Vehicle.class);System.out.println(u2.toString());System.out.println(v2.toString());}/*** 测试hash存取* @throws Exception* @author corleone* @date 2018年11月27日*/@Testpublic void TestHash() throws Exception{Vehicle v = new Vehicle(1,"渝A00000","蓝色");RedisOps.setObjectHash(Vehicle.class.getName().toString()+":"+1, v);Vehicle v2=(Vehicle) RedisOps.getObjectHash(Vehicle.class.getName().toString()+":"+1,Vehicle.class);System.out.println(v2.toString());}}
五.连接测试
这里以json序列化存取对象为例
1.执行TestJson方法成功

2.查看redis中的数据

六.注意事项
这里都是踩坑过来的,把我遇到过的问题也贴出来
1.外部无法连接:一般是linux防火墙未关闭的原因,这里特别注意centos7关闭防火墙与之前版本不一样,如果你用的centos7,那么请整对centos7进行百度
2.如果你的redis没有密码,请不要输入空字符串
3.java序列化存取对象,记得实现Serializable
4.如果你的实体类添加了有参构造方法,请重写无参构造方法,否则报如下错误

后续贴出springAOP实现redis连接,以及本人在实际业务中的存取方式,如有不足感谢指出!
