redis

Redis

1. 概念: redis是一款高性能的NOSQL系列的非关系型数据库

	1.1.什么是NOSQL
		NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。
		1.1.1.	NOSQL和关系型数据库比较
			优点:
				1)成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相比关系型数据库价格便宜。
				2)查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。
				3)存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
				4)扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。

			缺点:
				1)维护的工具和资料有限,因为nosql是属于新的技术,不能和关系型数据库10几年的技术同日而语。
				2)不提供对sql的支持,如果不支持sql这样的工业标准,将产生一定用户的学习和使用成本。
				3)不提供关系型数据库对事务的处理。

		1.1.2.	非关系型数据库的优势:
			1)性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
			2)可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

		1.1.3.	关系型数据库的优势:
			1)复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
			2)事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库,对方的优势就是自己的弱势,反之亦然。

		1.1.4.	总结
			关系型数据库与NoSQL数据库并非对立而是互补的关系,即通常情况下使用关系型数据库,在适合使用NoSQL的时候使用NoSQL数据库,
			让NoSQL数据库对关系型数据库的不足进行弥补。
			一般会将数据存储在关系型数据库中,在nosql数据库中备份存储关系型数据库的数据
	1.3 什么是Redis
		Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
			1) 字符串类型 string
			2) 哈希类型 hash
			3) 列表类型 list
			4) 集合类型 set
			5) 有序集合类型 sortedset
		1.3.1 redis的应用场景
			•	缓存(数据查询、短连接、新闻内容、商品内容等等)
			•	聊天室的在线好友列表
			•	任务队列。(秒杀、抢购、12306等等)
			•	应用排行榜
			•	网站访问统计
			•	数据过期处理(可以精确到毫秒
			•	分布式集群架构中的session分离

2. 命令操作

1. redis的数据结构:

		* redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构
			* value的数据结构:
				1) 字符串类型 string
				2) 哈希类型 hash : map格式  
				3) 列表类型 list : linkedlist格式。支持重复元素
				4) 集合类型 set  : 不允许重复元素
				5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序

2. 字符串类型 string

		1. 存储: set key value
			set username zhangsan

		2. 获取: get key
			  get username
		
		3. 删除: del key
		   del age

3. 哈希类型 hash

		1. 存储: hset key field value
			 hset myhash username lisi
			 
		2. 获取: 
			* hget key field: 获取指定的field对应的值
				hget myhash username
				
			* hgetall key:获取所有的field和value
				 hgetall myhash
			
		3. 删除: hdel key field
		 hdel myhash username

4. 列表类型 list

可以添加一个元素到列表的头部(左边)或者尾部(右边)
		1. 添加:
			1. lpush key value: 将元素加入列表左表
				
			2. rpush key value:将元素加入列表右边
				
				lpush myList a
				rpush myList c
		
		2. 获取:
			* lrange key start end :范围获取
			 lrange myList 0 -1 //-1表示所有
			
		3. 删除:
			* lpop key: 删除列表最左边的元素,并将元素返回
			* rpop key: 删除列表最右边的元素,并将元素返回

5. 集合类型 set

 不允许重复元素
		1. 存储:sadd key value
			 sadd myset a
			(integer) 1
			127.0.0.1:6379> sadd myset a
			(integer) 0
		2. 获取:smembers key:获取set集合中所有元素
			 smembers myset
			
		3. 删除:srem key value:删除set集合中的某个元素	
			srem myset a

6. 有序集合类型 sortedset

不允许重复元素,且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

		1. 存储:zadd key score value
			zadd mysort 60 zhangsan
			
			 zadd mysort 50 lisi
			
			 zadd mysort 80 wangwu
		
		2. 获取:zrange key start end [withscores]
			zrange mysort 0 -1
		
			zrange mysort 0 -1 withscores
			1) "zhangsan"
			2) "60"
			3) "wangwu"
			4) "80"
			5) "lisi"
			6) "500"
		3. 删除:zrem key value
		    zrem mysort lisi
			

	7. 通用命令
		1. keys * : 查询所有的键
		2. type key : 获取键对应的value的类型
		3. del key:删除指定的key value

