文档章节

redis(jedis)相关API ,实现与关系型数据库相似的功能

alexgaoyh
 alexgaoyh
发布于 2015/06/04 14:09
字数 2101
阅读 1481
收藏 17

    本文简单介绍了在使用jedis操作redis这个nosql数据库过程中,总结的一些问题,例如使用jedis实现形如关系型数据库的数据关联关系处理。

    分三个层面:

        1:单表数据处理,新增一行数据到数据库中,如果存在主键id是自增情况的条件下,如何新增数据集合到数据库行数据;

        2:一对多关联关系,本文举例形如---学生&&成绩; 一个学生包含多个学科的成绩,某一个学科的的成绩属于某个学生;

        3:多对多关联关系,本文举例例如---文章&&标签; 一篇文章可以添加多个标签,某一个标签可以被包含于多个文章中;

        整体代码链接已经上传git,可以在git上查看: 

http://git.oschina.net/alexgaoyh/MutiModule-parent/blob/master/MutiModule-service/src/test/java/com/alexgaoyh/MutiModule/service/unJunit/redis/test2/TestCase.java

    1:单表数据处理

/**
	 * [向Redis list压入ID而不是实际的数据]
		在上面的例子里 ,我们将“对象”(此例中是简单消息)直接压入Redis list,但通常不应这么做,
		由于对象可能被多次引用:例如在一个list中维护其时间顺序,在一个集合中保存它的类别,只要有必要,它还会出现在其他list中,等等。
		让我们回到reddit.com的例子,将用户提交的链接(新闻)添加到list中,有更可靠的方法如下所示:
		$ redis-cli incr next.news.id
		(integer) 1
		$ redis-cli set news:1:title "Redis is simple"
		OK
		$ redis-cli set news:1:url "http://code.google.com/p/redis"
		OK
		$ redis-cli lpush submitted.news 1
		OK
		我们自增一个key,很容易得到一个独一无二的自增ID,然后通过此ID创建对象–为对象的每个字段设置一个key。最后将新对象的ID压入submitted.news list。
		这只是牛刀小试。在命令参考文档中可以读到所有和list有关的命令。你可以删除元素,旋转list,根据索引获取和设置元素,当然也可以用LLEN得到list的长度。
		
	 *
	 * 形如关系型数据库的单表一行数据(主键id为自增)	
	 * 自定义一个自增的id ,	jedis.incr(key),这个key可以形如mysql这种关系型数据库的自增主键id
	 * 形如关系型数据库的一行数据,自增主键id:jedis.incr(key) 他对应的数据内容:jedis.get("ad:adinfo:" + adInfoId + ":title") jedis.get("ad:adinfo:" + adInfoId + ":url")
	 * 这样,在查询这张‘表’结构下的所有数据时,可以匹配查询即可
	 */
	public static void testListStrUsage() {
		String title = "alexgaoyh";
		String url = "http://git.oschina.net/alexgaoyh";
		Jedis jedis = RedisUtil.getJedis(IP, PORT);

		long adInfoId = jedis.incr("ad:adinfo:next.id");
		jedis.set("ad:adinfo:" + adInfoId + ":title", title);
		jedis.set("ad:adinfo:" + adInfoId + ":url", url);
		jedis.lpush("ad:adinfo", String.valueOf(adInfoId));

		String resultTitle = jedis.get("ad:adinfo:" + adInfoId + ":title");
		String resultUrl = jedis.get("ad:adinfo:" + adInfoId + ":url");
		List<String> ids = jedis.lrange("ad:adinfo", 0, -1);
		System.out.println(resultTitle);
		System.out.println(resultUrl);
		System.out.println(ids);

		/**
		 * dbsize返回的是所有key的数目,包括已经过期的, 而redis-cli keys "*"查询得到的是有效的key数目
		 */
		System.out.println(jedis.dbSize());

		//清空所有的key
		jedis.flushAll();
	}



 


    2:一对多关联关系

