SpringBoot+Redis实现Java缓存技术

强颜欢笑 提交于 2020-01-15 05:34:14

        本文是笔者一边敲代码一边去编写的,因此在可用度上是极高的,欢迎大家来学习,有什么问题大家也可以跟笔者相互交流一下。
        该实例是基于SpringBoot环境下的RedisTemplate来对redis数据库进行操作,同时也使用到SSM来进行数据库操作,进而实现Java缓存技术的实例开发,下面我开始详细讲解具体的实现过程:
(一)项目的目录结构:
在这里插入图片描述
        该项目为maven项目结构,相信有学习SpringBoot框架的读者应该都会创建这种项目,此处笔者就不讲解,有需要了解的读者可以在评论区下留言,笔者提供创建链接。

(二)在pom.xml文件中添加依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>SpringBootDemo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringBootDemo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
	 	
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		
		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>

        <!-- 热部署用,改变代码不需要重启项目  -->
		 <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
			<scope>true</scope>
		</dependency> 
		
		<!--  配置JSP访问视图 -->
		<dependency>
		   <groupId>org.apache.tomcat.embed</groupId>
		   <artifactId>tomcat-embed-jasper</artifactId>
		</dependency>
		<dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-tomcat</artifactId>
           <scope>provided</scope>
       </dependency>
       
		<!-- mysql连接  -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		
		<!-- 添加 Mysql 依赖 -->
		<!-- 添加 Spring Data JPA 依赖 -->  
	    <dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-data-jpa</artifactId>
	    </dependency>
    
    	<!-- redis依赖配置 -->
    	<dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-data-redis</artifactId>
          </dependency>
          <dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>fastjson</artifactId>
              <version>1.2.44</version>
          </dependency> 
	    <dependency>             
		    <groupId>com.google.code.gson</groupId>             
		    <artifactId>gson</artifactId>             
		    <version>2.8.5</version>         
	    </dependency>
    
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<!-- fork : 如果没有该选项,那这个热部署的devtools不会起作用,即应用不会自动restart -->
					<fork>true</fork>
				</configuration>
			</plugin>
			
		</plugins>
		
	</build>

</project>

(三)在配置文件application.properties中添加以下信息:

server.port: 8081

# mysql
spring.datasource.url: jdbc:mysql://localhost:3306/jsp?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username: root
spring.datasource.password: root
# spring.datasource.driver-class-name: com.mysql.jdbc.Driver     not can use
spring.datasource.driver-class-name: com.mysql.jdbc.Driver
spring.datasource.dbcp2.validation-query: 'select 1'
spring.datasource.dbcp2.test-on-borrow: true
spring.datasource.dbcp2.test-while-idle: true
spring.datasource.dbcp2.time-between-eviction-runs-millis: 27800
spring.datasource.dbcp2.initial-size: 5
spring.datasource.dbcp2.min-idle: 5
spring.datasource.dbcp2.max-idle: 100
spring.datasource.dbcp2.max-wait-millis: 10000

# mybatis 
# 指mapper映射文件会绑定到src/main/resource/mapper目录下
mybatis.mapper-locations: classpath*:mapper/**/*.xml
mybatis.configuration.map-underscore-to-camel-case: true

# JSP use's configution spring.mvc.view.prefix
spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp

#解决sql Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set 的问题
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
#本地主机名
spring.redis.host=127.0.0.1
#redis默认的端口值
spring.redis.port=6379
#redis数据库,总共有0-15可以输入
spring.redis.database=1

注意:
①此处的mysql数据库信息配置读者可以根据自己的本地数据库信息进行修改;
②配置信息中“classpath*:mapper/**/*.xml”是指映射到mapper/路径下所有目录的xml文件;
③spring.redis.database=1的“1”代表redis数据库下对应的编号,如图所示:
在这里插入图片描述
(四)设计思路:
        在获取数据前,先对跟数据是否存在于redis缓存中进行判断,如果存在,则直接从缓存中把数据读取出来;否则,先把数据从mysql或SQL Server数据库中查询出来,然后再把查询出来的数据添加到redis缓存中。

实体类的编写:

import javax.persistence.Id;
import javax.persistence.Table;
/*
* @time:2020/1/2
* @descrition:学生实体类,用于封装学生的基本信息
**/
@Table(name="student")
public class Student {
	
