jedis是redis的java版本的客户端实现,本文通过一些web请求&响应的实例展示了jedis的基本用法;

开始编码前我们先把环境准备好,总共两个server,对应两个docker容器:

  1. redis,采用redis的3.2.8版本,本次实战用的是redis单机;
  2. tomcat,采用7.0.77-jre8版本,由于要支持在线部署,所以tomcat镜像对官方镜像做了少量定制,详情请参照《实战docker,编写Dockerfile定制tomcat镜像,实现web应用在线部署》,这里可以不用自己动手做,在hub.docker.com下载bolingcavalry/online_deploy_tomcat:0.0.1镜像即可,为了支持在线部署,请在本地maven环境的settings.xml中的servers节点内增加一个server节点,内容如下:
  1. <server>
  2. <id>tomcat7</id>
  3. <username>bolingcavalry</username>
  4. <password>bolingcavalrypswd</password>
  5. </server>

以上只是对环境做个介绍,不需要自己动手去挨个构建,通过一个docker-compose.yml即可搭建成功,docker-compose.yml文件内容如下:

  1. version: '2'
  2. services:
  3. redis001:
  4. image: daocloud.io/library/redis:3.2.8
  5. restart: always
  6. tomcat001:
  7. image: bolingcavalry/online_deploy_tomcat:0.0.1
  8. links:
  9. - redis001:redishost
  10. ports:
  11. - "8080:8080"
  12. environment:
  13. TOMCAT_SERVER_ID: tomcat_server_001
  14. restart: always

打开控制台,在docker-compose.yml文件所在目录下执行以下命令:

  1. docker-compose up -d

执行完毕后环境就搭建成功了,在浏览器输入"localhost:8080"可以看到熟悉的tomcat首页:

[外链图片转存中...(img-dXCPA2Gd-1568682376493)]

环境OK了,可以开始编码了,源代码的git地址是git@github.com:zq2599/blog_demos.git,里面有多个工程,本篇用到的工程是redisdemo,如下图红框所示:

这是个maven工程,首先看下maven依赖,pom中的依赖除了jedis,还要加上spring,jstl,common等常用库,如下:

  1. <dependency>
  2. <groupId>junit</groupId>
  3. <artifactId>junit</artifactId>
  4. <version>4.11</version>
  5. <!-- 表示开发的时候引入,发布的时候不会加载此包 -->
  6. <scope>test</scope>
  7. </dependency>
  8. <!-- spring核心包 -->
  9. <dependency>
  10. <groupId>org.springframework</groupId>
  11. <artifactId>spring-core</artifactId>
  12. <version>${spring.version}</version>
  13. </dependency>
  14. <dependency>
  15. <groupId>org.springframework</groupId>
  16. <artifactId>spring-web</artifactId>
  17. <version>${spring.version}</version>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework</groupId>
  21. <artifactId>spring-oxm</artifactId>
  22. <version>${spring.version}</version>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework</groupId>
  26. <artifactId>spring-tx</artifactId>
  27. <version>${spring.version}</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework</groupId>
  31. <artifactId>spring-jdbc</artifactId>
  32. <version>${spring.version}</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework</groupId>
  36. <artifactId>spring-webmvc</artifactId>
  37. <version>${spring.version}</version>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.springframework</groupId>
  41. <artifactId>spring-aop</artifactId>
  42. <version>${spring.version}</version>
  43. </dependency>
  44. <dependency>
  45. <groupId>org.springframework</groupId>
  46. <artifactId>spring-context-support</artifactId>
  47. <version>${spring.version}</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>org.springframework</groupId>
  51. <artifactId>spring-test</artifactId>
  52. <version>${spring.version}</version>
  53. </dependency>
  54. <!-- 导入java ee jar 包 -->
  55. <dependency>
  56. <groupId>javax</groupId>
  57. <artifactId>javaee-api</artifactId>
  58. <version>7.0</version>
  59. </dependency>
  60. <!-- JSTL标签类 -->
  61. <dependency>
  62. <groupId>jstl</groupId>
  63. <artifactId>jstl</artifactId>
  64. <version>1.2</version>
  65. </dependency>
  66. <!-- 映入JSON -->
  67. <dependency>
  68. <groupId>org.codehaus.jackson</groupId>
  69. <artifactId>jackson-mapper-asl</artifactId>
  70. <version>1.9.13</version>
  71. </dependency>
  72. <!-- 上传组件包 -->
  73. <dependency>
  74. <groupId>commons-fileupload</groupId>
  75. <artifactId>commons-fileupload</artifactId>
  76. <version>1.3.1</version>
  77. </dependency>
  78. <dependency>
  79. <groupId>commons-io</groupId>
  80. <artifactId>commons-io</artifactId>
  81. <version>2.4</version>
  82. </dependency>
  83. <dependency>
  84. <groupId>commons-codec</groupId>
  85. <artifactId>commons-codec</artifactId>
  86. <version>1.9</version>
  87. </dependency>
  88. <!-- redis -->
  89. <dependency>
  90. <groupId>redis.clients</groupId>
  91. <artifactId>jedis</artifactId>
  92. <version>2.9.0</version>
  93. </dependency>