/**
	 * sort list
	 * LIST结合hash的排序
	 * 根据指定的SortingParams排序方式,将符合条件的数据格式进行返回
	 * 关联关系处理,
	 * 可以理解为studentlist代表学生的整体数据集合
	 * hset方法,可以将某个学生user:id下的某个域(学科)的成绩(value)进行数据保存
	 * 根据匹配条件,将相对应的成绩进行输出
	 */
	public static void testSort2() {
		Jedis jedis = RedisUtil.getJedis(IP, PORT);
		jedis.del("user:66", "user:55", "user:33", "user:22", "user:11", "userlist");
		jedis.lpush("studentlist", "33");
		jedis.lpush("studentlist", "22");
		jedis.lpush("studentlist", "55");
		jedis.lpush("studentlist", "11");

		//将哈希表 key 中的域 field 的值设为 value 。 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。 如果域 field 已经存在于哈希表中,旧值将被覆盖。
		jedis.hset("user:66", "math", "66");
		jedis.hset("user:55", "math", "55");
		jedis.hset("user:33", "math", "33");
		jedis.hset("user:22", "math", "22");
		jedis.hset("user:11", "math", "11");//学生user:编号,在field域(某个学科-数学/英语)上的成绩(value)
		jedis.hset("user:11", "english", "110");
		jedis.hset("user:22", "english", "220");
		jedis.hset("user:33", "english", "330");
		jedis.hset("user:55", "english", "550");
		jedis.hset("user:66", "english", "660");

		SortingParams sortingParameters = new SortingParams();
		// 符号 "->" 用于分割哈希表的键名(key name)和索引域(hash field),格式为 "key->field" 。
		sortingParameters.desc();
		sortingParameters.get("user:*->math");
		sortingParameters.get("user:*->english");
		List<String> result = jedis.sort("studentlist", sortingParameters);
		for (String item : result) {
			System.out.println("item...." + item);
		}
		/**
		 * 对应的redis客户端命令是:sort ml get user*->name sort ml get user:*->name get
		 * user:*->add
		 */
	}

/**
        * sort set
        * SET结合String的排序
        * REL关系相关处理操作   好友列表 好友信息 好友成绩数据信息添加即相应的数据输出
        * 输出好友id,好友的详细信息,好友的对应成绩
        */
        public static void testSort3() {
              Jedis jedis = RedisUtil. getJedis( IP, PORT);
              jedis.del( "tom:friend:list" , "score:uid:123" , "score:uid:456" ,
                            "score:uid:789" , "score:uid:101" , "uid:123" , "uid:456" ,
                            "uid:789" , "uid:101" );

              jedis.sadd( "tom:friend:list" , "123" ); // tom的好友列表
              jedis.sadd( "tom:friend:list" , "456" );
              jedis.sadd( "tom:friend:list" , "789" );
              jedis.sadd( "tom:friend:list" , "101" );

              jedis.set( "score:uid:123" , "1000" ); // 好友对应的成绩
              jedis.set( "score:uid:456" , "6000" );
              jedis.set( "score:uid:789" , "100" );
              jedis.set( "score:uid:101" , "5999" );

              jedis.set( "uid:123" , "{'uid':123,'name':'lucy'}" ); // 好友的详细信息
              jedis.set( "uid:456" , "{'uid':456,'name':'jack'}" );
              jedis.set( "uid:789" , "{'uid':789,'name':'jay'}" );
              jedis.set( "uid:101" , "{'uid':101,'name':'jolin'}" );

              SortingParams sortingParameters = new SortingParams();

              sortingParameters.desc();
               // sortingParameters.limit(0, 2);
               // 注意GET操作是有序的,GET user_name_* GET user_password_*
               // 和 GET user_password_* GET user_name_*返回的结果位置不同
              sortingParameters.get( "#" );// GET 还有一个特殊的规则—— "GET #"
                                                               // ,用于获取被排序对象(tom:friend:list)(我们这里的例子是 user_id )的当前元素。
              sortingParameters.get( "uid:*" );
              sortingParameters.get( "score:uid:*" );
              sortingParameters.by( "score:uid:*" );
               // 对应的 redis 命令是./redis -cli sort tom:friend:list by score:uid:* get # get
               // uid :* get score:uid:*
              List<String> result = jedis.sort( "tom:friend:list" , sortingParameters);
               for (String item : result) {
                     System. out .println("item..." + item);
              }

       }