	@Id
	String id;//主键
	String name;//姓名
	String sno;//学号
	String sex;//性别
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSno() {
		return sno;
	}
	public void setSno(String sno) {
		this.sno = sno;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
}

        在此说明一下,本文并没有单独把数据库文件导出来给大家使用,读者们可以自己去创建一个数据库及表来进行测试,相信能学到这里的读者都应该具备较好的编程基础,对于这种简单的数据库设计应该只需要几分钟就能完成的,实在不会可以在评论区下留言,笔者一一帮忙解答。

dao层的编写:

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import Test.entity.Student;

/*
*  @time: 2020/1/3
*  @description: 映射对应xml配置文件
*  
**/
@Mapper
public interface TestDao {
	//查询学生信息
	public List<Student> getStuList();
	
}

TestMapper.xml配置文件的编写:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Test.dao.TestDao">
	 <select id="getStuList" resultType="Test.entity.Student">
	 	select * from student 
	 </select>
</mapper>

        此处也要注意一点,即namespaceresultType属性的值都要对应自己的项目路径来编写,否则一定会出错,请各位读者认真查阅,避免不必要的错误。

业务逻辑层的编写:

import java.lang.reflect.Type;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import Test.dao.TestDao;
import Test.entity.Student;
/*
*  @time: 2020/1/3
*  @description: 测试业务逻辑类,用于编写代码的具体实现逻辑
*  
**/
@Service
public class TestService {

	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	
	@Autowired
	private TestDao testDao;
	
	/*
	*  此处为redis缓存技术的核心代码
	* 这是基于一种相对简单方式去进行缓存的,适合刚入门的新手去学习
	**/
	public List<Student> getStuList(){
		String key = "student_list";
		ValueOperations<String, String> operations = redisTemplate.opsForValue();
		//如果该键存在,说明缓存中存在,则直接从缓存中把数据读出即可,而不需要查询数据库进行获取。
		if (redisTemplate.hasKey(key)) {
			//从缓存中
			String redisList = (String) operations.get(key);
			Type type = new TypeToken<List<Student>>() {}.getType();
			List<Student> list = new Gson().fromJson(redisList, type);
			System.out.println("从缓存取得数据"+ list.size()+"条数" );
			return list;
		}
		//此处是笔者在后端数据库中获取的list数据集合,读者可以根据自己的需求进行修改。
		List<Student> list = studentMapper.selectAll();
		System.out.println("从数据库中查询数据");
		//再把list集合强制转化为json格式数据
		String toJson = new Gson().toJson(list);
		// 保存到redis数据库缓存中,第一个参数为键名,第二个参数为数据,第三个参数为有效时间,第四个为时间单位
		operations.set(key, toJson, 60, TimeUnit.SECONDS);
		System.out.println("已经把list集合保存到缓存中");
		return list;
	}
}

控制层的编写:

import java.util.List;

import javax.servlet.ServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import Test.entity.Student;
import Test.service.TestService;

/*
*  @time: 2020/1/3
*  @description: 测试控制器,有设置到两层访问路径
**/
@Controller
@RequestMapping(value="student")
public class TestController {

	@Autowired
	private TestService testService;
	
	//@ResponseBody注解可以让该方法映射对应数据返回到前端页面,而不是查找jsp视图
	@RequestMapping(value="getStuList",produces = "application/json;charset=UTF-8")
	@ResponseBody
	public List<Student> getStuList(ServletRequest request) {
		
		return testService.getStuList();
	}
}

⑥最后在浏览器中输入:http://localhost:8081/student/getStuList。结果如下:
在这里插入图片描述
        此处是把list集合以json数据格式显示在页面中,方便读者去查看效果。
        同时,我们也可以注意到,当我们第一次在浏览器访问时,该集合是从mysql数据库进行获取的,当我们开始第二次访问时,会发现我们的数据是从redis缓存中进行获取,可以从编译器的控制台中查看,主要是因为笔者在Service层代码中设置到相应的提示信息,具体如下:
在这里插入图片描述
        到此,本文算是结束了,如果有读者在查阅时发现其中存在什么问题,欢迎大家多多批评指正。因为笔者也是初学者,一来是希望通过编写文章去总结自己所学过的东西,二来是想通过这种方式去跟各位读者分享,跟大家交流,共同学习,相互进步!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!