Redis
概念:
redis是一款高性能的NOSQL系列的非关系型数据库
安装:
解压直接可以使用:
redis.windows.conf
:配置文件
redis-cli.exe
:redis的客户端
redis-server.exe
:redis服务器端
命令操作
一、redis的数据结构:
1.redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构
2.value的数据结构:
1)字符串类型 String
2)哈希类型 hash :map格式
3)列表类型 list :linkedlist格式
4)集合类型 set
5)有序集合类型 sortedset
二、字符串类型 String
1.存储:
set key value
2.获取:
get key
3.删除:
del key
三、哈希类型 hash
1.存储:
hset key field value
2.获取:
hget key field
:获取指定的field对应的值
hgetall key
:获取所有的field和value
3.删除:
hdel key field
:删除指定的field,其对应的value也被删除掉
四、列表类型 list:可以添加一个元素到列表的头部(左边)或者尾部(右边)
1.添加:
lpush key value
:将元素加入列表的左边
rpush key value
:将元素加入列表的右边
2.获取:
lrange key start end
:范围获取
3.删除:
lpop key
:删除列表最左边的元素,并将元素返回
rpop key
:删除列表最右边的元素,并将元素返回
五、集合类型 set 不允许重复元素
1.存储:
sadd key value
2.获取:
smembers key
:获取set集合中所有元素
3.删除:
srem key value
:删除set集合中的某个元素
六、有序集合类型 sortedset 不允许重复元素,且元素有序
1.存储:
zadd key score value
2.获取:
zrange key start end
3.删除:
zren key value
七、通用命令
1.keys *:查询所有的键
2.type key:获取键对应的value的类型
3.del key:删除指定的key value
持久化
1.redis是一个内存数据库,当redis服务器重启,或者电脑重启,数据就会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
2.redis持久化机制:
1)RDB:默认方式,不需要进行配置,默认就是用这种机制
1.在一定的时间间隔中,检测key的变化情况,然后去持久化数据
after 900 sec (15 min) if at least 1 key changed
save 900 1
after 300 sec (5 min) if at least 10 keys changed
save 300 10
after 60 sec if at least 10000 keys changed
save 60 10000
2.重新启动redis服务器,并指定配置文件名称
PS D:\redis> .\redis-server.exe .\redis.windows.conf
2)AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
1.编辑redis.windows.conf文件
appendonly no(关闭AOF) ---> appendonly yes (开启AOF)
appendfsync always :每一次操作都进行持久化
appendfsync everysec :每隔一秒进行一次持久化
appendfsync no :不进行持久化
Java客户端 Jedis
Jedis:一款java操作redis数据库的工具。
使用步骤:
1.下载jedis的jar包
2.使用
//1.获取连接
Jedis jedis = new Jedis("localhost",6379);
//2.操作
jedis.set("username","zhangsan");
//3.关闭连接
jedis.close();
Jedis操作各种redis中的数据结构
1)字符串类型 String
set
get
2)哈希类型 hash :map格式
hset
hget
hgetAll
3)列表类型 list :linkedlist格式
lpush/rpush
lpop/rpop
4)集合类型 set
sadd
smember:获取所有元素
5)有序集合类型 sortedset
zadd
package cn.hu.jedis.test;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.List;
import java.util.Map;
import java.util.Set;
/*
jedis的测试类
*/
public class JedisTest {
/**
* 快速入门
*/
@Test
public void test1(){
//1.获取连接
Jedis jedis = new Jedis("localhost",6379);
//2.操作
jedis.set("username","zhangsan");
//3.关闭连接
jedis.close();
}
/**
* String 数据结构操作
*/
@Test
public void test2(){
//1.获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost" ,6379端口
//2.操作
//存储
jedis.set("username","zhangsan");
//获取
String username = jedis.get("username");
System.out.println(username);
//可以使用setex()方法存储可以指定过期时间的 key value
jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对
//3.关闭连接
jedis.close();
}
/**
* hash 数据结构操作
*/
@Test
public void test3(){
//1.获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost" ,6379端口
//2.操作
//存储hash
jedis.hset("user","name","lisi");
jedis.hset("user","age","23");
jedis.hset("user","gender","male");
//获取hash
String name = jedis.hget("user", "name");
System.out.println(name);
//获取hash的所有map中的数据
Map<String, String> user = jedis.hgetAll("user");
//keyset
Set<String> keySet = user.keySet();
for (String key : keySet) {
System.out.println(user.get(key));
}
//3.关闭连接
jedis.close();
}
/**
* list 数据结构操作
*/
@Test
public void test4(){
//1.获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost" ,6379端口
//2.操作
//list 存储
jedis.lpush("mylist","a","b","c");//从左边存
jedis.rpush("mylist","a","b","c");//从右边存
//list 范围获取
List<String> mylist = jedis.lrange("mylist", 0, -1);
System.out.println(mylist);
//list 弹出
String element = jedis.lpop("mylist");
System.out.println(element);
String mylist1 = jedis.rpop("mylist");
System.out.println(mylist1);
//list 范围获取
List<String> mylist2 = jedis.lrange("mylist", 0, -1);
System.out.println(mylist2);
//3.关闭连接
jedis.close();
}
/**
* set 数据结构操作
*/
@Test
public void test5(){
//1.获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost" ,6379端口
//2.操作
//set 存储
jedis.sadd("myset","java","c++","python");
//set 获取
Set<String> myset = jedis.smembers("myset");
System.out.println(myset);
//3.关闭连接
jedis.close();
}
/**
* sortedset 数据结构操作
*/
@Test
public void test6(){
//1.获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost" ,6379端口
//2.操作
//sortedset 存储
jedis.zadd("mysoetedset",3,"亚瑟");
jedis.zadd("mysoetedset",30,"后羿");
jedis.zadd("mysoetedset",13,"猴子");
//sortedset 获取
Set<String> mysoetedset = jedis.zrange("mysoetedset", 0, -1);
System.out.println(mysoetedset);
//3.关闭连接
jedis.close();
}
}
jedis连接池:JedisPool
使用:
1.创建JedisPool
连接池对象
2.调用方法getResource()
方法获取Jedis
连接
/**
* jedis连接池使用
*/
@Test
public void test0(){
//0.创建一个配置对象
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(10);
//1.创建jedis连接池对象
JedisPool pool=new JedisPool(config,"localhost",6379);
//2.获取连接
Jedis jedis = pool.getResource();
//3.使用
jedis.set("hehe","heihie");
//4.关闭 归还到连接池中
jedis.close();
}
案例
分析
前台页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script>
$(function () {
//发送ajax请求,加载所有省份的数据
$.get("provinceServlet",{},function (data) {
//[{"id":1,"name":"北京"},{"id":2,"name":"湖北"},
// {"id":3,"name":"上海"},{"id":4,"name":"陕西"},
// {"id":5,"name":"甘肃"}]
//1.获取select
var province = $("#province");
//2.遍历json数组
$(data).each(function () {
// "<p>this.id</p>"
//3.创建<option>
var option="<option name='"+this.id+"'>"+this.name+"</option>";
//4.调用select的append追加option
province.append(option);
});
},"json");
});
</script>
</head>
<body>
<select id="province">
<option>--请选择省份--</option>
</select>
</body>
</html>
servlet代码
package com.hu.web.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hu.domain.Province;
import com.hu.service.ProvinceService;
import com.hu.service.impl.ProvinceServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/provinceServlet")
public class ProvinceServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.调用service查询
ProvinceService service=new ProvinceServiceImpl();
List<Province> list = service.findAll();
//2.序列化list为json
ObjectMapper mapper=new ObjectMapper();
String json = mapper.writeValueAsString(list);
//System.out.println(json);
//3.响应结果
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(json);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
JDBCUtil
package com.hu.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
import javax.sql.DataSource;
public class JDBCUtils {
private static DataSource ds;
static{
try {
//2.加载配置文件
Properties pro=new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2.获取DateSource
ds= DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//获取连接池
public static DataSource getDateSource(){
return ds;
}
}
ProvinceService
package com.hu.service;
import com.hu.domain.Province;
import java.util.List;
public interface ProvinceService {
public List<Province> findAll();
}
ProvinceServiceImpl
package com.hu.service.impl;
import com.hu.dao.ProvinceDao;
import com.hu.dao.impl.ProvinceDaoImpl;
import com.hu.domain.Province;
import com.hu.service.ProvinceService;
import java.util.List;
public class ProvinceServiceImpl implements ProvinceService {
//声明Dao
private ProvinceDao dao=new ProvinceDaoImpl();
@Override
public List<Province> findAll() {
return dao.findAll();
}
}
ProvinceDao
package com.hu.dao;
import com.hu.domain.Province;
import java.util.List;
public interface ProvinceDao {
public List<Province> findAll();
}
ProvinceDaoImpl
package com.hu.dao.impl;
import com.hu.dao.ProvinceDao;
import com.hu.domain.Province;
import com.hu.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class ProvinceDaoImpl implements ProvinceDao {
//1.声明成员变量 jdbctemplement
private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDateSource());
@Override
public List<Province> findAll() {
//1.定义sql
String sql="select * from province";
//2.执行sql
List<Province> list = template.query(sql, new BeanPropertyRowMapper<Province>(Province.class));
return list;
}
}
Province
package com.hu.domain;
public class Province {
private int id;
private String name;
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;
}
}
使用redis缓存优化性能
注意:使用redis缓存一些不经常发生变化的数据。
数据库的数据一旦发生改变(数据库表执行了,增、删、改的相关操作,需要将redis缓存数据清空,再次存入),则需要更新缓存
在service对应的增删改方法中,将redis数据删除。
代码优化:
package com.hu.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hu.dao.ProvinceDao;
import com.hu.dao.impl.ProvinceDaoImpl;
import com.hu.domain.Province;
import com.hu.jedis.util.JedisPoolUtils;
import com.hu.service.ProvinceService;
import redis.clients.jedis.Jedis;
import java.util.List;
public class ProvinceServiceImpl implements ProvinceService {
//声明Dao
private ProvinceDao dao=new ProvinceDaoImpl();
@Override
public List<Province> findAll() {
return dao.findAll();
}
/**
* 使用redis缓存
* @return
*/
@Override
public String findAllJson() {
//1.先从redis中查询数据
//1.1获取redis客户端连接
Jedis jedis = JedisPoolUtils.getJedis();
String province_json = jedis.get("province");
//2.判断province_json是否为null
if(province_json==null||province_json.length()==0){
//redis中没有数据
System.out.println("redis中没有数据。。。查数据库");
//2.1从数据中查寻
List<Province> ps = dao.findAll();
//2.2将list序列化为json
ObjectMapper mapper=new ObjectMapper();
try {
province_json = mapper.writeValueAsString(ps);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//2.3将json数据存入到redis中
jedis.set("province",province_json);
//归还连接
jedis.close();
}else{
System.out.println(province_json);
System.out.println("redis中有数据。。。查询缓存");
}
return province_json;
}
}
package com.hu.web.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hu.domain.Province;
import com.hu.service.ProvinceService;
import com.hu.service.impl.ProvinceServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/provinceServlet")
public class ProvinceServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*//1.调用service查询
ProvinceService service=new ProvinceServiceImpl();
List<Province> list = service.findAll();
//2.序列化list为json
ObjectMapper mapper=new ObjectMapper();
String json = mapper.writeValueAsString(list);
//System.out.println(json);*/
//1.调用service查询
ProvinceService service=new ProvinceServiceImpl();
String json = service.findAllJson();
//3.响应结果
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
package com.hu.jedis.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class JedisPoolUtils {
private static JedisPool jedisPool;
static{
//读取配置文件
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
//创建Properties对象
Properties properties=new Properties();
//关联文件
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//获取数据,设置到JedisPoolConfig中
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(properties.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle")));
//初始化JedisPool对象
jedisPool=new JedisPool(config,properties.getProperty("host"), Integer.parseInt(properties.getProperty("port")));
}
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
结果: