jedis
使用java来操作redis
jedis是redis官方推荐的Java连接开发工具。
1.导入依赖
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
</dependencies>
2.编码测试
- 链接数据库
- 操作命令
- 断开链接
public static void main(String[] args) {
//1.new 一个Jedis对象
Jedis jedis = new Jedis("127.0.0.1",6379);
//jedis 所有命令就是我们之前学得
System.out.println(jedis.ping());
}
输出
public class TestKey {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
System.out.println("清空数据:"+jedis.flushDB());
System.out.println("判断某个数据是否存在:"+jedis.exists("uname"));
System.out.println("新增uname:beibei:"+jedis.set("uname","beibei"));
System.out.println("新增upass:beibeimima:"+jedis.set("upass","beibeimima"));
System.out.println("随机返回key控件的一个:"+jedis.randomKey());
System.out.println("系统中所有建:"+jedis.keys("*"));
Set<String> keys = jedis.keys("*");
System.out.println(keys);
System.out.println("删除key,upass:"+jedis.del("upass"));
System.out.println("判断某个key,upass是否存在:"+jedis.exists("upass"));
System.out.println("查看key,uname的类型:"+jedis.type("uname"));
System.out.println("重命名key:"+jedis.rename("uname","uname1"));
System.out.println("取出更改后的name:"+jedis.get("uname1"));
System.out.println("切换库1:"+jedis.select(1));
System.out.println("取出更改后的name:"+jedis.get("uname1"));
System.out.println("新增uname:beibei:"+jedis.set("uname","beibei"));
System.out.println("取出uname:"+jedis.get("uname"));
System.out.println("删除当前数据库:"+jedis.flushDB());
System.out.println("当前库大小:"+jedis.dbSize());
System.out.println("切换库0:"+jedis.select(0));
System.out.println("当前库0大小:"+jedis.dbSize());
System.out.println("切换库1:"+jedis.select(1));
System.out.println("删除所有数据库:"+jedis.flushAll());
System.out.println("切换库0:"+jedis.select(0));
System.out.println("当前库0大小:"+jedis.dbSize());
}
}
输出:
事务
public class TestTX {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.flushDB();
JSONObject jsonObject = new JSONObject();
jedis.set("uname","beiebi");
jsonObject.put("money",100);
jsonObject.put("out",0);
Transaction multi= jedis.multi();//开启事务
String result = jsonObject.toJSONString();
try{
multi.set("bank1",result);
multi.set("bank2",result);
//int i = 1/0;//代码抛出异常,执行失败,输出为null
multi.exec();//执行事务
} catch (Exception e){
multi.discard();
}finally {
System.out.println(jedis.get("bank1"));
System.out.println(jedis.get("bank2"));
jedis.close();//关闭连接
}
}
}
正常输出:
抛错输出
Springboot整合
springBoot操作数据:spring data, jpa, jdbc,monggodb,redis
SpringData也是和springboot齐名的项目
说明:在springboot2.x之后,原来使用的jedis被替换为lettuce
jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池!(类似于BIO)
lettuce:采用用netty(可以看lettuce引用的netty),实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
源码分析:
找到redis
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
//如果不存在才启用这个,可以自己写一个去替换
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//默认的RedisTemplate没有过多的设置,redis对象都是需要序列化的
//两个泛型都是object,object的类型,我们使用string,Object需要强制转换
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
//由于string是最常使用的,单独提出来一个bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
整合测试
- 导入依赖
- 配置连接
spring.redis.host=127.0.0.1
spring.redis.port=6379
- 测试
@SpringBootTest
class Redis02SpringbootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
/**
* opsForValue 操作string
* opsForHash 操作hash
* opsForList 操作list
* opsForSet 操作set
* opsForZSet
* opsForHyperLogLog
* opsForGeo
*/
//除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务和基本的CRUD
//获取redis的连接对象,
/*RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
redisConnection.flushDb();
redisConnection.flushAll();*/
redisTemplate.opsForValue().set("mykey","beibei贝贝");
System.out.println(redisTemplate.opsForValue().get("mykey"));
}
}
输出:
中文乱码问题:
java代码中设置了mykey beibei贝贝
用窗口查看时mykey前有一堆乱码,需要将其序列化来解决
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (this.defaultSerializer == null) {
//默认的序列化方式是jdk序列化,我们可能会使用Json来序列化
this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}
if (this.enableDefaultSerializer) {
if (this.keySerializer == null) {
this.keySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.valueSerializer == null) {
this.valueSerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashKeySerializer == null) {
this.hashKeySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashValueSerializer == null) {
this.hashValueSerializer = this.defaultSerializer;
defaultUsed = true;
}
}
if (this.enableDefaultSerializer && defaultUsed) {
Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
}
if (this.scriptExecutor == null) {
this.scriptExecutor = new DefaultScriptExecutor(this);
}
this.initialized = true;
}
关于对象的保存:
将对象序列化:
序列化后输出
编写一个自己的redisTemplate
@Configuration
public class RedisConfig {
/*
*
* public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
*/
//编写我们自己的redisTemplate
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
//写成<String, Object>为了方便我们日常使用
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
//建立连接
template.setConnectionFactory(redisConnectionFactory);
//序列化配置
//json的序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(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;
}
}
使用自己学的redisTemplate之后,flushdb,再次执行测试代码窗口中的key不再乱码
不知道为啥我写了redisTemplate,但是我窗口get key还是乱码???但是我看狂神的视屏他取出来没有乱码,暂时还没找到方案解决
redisUtil工具类
可以参照这个:https://www.cnblogs.com/zeng1994/p/03303c805731afc9aa9c60dbbd32a323.html