一、简单介绍
redis
是一款高性能的NOSQL
系列的非关系型数据库。主要用于缓存,可提升数据访问的性能。这里用于做缓存的数据是不经常做改变的数据。核心思想见下图:
使用缓存机制,可以加快我们数据的访问。因为数据是暂存在内存中,直接访问内存的数据可以减少在访问数据库过程中的I/O
操作,这样便可以提升系统的性能,查询速度。但是作为缓存也有一定的缺点:数据因为是暂存在内存上的,一旦redis
服务端关闭,再次开启时,缓存数据将不复存在。因此在某些场合中,我们需要对redis
缓存数据做持久化操作,将其持久化到硬盘上,当再次查询时,可将数据读取到缓存中。
从以上我们看出redis
使用时的两点注意事项:
- 数据不会经常改变。如果,数据持续改变,就不断的访问数据库,再将数据放入到缓存中。
- 确定持久化操作的条件。不能随时随地的进行持久化(反而增加了
IO
操作),也不能对缓存中大量改变的数据不做持久化数据(会导致数据大量的丢失)。
二、案例实操
通过对redis
的基本介绍,我们做一个小案例。案例需求如下:
- 提供index.html页面,页面中有一个省份下拉列表
- 当页面加载完成后,发送
ajax
请求,加载所有省份
思路:
当接收到请求时,做redis
缓存的查询。如果缓存中存在所需要的数据,就将缓存数据进行返回;如果不存在,就进行数据库查询,同时将数据库中的数据加入到缓存中,再将数据进行返回。
前端接收到的数据是序列化后的Json
数据,便于数据的读取,进行页面数据的展示。
思考:为什么这里要使用ajax
?
当我们对页面进行加载时,就需要自动显示后台传递的数据,而没有进行任何链接的操作(form表单提交、点击超链接等操作),而让页面主动对后端进行请求,所以我们这里需要使用ajax
,简化我们的操作。
第二点是因为异步请求是为了获取服务器响应的数据,而前端使用的是html
,不能够直接从servlet
相关的域对象获取值,只能通过ajax
获取相应的数据。
以下便是具体实现的代码:
dao层中findAll方法的实现
1 2 3 4 5 6 7 8 9 10 11
| public class ProvinceDaoImpl implements ProvinceDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override public List<Province> findAll() { String sql = "select * from province"; List<Province> list = template.query(sql, new BeanPropertyRowMapper<Province>(Province.class)); return list; } }
|
service层中findAll方法的实现
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
| public class ProvinceServiceImpl implements ProvinceService {
private ProvinceDao provinceDao = new ProvinceDaoImpl(); @Override public String findAllByRedis() { Jedis jedis = JedisUtils.getJedis(); String province = jedis.get("province"); if (province == null || province.length() == 0) { System.out.println("缓存中没有,先对数据库进行查询"); List<Province> list = provinceDao.findAll(); ObjectMapper mapper = new ObjectMapper(); try { province = mapper.writeValueAsString(list); jedis.set("province", province); } catch (JsonProcessingException e) { e.printStackTrace(); } finally { jedis.close(); } } else { System.out.println("查询的数据在缓存中"); }
return province; } }
|
web层中FindAllProvince类
1 2 3 4 5 6 7 8 9 10 11 12 13
| @WebServlet("/findAllProvince") public class FindAllProvince extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/json;charset=utf-8"); ProvinceService service = new ProvinceServiceImpl(); String json_list = service.findAllByRedis(); response.getWriter().write(json_list); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
|
2.1 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
| public class JDBCUtils {
private static DataSource ds;
static {
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");// 配置文件的字节输入流 Properties properties = new Properties(); try { properties.load(is); ds = DruidDataSourceFactory.createDataSource(properties); } 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(); }
}
|
JedisUtils工具类
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
| public class JedisUtils {
private static Jedis jedis;
static {
InputStream is = JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties"); Properties properties = new Properties(); try { properties.load(is); } catch (IOException e) { e.printStackTrace(); } JedisPoolConfig config = new JedisPoolConfig(); String password = (String) properties.get("password"); String port = properties.getProperty("port"); String host = (String) properties.get("host"); String maxTotal = (String) properties.get("maxTotal"); String maxIdle = (String) properties.get("maxIdle"); config.setMaxIdle(Integer.parseInt(maxIdle)); config.setMaxTotal(Integer.parseInt(maxTotal)); JedisPool jedisPool = new JedisPool(config, host, Integer.parseInt(port)); jedis = jedisPool.getResource(); jedis.auth(password); }
public static Jedis getJedis() { return jedis; } }
|
2.2前端代码
前端代码展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>省份导入</title> <script src="js/jquery-3.3.1.min.js"></script> </head> <body> <select id="province"> <option>--请选择省份--</option> </select>
<script> $.get("findAllProvince", {}, function (data) { $(data).each(function () { var option = "<option name=(''+this.id) value=(''+this.id)>"+this.name+"</option>"; $province.append(option) });
}); </script> </body> </html>
|
2.3 注意事项
redis
是用于缓存一些不经常发生变化的数据。
数据库的数据一旦发生改变,则需要更新缓存。
- 数据库的表执行增删改的相关操作,需要将对应的
redis
缓存数据清空,再次存入
- 在
service
对应的增删改方法中,将redis
数据删除。