其中需要注意 sortingParameters.get("#");

GET 还有一个特殊的规则—— "GET #" 用于获取被排序对象(tom:friend:list)(我们这里的例子是 user_id )的当前元素。



     3:多对多关联关系

    

/**
	 * 下面是一个简单的方案:对每个想加标签的对象,用一个标签ID集合与之关联,并且对每个已有的标签,一组对象ID与之关联。 例如假设我们的新闻ID
	 * 1000被加了三个标签tag 1,2,5和77,就可以设置下面两个集合: 
	 * $ redis-cli sadd news:1000:tags 1
	 * (integer) 1 
	 * $ redis-cli sadd news:1000:tags 2 
	 * (integer) 1 
	 * $ redis-cli sadd news:1000:tags 5 
	 * (integer) 1 
	 * $ redis-cli sadd news:1000:tags 77
	 * (integer) 1 
	 * $ redis-cli sadd tag:1:objects 1000 
	 * (integer) 1 
	 * $ redis-cli sadd tag:2:objects 1000 
	 * (integer) 1 
	 * $ redis-cli sadd tag:5:objects 1000
	 * (integer) 1 
	 * $ redis-cli sadd tag:77:objects 1000 
	 * (integer) 1
	 * 要获取一个对象的所有标签,如此简单: 
	 * $ redis-cli smembers news:1000:tags 
	 * 1.5		2.1		3.77	4.2 
	 *  而有些看上去并不简单的操作仍然能使用相应的Redis命令轻松实现。
	 *  例如我们也许想获得一份同时拥有标签1, 2,10和27的对象列表。这可以用SINTER命令来做,他可以在不同集合之间取出交集。
	 *  因此为达目的我们只需: $ redis-cli sinter tag:1:objects tag:2:objects tag:10:objects tag:27:objects ... no result
	 * in our dataset composed of just one object ...
	 * 在命令参考文档中可以找到和集合相关的其他命令,令人感兴趣的一抓一大把。一定要留意SORT命令,Redis集合和list都是可排序的。
	 * 
	 * 关系型数据库双向关联操作  一个文章对应多个标签,一个标签可以被多个文章关联
	 * 多对多的数据库表结构
	 */
	
	public static void testSetUsage() {
		Jedis jedis = RedisUtil.getJedis(IP, PORT);
		
		//某个文章包含的标签
		jedis.sadd("zhongsou:news:1000:tags", "1");
		jedis.sadd("zhongsou:news:1000:tags", "2");
		jedis.sadd("zhongsou:news:1000:tags", "5");
		jedis.sadd("zhongsou:news:1000:tags", "77");
		jedis.sadd("zhongsou:news:2000:tags", "1");
		jedis.sadd("zhongsou:news:2000:tags", "2");
		jedis.sadd("zhongsou:news:2000:tags", "5");
		jedis.sadd("zhongsou:news:2000:tags", "77");
		jedis.sadd("zhongsou:news:3000:tags", "2");
		jedis.sadd("zhongsou:news:4000:tags", "77");
		jedis.sadd("zhongsou:news:5000:tags", "1");
		jedis.sadd("zhongsou:news:6000:tags", "5");

		//某个标签包含的对应的文章id
		jedis.sadd("zhongsou:tag:1:objects", 1000 + "");
		jedis.sadd("zhongsou:tag:2:objects", 1000 + "");
		jedis.sadd("zhongsou:tag:5:objects", 1000 + "");
		jedis.sadd("zhongsou:tag:77:objects", 1000 + "");

		jedis.sadd("zhongsou:tag:1:objects", 2000 + "");
		jedis.sadd("zhongsou:tag:2:objects", 2000 + "");
		jedis.sadd("zhongsou:tag:5:objects", 2000 + "");
		jedis.sadd("zhongsou:tag:77:objects", 2000 + "");

		//返回一个集合的全部成员,该集合是所有给定集合的交集
		//这四个标签全部都被包含的文章id集合
		Set<String> sets = jedis.sinter("zhongsou:tag:1:objects",
				"zhongsou:tag:2:objects", "zhongsou:tag:5:objects",
				"zhongsou:tag:77:objects");
		System.out.println(sets);
		jedis.flushAll();
	}