然后是web.xml中的配置,包括spring mvc配置和扩展配置文件(spring-extends.xml):

  1. <!-- Spring的配置文件 -->
  2. <context-param>
  3. <param-name>contextConfigLocation</param-name>
  4. <param-value>classpath:spring-extends.xml</param-value>
  5. </context-param>
  6. <!-- 编码过滤器 -->
  7. <filter>
  8. <filter-name>encodingFilter</filter-name>
  9. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  10. <async-supported>true</async-supported>
  11. <init-param>
  12. <param-name>encoding</param-name>
  13. <param-value>UTF-8</param-value>
  14. </init-param>
  15. </filter>
  16. <filter-mapping>
  17. <filter-name>encodingFilter</filter-name>
  18. <url-pattern>/*</url-pattern>
  19. </filter-mapping>
  20. <!-- Spring监听器 -->
  21. <listener>
  22. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  23. </listener>
  24. <!-- 防止Spring内存溢出监听器 -->
  25. <listener>
  26. <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  27. </listener>
  28. <!-- Spring MVC servlet -->
  29. <servlet>
  30. <servlet-name>SpringMVC</servlet-name>
  31. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  32. <init-param>
  33. <param-name>contextConfigLocation</param-name>
  34. <param-value>classpath:spring-mvc.xml</param-value>
  35. </init-param>
  36. <load-on-startup>1</load-on-startup>
  37. <async-supported>true</async-supported>
  38. </servlet>
  39. <servlet-mapping>
  40. <servlet-name>SpringMVC</servlet-name>
  41. <url-pattern>/</url-pattern>
  42. </servlet-mapping>

接下来就是java编码了,由于web请求是多线程并发进行的,多个线程会同时使用redis服务,所以我们使用jedis的连接池JedisPool来为并发请求同时提供jedis服务的实例;

连接池一个就够了,所以这里创建了一个单例的类RedisPool,它的功能如下:

实例化一个Jedis资源池对象,也就是JedisPool;

为业务线程提供获取Jedis和归还Jedis的服务;

接下来我们看一下RedisPool的关键代码,包括实例化,JedisPool创建,获取Jedis,归还Jedis四个部分:

RedisPool的实例化:

  1. public static RedisPool getInstance(){
  2. if(null==instance) {
  3. synchronized (RedisPool.class){
  4. if(null==instance){
  5. instance = new RedisPool();
  6. }
  7. }
  8. }
  9. return instance;
  10. }

下面时资源池的初始化代码,注意红框部分的ADDR参数是redis服务器的ip,本例中要连接的是docker 容器,所以ADDR的值用的是"redishost",这个和tomcat容器启动时的link参数中的redis容器的别名一致:

下面是getJedis方法,从资源池取出一个Jedis实例给业务线程,由于jedisPool.getResource方法是线程安全的,所以getJedis()可以被多个线程同时调用,不用锁操作:

  1. public Jedis getJedis(){
  2. try {
  3. if(null!=jedisPool){
  4. Jedis jedis = jedisPool.getResource();
  5. return jedis;
  6. }else{
  7. return null;
  8. }
  9. } catch (Exception e) {
  10. e.printStackTrace();
  11. return null;
  12. }
  13. }

下面是业务线程用完Jedis实例后,归还给资源池时调用的方法,注意,本次使用的jedis是2.9.0版本,所以继续使用jedisPool.returnResource,jedis3.0版本之后就要用新的方法来归还到资源池了:

  1. public void returnResource(final Jedis jedis){
  2. if(jedis!=null){
  3. //jedis.close()取代jedisPool.returnResource(jedis)方法将3.0版本开始
  4. jedisPool.returnResource(jedis);
  5. }
  6. }

写完了RedisPool,就解决了Jedis的来源问题,接下来我们看下如何使用Jedis:

本文只是入门学习,所以只展示了部分Jedis服务,通过RedisService接口对外提供,API如下:

  1. /**
  2. * string操作,常规设置key-value
  3. * @param key
  4. * @param value
  5. */
  6. void strSet(String key, String value);
  7. /**
  8. * string操作,常规通过key获取value
  9. * @param key
  10. * @return
  11. */
  12. String setGet(String key);
  13. /**
  14. * list操作,尾部追加数据
  15. * @param key
  16. * @param value
  17. */
  18. void listAppend(String key, String value);
  19. /**
  20. * list操作,获取说有数据
  21. */
  22. List<String> listGetAll(String key);
  23. /**
  24. * 指定键值在redis中是否存在
  25. * @param key
  26. * @return
  27. */
  28. boolean exists(String key);