持久化

	1. redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
	2. redis持久化机制:
		1. RDB:默认方式,不需要进行配置,默认就使用这种机制
			* 在一定的间隔时间中,检测key的变化情况,然后持久化数据
			1. 编辑redis.windwos.conf文件
				#   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服务器,并指定配置文件名称
				D:安装目录>redis-server.exe redis.windows.conf	
			
		2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
			1. 编辑redis.windwos.conf文件
				appendonly no(关闭aof) --> appendonly yes (开启aof)
				
				# appendfsync always : 每一次操作都进行持久化
				appendfsync everysec : 每隔一秒进行一次持久化
				# appendfsync no	 : 不进行持久化

Java客户端 Jedis

	* Jedis: 一款java操作redis数据库的工具.
	* 使用步骤:
		1. 下载jedis的jar包
		2. 使用

使用方法基本和redis客户端一致,先获取jedis连接,然后再使用对应类型的增删改查方法

			//1. 获取连接
    		Jedis jedis = new Jedis("localhost",6379);
   			//2. 操作
   			jedis.set("username","zhangsan");
    		//3. 关闭连接
    		jedis.close();


    		* 连接池工具类
			public class JedisPoolUtils {

			    private static JedisPool jedisPool;
			
			    static{
			        //读取配置文件
			        InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
			        //创建Properties对象
			        Properties pro = new Properties();
			        //关联文件
			        try {
			            pro.load(is);
			        } catch (IOException e) {
			            e.printStackTrace();
			        }
			        //获取数据,设置到JedisPoolConfig中
			        JedisPoolConfig config = new JedisPoolConfig();
			        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
			        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
			
			        //初始化JedisPool
			       jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port"))); 
			         }  
			         /**  * 获取连接方法  *
			         /public static Jedis getJedis(){ return jedisPool.getResource();
			          }
			          }

案例

案例需求:
	1. 提供index.html页面,页面中有一个省份 下拉列表
	2. 当 页面加载完成后 发送ajax请求,加载所有省份

html主要代码:

<script>


        $(function () {
        //刷新按钮的单击方法
            $("#bt").click(function () {
                $.get("provinceServlet", {"flag": false}, function (data) {
                    //[{"id":1,"name":"北京"},{"id":2,"name":"上海"},{"id":3,"name":"广州"},{"id":4,"name":"陕西"}]

                    //1.获取select
                    var province = $("#province");
                    //清除之前的option
                    $("option").remove();
                    //添加默认option
                    var mianoption = "<option >--请选择省份--</option>";
                    province.append(mianoption);
                    //2.遍历json数组
                    $(data).each(function () {
                        //3.创建<option>
                        var option = "<option name='" + this.id + "'>" + this.name + "</option>";
                        //4.调用select的append追加option
                        province.append(option);
                    });
                });
            })
        });

        $(function () {

            //发送ajax请求,加载所有省份数据
            $.get("provinceServlet", {"flag": true}, function (data) {
                //[{"id":1,"name":"北京"},{"id":2,"name":"上海"},{"id":3,"name":"广州"},{"id":4,"name":"陕西"}]

                //1.获取select
                var province = $("#province");
                //2.遍历json数组
                $(data).each(function () {
                    //3.创建<option>
                    var option = "<option name='" + this.id + "'>" + this.name + "</option>";

                    //4.调用select的append追加option
                    province.append(option);
                });
            });
        });


    </script>

servlet主要代码:

 //1.调用service查询
        String flag = request.getParameter("flag");
        ProvinceService service = new ProvinceServiceImpl();
        String json = service.findAllJson(Boolean.parseBoolean(flag));


        System.out.println(json);
        //3.响应结果
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(json);

service主要代码:

 public String findAllJson(boolean flag) {
        //1.先从redis中查询数据
        //1.1获取redis客户端连接

        Jedis jedis = JedisPoolUtils.getJedis();
        String province_json=null;
        if(flag){

          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("redis中有数据,查询缓存...");
            }

        }
        else {
        jedis.del("province");
            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();

        }


        return province_json;
    }
* 注意:使用redis缓存一些不经常发生变化的数据。
	* 数据库的数据一旦发生改变,则需要更新缓存。
		* 数据库的表执行 增删改的相关操作,需要将redis缓存数据情况,再次存入
		* 在service对应的增删改方法中,将redis数据删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值