© 著作权归作者所有

共有 人打赏支持
alexgaoyh

alexgaoyh

粉丝 76
博文 82
码字总数 65212
作品 1
郑州
后端工程师
私信 提问
java如何操作非关系型数据库redis(-)

redis简单介绍: 是一种Nosql数据库,Nosql全称是Not Only SQL,是一种不同于关系型数据库的数据库管理系统设计方式。对NoSQL最普遍的解释是“非关系型的”,强调Key-Value Stores和文档数据...

WYDPH
2012/09/19
0
1
Redis应用学习(三)——Jedis客户端的简单使用介绍

Redis的Java客户端程序——Jedis 1. 在Redis的安装目录中redis-cli是一个Redis的Shell语言写的客户端,通过运行该客户端就可以实现一系列Redis操作,而如果要使用Java语言的Redis客户端,就必...

江左煤郎
2018/10/27
0
0
redis系列(一)- 安装与启动

redis系列文章: redis系列(一)- 安装与启动 redis系列(二)- 语法与命令 一、Redis介绍 Redis是NoSql的一种,在弄清楚Redis是个什么玩意之前,先了解下NoSql是什么。 1、什么是NoSql NoS...

CSDN_LQR
2017/09/27
0
0
redis系列(一)- 安装与启动

redis系列文章: redis系列(一)- 安装与启动 redis系列(二)- 语法与命令 一、Redis介绍 Redis是NoSql的一种,在弄清楚Redis是个什么玩意之前,先了解下NoSql是什么。 1、什么是NoSql NoS...

CSDN_LQR
2017/09/27
0
0
spring boot 1.5.9 整合redis

上一篇博客:spring boot 1.5.4 集成Swagger2构建Restful API(十八) Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库。 redis官网:https...

wyait
2017/12/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

js中原型模式

原型模式就是用克隆对象来创建对象的,在es6中提供了Object.create方法来克隆对象 在不支持该方法的浏览器中,可以使用以下代码: Object.create = Object.create || function (obj) { ...

莫西摩西
5分钟前
0
0
ORACLE插入insert带where条件

ORACLE插入带条件 insert into THIRD_PAYEE_ACCOUNT_DETAIL t (id, collection_mode, t.store_code) select Third_Payee_Account_Detail_Seq.Nextval,'006','A05K' from dual where not......

Cobbage
14分钟前
0
0
分享几张Java架构大牛总结的架构知识脑图

前言 系统架构师是一个既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物。一个架构师得需要足够的想像力,能把各种目标需求进行不同维度的扩展,为目标客户...

Java-飞鱼
22分钟前
0
0
2019BATJ面试题详解:MyBatis+MySQL+Spring+Redis+多线程

这里为大家分享一些面试的一手资料,供大家迎接接下来的金三银四跳槽季 Spring Spring 概述 什么是spring? 使用Spring框架的好处是什么? Spring由哪些模块组成? 解释AOP模块 Spring配置文件...

别打我会飞
25分钟前
0
0
首场百度大脑开放日来袭 | 全新开放24项AI技术

活动当天,百度AI技术生态部总经理喻友平,就百度大脑平台与生态进行了全面的详解,同时展示了百度大脑开放平台Q1核心升级内容,包括语音技术、视觉技术、自然语言处理、知识图谱等通用AI能力...

PaddleWeekly
26分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部