具体的实现在RedisServiceImpl中,我们挑几个看看:

  1. @Override
  2. public void strSet(String key, String value) {
  3. Jedis jedis = borrowJedis();
  4. if(null!=jedis){
  5. jedis.set(key, value);
  6. }
  7. returnJedis(jedis);
  8. }
  9. @Override
  10. public String setGet(String key) {
  11. Jedis jedis = borrowJedis();
  12. if(null!=jedis){
  13. String value = jedis.get(key);
  14. returnJedis(jedis);
  15. return value;
  16. }
  17. return null;
  18. }
  19. @Override
  20. public void listAppend(String key, String value) {
  21. Jedis jedis = borrowJedis();
  22. if(null!=jedis){
  23. jedis.rpush(key, value);
  24. returnJedis(jedis);
  25. }
  26. }
  27. @Override
  28. public List<String> listGetAll(String key) {
  29. List<String> list = null;
  30. Jedis jedis = borrowJedis();
  31. if(null!=jedis){
  32. list = jedis.lrange(key, 0, -1);
  33. returnJedis(jedis);
  34. }
  35. return null==list ? new ArrayList() : list;
  36. }

可以发现,Jedis提供的api与redis客户端上的命令是很像的,例如jedis.get,jedis.lrange等等,基本上会操作命令行就能找到对应的api了。

再看看上次的对RedisService的调用场景,本例中用的是spring mvc,所以我们先看下RedisController:

下面四个方法代表了四个url入口:

  1. @RequestMapping("/simpleset")
  2. public String simpleset(HttpServletRequest request, Model model) {
  3. addCommon(model);
  4. return "simple_set";
  5. }
  6. @RequestMapping("/simpleget")
  7. public String simpleget(HttpServletRequest request, Model model) {
  8. addCommon(model);
  9. return "simple_get";
  10. }
  11. @RequestMapping("/listappend")
  12. public String listappend(HttpServletRequest request, Model model) {
  13. addCommon(model);
  14. return "list_append";
  15. }
  16. @RequestMapping("/listgetall")
  17. public String listgetall(HttpServletRequest request, Model model) {
  18. addCommon(model);
  19. return "list_get_all";
  20. }

以第一个simpleset为例,在浏览器中输入http://localhost:8080/redisdemo/simpleset,对应的simpleset方法会被调用,打开simple_get.jsp,如下图:

输入了key,value,点击提交后,由于form中指定了提交地址是strget,所以RedisController的get方法会被调用:

  1. @RequestMapping("/strget")
  2. public String get(HttpServletRequest request, Model model) {
  3. String key = request.getParameter("key");
  4. String rlt;
  5. //判断key在redis中是否存在
  6. if(redisService.exists(key)){
  7. rlt = "simple_get_success";
  8. String value = redisService.setGet(key);
  9. model.addAttribute("value", value);
  10. }else{
  11. rlt = "check";
  12. model.addAttribute("exists", "不存在");
  13. }
  14. model.addAttribute("key", key);
  15. addCommon(model);
  16. return rlt;
  17. }

key如果存在,就取出数据,并跳转到simple_get_success.jsp页面,否则跳转到check.jsp页面,分别展示不同的内容。

以上就是jedis基本用法的简介,详情请见redisdemo源码。

另外,部署工程的时候,请使用命令mvn clean package -U -Dmaven.test.skip=true tomcat7:redeploy,就能将工程编译打包部署到tomcat上去。

欢迎关注我的公众号:程序员欣宸

