非关系型KV数据库Redis
介绍使用Java对redis数据库进行操作的相关记录
一、Jedis整合Redis
1.1 新建项目
新建一个SpringBoot的项目,导入相关的jedis依赖以及启动器
<dependencies>
<!--jedis 不需要设置版本号 因为springboot已经内置好了jedis的版本-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.2 写一个jedis连接的配置文件
- JedisPool 类 :jedis连接池
里面有许多的构造方法
这里我们最常使用的构造有两个
JedisPool(String host,int port)
2.JedisPool(final GenericObjectPoolConfig<Jedis> poolConfig, final String host, int port, int timeout, final String password)
使用配置文件进行jedis的相关配置参数
spring:
redis:
database: 0 # 数据库 0-15
host: 192.168.188.129 # ip地址
port: 6379 # 端口号
# 连接池配置
jedis:
pool:
max-active: 8 # 最大连接数
max-idle: 8 # 最大空闲数
min-idle: 1 # 最小空闲数
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
public class JedisConfig {
private int database;
private String host;
private int port;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
/**
* jedis连接池配置 在jedis连接池中获取jedis连接
* @return
*/
@Bean
public JedisPool geJedisPool() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(maxIdle);
config.setMaxTotal(maxActive);
config.setMinIdle(minIdle);
JedisPool pool = new JedisPool(config,host,port,2000,null);
return pool;
}
public int getDatabase() {
return database;
}
public void setDatabase(int database) {
this.database = database;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
1.3 连接测试
@SpringBootTest
class DhcRedisProjectJedis2ApplicationTests {
@Autowired
private JedisPool jedisPool;
@Test
void contextLoads() {
Jedis jedis = jedisPool.getResource();
System.out.println(jedis.ping());
jedis.close();
}
}
二、key的相关操作
使用Jedis来操作redis中key的方法常用的主要有以下方法
ping(final String message)
:测试redis连接是否成功 连接成功返回message,默认不写参数连接成功返回PONGset(final String key, final String value)
:向redis中设置一个key-value 如果键已经存在,则会将新的value值覆盖掉之前的value值strlen(final String key)
:获取指定key的长度 返回值类型是Longmset(final String... keysvalues)
:设置多个key-value 参数是一个String类型的可变形参,有mset那必然会有mget
setex(final String key, final long seconds, final String value)
:设置一个带有失效时间的keyttl(final String key)
:获取一个key的剩余时间 返回值是一个Long类型expire(final String key, final long seconds)
:为一个已经存在的key设置失效时间getSet(final String key, final String value)
:设置key-value,如果键不存在就返回一个null,否则会返回旧的值相当于是修改的命令
del(final String key)
:删除一个key 如果key存在则会返回1 否则返回0 即删除成功的个数type(final String key)
:获取一个key的数据类型keys(final String pattern)
:获取符合通配条件的key 参数支持*
代表所有任意的类型decrby|decr|incrby|incr
如果是带有by的方法则会指定步进长度来增加一个数字类型的String的key 否则是默认自增1的,如果不是数字类型的会报错
@SpringBootTest
public class JedisKey {
@Autowired
private JedisPool jedisPool;
@Test
public void testKey() {
Jedis jedis = jedisPool.getResource();
// 测试链接是否成功
System.out.println(jedis.ping("hello"));
// 测试设置redis的key
System.out.println("=============设置值=============");
System.out.println("往redis中设置一个string类型的数据");
String string1 = jedis.set("key", "value");
System.out.println(string1);
System.out.println("获取刚才设置的值");
String getString = jedis.get("key");
System.out.println(getString);
System.out.println("=============判断值得长度=============");
Long long1 = jedis.strlen("key");
System.out.println(getString+"长度:"+long1);
System.out.println("=========getset=========");
String string = jedis.getSet("key", "sss");
System.out.println(string);
String set = jedis.getSet("key1", "v1");
System.out.println(set);
System.out.println("=============设置多个值=============");
String mset = jedis.mset("k1","v1","k2","v2");
System.out.println(mset);
List<String> mget = jedis.mget("k1","k2");
mget.forEach(System.out::println);
System.out.println("=============设置值的过期时间=============");
String setex = jedis.setex("k3", 10, "expire");
System.out.println(setex);
Long ttl = jedis.ttl("k3");
System.out.println(jedis.get("k3")+"还有:"+ttl+"s过期");
System.out.println("=============删除值=============");
Long del = jedis.del("k1");
System.out.println(del);
System.out.println("=============修改键名=============");
String rename = jedis.rename("k2", "k122");
System.out.println(rename);
System.out.println("=============清空数据=============");
String flushAll = jedis.flushAll();
System.out.println(flushAll);
jedis.close();
}
}
三、Jedis操作String
Jedis来操作String类型的方法基本都是和操作Key的方法一样,且使用jedis来操作redis的方法与redis的命令保持一致。
故在这一小节,只简单介绍一些方法,其余可以自行练习
public void testString2() {
Jedis jedis = jedisPool.getResource();
String set = jedis.set("msg", "hello");
System.out.println(set);
String string = jedis.get("msg");
System.out.println(string);
String mset = jedis.mset("key1","value1","key2","value2","key3","value3");
System.out.println(mset);
List<String> mget = jedis.mget("key1","key2","key3");
mget.forEach(System.out::println);
String all = jedis.flushAll();
System.out.println(all);
jedis.close();
}
四、Jedis操作Hash
在使用Hash数据类型的时候,在实际的开发过程中我们一般都是用hash类型来存储对象的数据的。存储对象的数据,一般都需要序列化与反序列化
这里我举个小例子,来测试操作Hash:
需求:需要利用Redis作为缓存来减轻关系型数据库的访问压力在高并发环境下,查询一条用户数据,如果MySQL或者Oracle中有则查询,将结果设置进Redis里,返回。否则直接查询Redis
4.1 创建对象实体
创建一个用户实体序列化实现Serializable接口
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String remark;
}
4.2 创建服务类,实现业务
@Service
@Slf4j
public class JedisServiceImpl {
@Autowired
private JedisPool jedisPool;
/**
* 对象Redis hash的操作进行存取
*
* 用户前端传入id 我们根据用户的id生成Redis的key 判断Redis的是否有Key
* 如果Key不存在,查询MySQL数据库,将查询的对象结果返回,并再次存储在Redis hash类型 如果Key存在,直接查询Redis数据库
*/
public User selectById(String id) {
String key = "User:" + id;
User user = new User();
Jedis jedis = jedisPool.getResource();
if (jedis.exists(key)) { // 存在的情况
log.info("查询Redis");
Map<String, String> map = jedis.hgetAll(key);
user.setId(map.get("id"));
user.setName(map.get("name"));
user.setRemark(map.get("remark"));
} else {// 不存在得情况
//1、先查询数据库中的数据
user.setId(id);
user.setName("赵安");
user.setRemark("在学习Redis");
log.info("查询的是Mysql数据库..." + user);
//2、再将查询结果存储到Redis中
Map<String, String> map = new HashMap<>();
map.put("id", user.getId());
map.put("name", user.getName());
map.put("remark", user.getRemark());
jedis.hset(key, map);
log.info("在MySQL中查询的数据存入Redis中...");
}
jedis.close();
return user;
}
}
4.3 编写测试类测试
@SpringBootTest
public class JedisHash {
@Autowired
private JedisServiceImpl jedisService;
@Autowired
private JedisPool jedisPool;
@Test
public void testHash() {
User user = jedisService.selectById("1001");
System.out.println(user);
}
}
4.4 执行结果
第一次执行结果—>
第二次查询结果—>
第二次查询,只要第一次查询到结果后,那么以后再查询都是从缓存Redis中查询