jedis是Redis官方推荐的java连接开发工具,使用java操作Redis的中间键
1.新建maven项目
2.导入依赖
<!-- 导入jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
<!-- fastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
2.编码测试:
- 连接数据库
- 操作命令
- 断开连接
测试连接:
import redis.clients.jedis.Jedis;
public class TestPing {
public static void main(String[] args) {
// 1. new Jedis 对象
Jedis jedis = new Jedis("127.0.0.1", 6379);
System.out.println(jedis.ping());
}
}
输出
PONG
如果redis在服务器上
import redis.clients.jedis.Jedis;
public class TestPing {
public static void main(String[] args) {
// 1. new Jedis 对象
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.auth("password");
System.out.println(jedis.ping());
// (输出PONG的话就成功了)
}
}
执行下面命令即可
String
List
Set
Hash
Zset
Jedis事务
正常情况下执行成功
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class RestResis {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
JSONObject jsonObject = new JSONObject();
jsonObject.put("heool", "world");
jsonObject.put("tel", "1338888");
Transaction multi = jedis.multi();//开启事务
try {
String result = jsonObject.toJSONString();
multi.set("key1", result);
multi.set("key2", result);
multi.exec(); //成功 执行事务
} catch (Exception e) {
multi.discard();//出异常 放弃事务
e.printStackTrace();
} finally {
System.out.println(jedis.get("key1"));
System.out.println(jedis.get("key2"));
jedis.close();//关闭连接
}
}
}
输出:
{"heool":"world","tel":"1338888"}
{"heool":"world","tel":"1338888"}
抛出异常执行失败
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class RestResis {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.flushDB();
JSONObject jsonObject = new JSONObject();
jsonObject.put("heool", "world");
jsonObject.put("tel", "1338888");
Transaction multi = jedis.multi();//开启事务
String result = jsonObject.toJSONString();
jedis.watch(result);//监控
try {
multi.set("key1", result);
multi.set("key2", result);
int i = 1 / 0; //抛出异常,事务执行失败
multi.exec(); //成功 执行事务
} catch (Exception e) {
multi.discard();//出异常 放弃事务
e.printStackTrace();
} finally {
System.out.println(jedis.get("key1"));
System.out.println(jedis.get("key2"));
jedis.close();//关闭连接
}
}
}
SpringBoot整合
SpringBoot操作数据:spring-boot-starter-data-redis
在SpringBoot2.x之后,原来的jedis被替换为lettuce
jedis:采用直连,多个线程操作是不安全的,如果想要避免不安全,就要使用jedis的pool连接池 ,更像BIO模式
SpringBoot2.0之后使用lettuce
lettuce:采用netty,示例可以在多个线程之间进行共享,不存在线程不安全的情况!可以减少线程数量,更像NIO模式
redis源码
@Bean
@ConditionalOnMissingBean(name = {"redisTemplate"}) //可以自定义redisTemplate来替换这个默认的
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//默认的 RedisTemplate 没有过多的设置,redis对象需要序列化
//两个泛型都是Object类型,后期使用需要强转为<String , Object>
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)//String是Redis最常使用的一个类型,所以单独提出来一个bena
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
整合测试
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置连接
#源码中默认是localhost
spring.redis.host=127.0.0.1
#端口设置
spring.redis.port=6379
#设置库,默认0号库
spring.redis.database=1
3.测试
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//opsForValue 操作String
//opsForList 操作list
//opsForSet 操作set
// opsForHash
// opsForZSet
// opsForGeo
// opsForHyperLogLog
// 除了最基本的使用,也可以用RedisTemplate操作事务,基本的CRUD
// 获取redis 的连接对象
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushAll();
// connection.flushDb();
redisTemplate.opsForValue().set("key1", "v1");
System.out.println(redisTemplate.opsForValue().get("key1"));
}
序列化设置
自定义RedisTemplate
实体类需要进行序列化,如果没有实例化就会报错 ,在实体类上加 implements Serializable
即可
实体序列化后结果正常
查看结果发旋出现了乱码,原因是使用了默认的模板
解决方法: 自定义Template
@Configuration
public class RedisConfig {
// 自定义Redis
@Bean
@SuppressWarnings("all")
public RedisTemplate<String , Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 序列化配置
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// Hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value的序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化也采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
测试自定义模板
@SpringBootTest
class Redis02SpringboootApplicationTests {
@Autowired
@Qualifier("redisTemplate1")
private RedisTemplate redisTemplate;
@Test
public void test() throws JsonProcessingException {
User user = new User("张三", 19);
// String jsonUser = new ObjectMapper().writeValueAsString(user);
redisTemplate.opsForValue().set("key3", user);
System.err.println(redisTemplate.opsForValue().get("key3"));
}
}
使用自定义模板后