Docker下Jedis体验的更多相关文章

  1. Docker下的Spring Cloud三部曲之一:极速体验

    版权声明:欢迎转载,请注明出处,谢谢. http://blog.csdn.net/boling_cavalry/article/details/79177930   目录(?)[+]   从本章开始, ...

  2. docker下的Jenkins安装和体验【转】

    原文地址:http://blog.csdn.net/boling_cavalry/article/details/78942408 作为一款优秀的持续集成工具,jenkins在日常的项目中经常会用到, ...

  3. Docker下使用disconf:极速体验

    Docker下的disconf实战全文链接 <Docker搭建disconf环境,三部曲之一:极速搭建disconf>: <Docker搭建disconf环境,三部曲之二:本地快速构 ...

  4. Docker下kafka学习三部曲之一:极速体验kafka

    Kafka是一种高吞吐量的分布式发布订阅消息系统,从本章开始我们先极速体验,再实战docker下搭建kafka环境,最后开发一个java web应用来体验kafka服务. 我们一起用最快的速度体验ka ...

  5. Docker下实战zabbix三部曲之一:极速体验

    对于想学习和实践zabbix的读者来说,在真实环境搭建一套zabbix系统是件费时费力的事情,本文内容就是用docker来缩减搭建时间,目标是让读者们尽快投入zabbix系统的体验和实践: 环境信息 ...

  6. 实战maven私有仓库三部曲之三:Docker下搭建maven私有仓库

    本章是<实战maven私有仓库>系列的第三篇,在前两章中,我们先在linux搭建maven私有仓库,然后在开发环境使用此仓库,本章我们在docker下快速搭建maven私有仓库,然后像前面 ...

  7. Docker下使用disconf:细说demo开发

    Docker下的disconf实战全文链接 <Docker搭建disconf环境,三部曲之一:极速搭建disconf>: <Docker搭建disconf环境,三部曲之二:本地快速构 ...

  8. Docker下kafka学习三部曲之二:本地环境搭建

    在上一章< Docker下kafka学习,三部曲之一:极速体验kafka>中我们快速体验了kafka的消息分发和订阅功能,但是对环境搭建的印象仅仅是执行了几个命令和脚本,本章我们通过实战来 ...

  9. Docker下dubbo开发三部曲之三:java开发

    在前两章<Docker下dubbo开发,三部曲之一:极速体验>和<Docker下dubbo开发,三部曲之二:本地环境搭建>中,我们体验了dubbo环境搭建以及服务的发布和消费, ...

随机推荐

  1. 【POJ - 2229】Sumsets(完全背包)

    Sumsets 直接翻译了 Descriptions Farmer John 让奶牛们找一些数加起来等于一个给出的数N.但是奶牛们只会用2的整数幂.下面是凑出7的方式 1) 1+1+1+1+1+1+1 ...

  2. 高性能MySQL之事物

    一.概念 事务到底是什么东西呢?想必大家学习的时候也是对事务的概念很模糊的.接下来通过一个经典例子讲解事务. 银行在两个账户之间转账,从A账户转入B账户1000元,系统先减少A账户的1000元,然后再 ...

  3. cookie session sessionStorage localStorage

    什么是会话? 会话指的是浏览器与服务器之间的数据交互.所白了就是 浏览器和服务器进行的请求和响应. http协议是无状态的,多次请求之间没有关联性 cookie和session的作用?干啥的? 利用c ...

  4. Promise对象的resolve回调函数和reject回调函数使用

    Promise是ES6中用来结局回调地狱的问题的但是并不能帮我们减少代码量 Promise是一个构造函数 new Promise() 得到一个Promise一个实例 在Promise上有两个函数分别是 ...

  5. SQL获取客户端网卡电脑名称等信息

    Select SYSTEM_USER 当前用户名, USER_NAME() 当前所有者,db_Name() 当前数据库,@@SPID 当前进程号,(select top 1 FileName from ...

  6. websocket初体验(小程序)

    之前上个公司做过一个二维码付款功能,涉及到websocket功能,直接上代码 小程序onShow方法下加载: /** 页面的初始数据 **/ data: { code: "", o ...

  7. IDEA搭建工程

    1. 创建一个Project File -> New -> Project...   : 选择jdk版本,然后Next: 输入项目名,确定项目路径,Finish. 2. 创建一个Modul ...

  8. VS引用文件出现黄色感叹号丢失文件,应该如何解决?

    VS是微软开发的一款超级强大的IDE,深受广大.net开发者喜爱. 但是再强大,也会有它的bug和缺点. 多人协同开发时,不知道你有没有遇到一个这样的情况:第二天上班,早早来到公司,打开电脑,拉取一下 ...

  9. vue入门:用户管理demo

    该demo纯前端实现 使用到vue技术点: 1.在该demo中使用到的vue指令:{{}}. v-if. v-model. @click v-for 2.在该demo中使用到的事件修饰符: .prev ...

  10. 简析 Golang net/http 包

    net/http 包涵盖了与 HTTP 请求发送和处理的相关代码.虽然包中定义了大量类型.函数,但最重要.最基础的概念只有两个:ServeMux 和 Handler. ServeMux 是 HTTP ...