Jedis
Jedis是Redis官方推荐的Java连接开发工具。 要在Java开发中使用好Redis中间件,必须对Jedis熟悉才能写成漂亮的代码。
Jedis使用教程
Jedis: 一款java操作redis数据库的工具.
使用步骤:
下载jedis的jar包并导入
使用
1 2 3 4 5 6 Jedis jedis = new Jedis("localhost" ,6379 ); jedis.set("username" ,"zhangsan" ); jedis.close();
Jedis快速入门
我们创建JedisTest,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package test;import org.junit.Test;import redis.clients.jedis.Jedis;public class JedisTest { @Test public void test1 () { Jedis jedis = new Jedis("localhost" , 6379 ); jedis.set("username" ,"rick" ); jedis.close(); } }
在执行代码前我们先查看一下redis数据库的键:
执行后结果为:
Jedis操作
菜鸟教程
Jedis方法介绍
jedis 各类方法示例
Jedis对redis的五大类型操作代码详解
之前的笔记 中已经提到了,redis的value有五种类型:
字符串类型:string
哈希类型 hash:map格式
列表类型 list:linkedlist格式。支持重复元素
集合类型 set:不允许重复元素
有序集合类型 sortedset:不允许重复元素,且元素有顺序
下面就来看一下如何在Jedis中操作这五种类型 。其实Jedis中的方法和之前操作redis的名称是一样的
(视频讲解 )
字符串类型
存储:set()
获取:
get()
setex()
:存储可以指定过期时间的 key value
删除:del()
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package test;import org.junit.Test;import redis.clients.jedis.Jedis;public class JedisTest { @Test public void test1 () { Jedis jedis = new Jedis("localhost" , 6379 ); jedis.set("username" ,"rick" ); String username = jedis.get("username" ); System.out.println("username为:" +username); jedis.del("username" ); jedis.setex("activecode" ,20 ,"hehe" ); jedis.close(); } }
执行后结果为:
哈希类型
例子:(这里我们只给test2方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Test public void test2 () { Jedis jedis = new Jedis(); jedis.hset("user" ,"name" ,"jerry" ); jedis.hset("user" ,"age" ,"19" ); jedis.hset("user" ,"gender" ,"female" ); String name = jedis.hget("user" , "name" ); System.out.println("name是:" +name); Map<String, String> user = jedis.hgetAll("user" ); Set<Map.Entry<String, String>> entrySet = user.entrySet(); System.out.println("user的值为:" ); for (Map.Entry<String, String> entry : entrySet) { System.out.println(entry.getKey()+":" +entry.getValue()); } jedis.del("user" ); jedis.close(); }
结果为:
列表类型
就直接上代码吧。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Test public void test3 () { Jedis jedis = new Jedis(); jedis.lpush("mylist" ,"hello" ,"world" ); jedis.rpush("mylist" ,"123" ,"456" ); List<String> mylist = jedis.lrange("mylist" , 0 , -1 ); System.out.println("mylist为:" +mylist); jedis.del("mylist" ); jedis.close(); }
结果如下:
集合类型
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Test public void test4 () { Jedis jedis = new Jedis(); jedis.sadd("myset" ,"java" ,"php" ,"c++" ); Set<String> myset = jedis.smembers("myset" ); System.out.println(myset); jedis.del("myset" ); jedis.close(); }
结果如下:
有序集合类型
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Test public void test5 () { Jedis jedis = new Jedis(); jedis.zadd("mysortedset" ,3 ,"亚瑟" ); jedis.zadd("mysortedset" ,30 ,"后裔" ); jedis.zadd("mysortedset" ,55 ,"孙悟空" ); Set<String> mysortedset = jedis.zrange("mysortedset" , 0 , -1 ); System.out.println(mysortedset); jedis.del("mysortedset" ); jedis.close(); }
结果如下:
Jedis连接池
JedisPool是一个线程安全的网络连接池。 可以用JedisPool创建一些可靠Jedis实例,可以从池中获取Jedis实例,使用完后再把Jedis实例还回JedisPool。 这种方式可以避免创建大量socket连接并且会实现高效的性能。
jedis:连接池(JedisPool)使用示例
Jedis连接池的使用
jedis连接池: JedisPool
使用:
创建JedisPool连接池对象
调用方法 getResource()
方法获取Jedis连接
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Test public void test6 () { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(50 ); jedisPoolConfig.setMaxIdle(10 ); JedisPool jedisPool = new JedisPool(jedisPoolConfig,"localhost" ,6379 ); Jedis jedis = jedisPool.getResource(); jedis.set("password" ,"1234" ); String password = jedis.get("password" ); System.out.println("password键的value是:" +password); jedis.del("password" ); jedis.close(); }
结果如下:
这里说一下JedisPoolConfig的配置参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 redis.pool.maxTotal =1000 redis.pool.maxIdle =100 redis.pool.minIdle =50 redis.pool.maxWaitMillis =10000 redis.pool.testOnBorrow =true redis.pool.testOnReturn =true redis.pool.timeBetweenEvictionRunsMillis =30000 redis.pool.testWhileIdle =true redis.pool.numTestsPerEvictionRun =50 redis.ip =xxxxxx redis1.port =6379
关于JedisPoolConfig的配置参数也可以参考文章:Jedis连接池的使用
Jedis连接池工具类
JedisPool工具类,用来:
加载配置文件,配置连接池的参数
提供获取连接的方法
例子:
首先我们在src目录下创建配置文件jedis.properties,代码如下:
1 2 3 4 host =localhost port =6379 maxTotal =50 maxIdle =10
然后创建Jedis连接池工具类JedisPoolUtils代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package 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 inputStream = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties"); Properties properties = new Properties(); try { properties.load(inputStream); } catch (IOException e) { e.printStackTrace(); } JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(Integer.parseInt(properties.getProperty("maxTotal" ))); jedisPoolConfig.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle" ))); jedisPool = new JedisPool(jedisPoolConfig,properties.getProperty("host" ),Integer.parseInt(properties.getProperty("port" ))); } public static Jedis getJedis () { Jedis jedis = jedisPool.getResource(); return jedis; } }
最后我们执行代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Test public void test7 () { Jedis jedis = JedisPoolUtils.getJedis(); jedis.set("username" ,"jerry" ); String username = jedis.get("username" ); System.out.println("username键的value是:" +username); jedis.close(); }
结果如下:
案例
本案例仓库地址:https://gitee.com/qingyu1011/springboot_study/tree/master/J2EE/Jedis
案例需求:
提供index.html页面,页面中有一个省份的下拉列表
当页面加载完成后 ,发送ajax请求,加载所有省份
案例分析
视频讲解
代码实现
首先还是要导入相关jar包:
然后创建配置文件:druid.properties和jedis.properties,代码分别如下:
1 2 3 4 5 6 7 driverClassName =com.mysql.jdbc.Driver url =jdbc:mysql://localhost:3306/jdbc_study username =root password =123456 initialSize =5 maxActive =10 maxWait =3000
1 2 3 4 host =localhost port =6379 maxTotal =50 maxIdle =10
然后在dao包下创建ProvinceDao接口和其实现类ProvinceDaoImpl,代码分别如下:
1 2 3 4 5 6 7 8 9 package dao;import domain.Province;import java.util.List;public interface ProvinceDao { public List<Province> findAll () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package dao.impl;import dao.ProvinceDao;import domain.Province;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import util.JDBCUtils;import java.util.List;public class ProvinceDaoImpl implements ProvinceDao { private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource()); @Override public List<Province> findAll () { String sql = "select * from province " ; List<Province> provinces = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Province>(Province.class )) ; return provinces; } }
在domain包下创建Province类代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package domain;public class Province { private Integer id; private String name; public Integer getId () { return id; } public void setId (Integer id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } }
在service包下创建ProvinceService接口和其实现类ProvinceServiceImpl,代码分别如下:
1 2 3 4 5 6 7 8 9 10 11 12 package service;import domain.Province;import java.util.List;public interface ProvinceService { public List<Province> findAll () ; public String findAllJson () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package service.impl;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import dao.ProvinceDao;import dao.impl.ProvinceDaoImpl;import domain.Province;import jedis.util.JedisPoolUtils;import redis.clients.jedis.Jedis;import service.ProvinceService;import java.util.List;public class ProvinceServiceImpl implements ProvinceService { private ProvinceDao provinceDao = new ProvinceDaoImpl(); @Override public List<Province> findAll () { return provinceDao.findAll(); } @Override public String findAllJson () { Jedis jedis = JedisPoolUtils.getJedis(); String provinc_json = jedis.get("province" ); if (provinc_json == null || provinc_json.length() == 0 ){ System.out.println("redis中没有数据,查询数据库" ); List<Province> provinces = provinceDao.findAll(); ObjectMapper objectMapper = new ObjectMapper(); try { provinc_json = objectMapper.writeValueAsString(provinces); } catch (JsonProcessingException e) { e.printStackTrace(); } jedis.set("province" ,provinc_json); jedis.close(); }else { System.out.println("redis中有数据,查询缓存" ); } return provinc_json; } }
在util包下创建JDBCUtils工具类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 package util;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;public class JDBCUtils { private static DataSource ds ; static { try { Properties pro = new Properties(); InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static DataSource getDataSource () { return ds; } public static Connection getConnection () throws SQLException { return ds.getConnection(); } }
在web包下的servlet包下创建ProvinceServlet代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package web.servlet;import com.fasterxml.jackson.databind.ObjectMapper;import domain.Province;import service.ProvinceService;import 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 { ProvinceService provinceService = new ProvinceServiceImpl(); String json = provinceService.findAllJson(); 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); } }
在浏览器中访问:http://localhost:8080/jedis/index.html
结果为:
注意:
千万要注意:druid.properties
配置文件中一些数字后面不要加空格,不然会报错java.lang.NumberFormatException: For input string: "10 # ×??ó??????"
错,就是因为之前这样写的:maxActive=10 # 最大连接数
。
使用redis缓存一些不经常发生变化的数据
因为数据库的数据一旦发生改变,则需要更新缓存。在service对应的增删改方法中,需要将redis数据删除。