1. SpringBoot 基础
1.1 简介
- 用途:快速搭建java EE项目,提供自动化配置方案
- 优势:
- 提供一个快速的spring项目搭建渠道
- 提供一系列通用配置,纯java配置
- 内嵌服务器,快速部署
1.2 手动创建SpringBoot工程
1.2.1 idea创建maven工程
1.2.2 手动构建项目
- 添加依赖pom.xml文件 spring-boot-starter-parent,作用:
- Java 版本默认使用1.8 .
- 编码格式默认使用UTF-8.
- 提供Dependency Management 进行项目依赖的版本管理。
- 默认的资源过滤与插件配置。
- 启动类
@SpringBootApplication // 1.配置Spring和SpringMVC 2.包扫描
public class App {
public static void main(String[] args){
SpringApplication.run(App.class,args);
}
}
- 启动项目
- idea启动main方法(内置tomcat)
- 引依赖spring-boot-maven-plugin, mvn clean package打包,java -jar 命令启动jar包
-
1.3 快速创建SpringBoot工程(常用)
- 项目的基本信息,包括组织Id 、模块名称、项目构建类型、最终生成包的类型、Java 的版本、开发语言、项目版本号、项目名称、项目描述以及项目的包。
- Spring Boot 项目创建成功之后,几乎零配置, 开发者就可以直接使用Spring 和SpringMVC 中的功能了
1.4 @Spring BootApplication注解
包括:
-
@Spring BootConfiguration 表明配置类,类似于Spring
中的aplicationContext.xml 文件-
一般会创建一个专门的类用来配置bean,方便管理
@Configuration public class MyConfig(){ }
-
-
@EnableAutoConfiguration 开启自动化配置
-
@ComponentScan 扫描当前类所在包下面内容,一般把项目启动类放在根包中
- 会扫描@Service , @Repository 、@Component 、
@Controller 、@RestController 和@Configuration 等注解的类
- 会扫描@Service , @Repository 、@Component 、
1.5 web容器配置
1.5.1 tomcat配置
1.5.1.1 常规配置
spring-boot-starter-web 依赖会默认使用Tomcat 作为Web 容器,可以在application.properties 中进行进一步配置
- server . port = 8081 端口
- server . error . path = /error 出错跳去的路径
- server . servlet . session.timeout = 30m session失效时间
- server . servlet . context-path = /chapter02 访问路径
- server . tomcat . uriencoding = utf-8
- server . tomcat . max-threads = 500 最大线程数
- server . tomcat .basedir = /home/sang/tmp basedir 是一个存放Tomcat 运行日志和临时文件的目录,若不配置,则默认使用系统的临时目录
1.5.1.2 https配置
- 通过工具生成一个https证书
keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048 -keystore sang.p12 -validity 365
2. 在application.properties 中配置
- server.ssl.key-store=sang.p12
- server.ssl.key-alias=tomcathttps
- server.ssl.key-store-password=root123
然后就可以使用https访问了。
https://localhost:8081/chapter02/getHello
1.6 application.properties配置
1.6.1 加载&注入
- application.properties或application.yml可能出现的4个位置,按照顺序依次加载到Spring Environment中:
- application.properties内容注入到bean中的例子:
- application.properties
book.name=三国演义
book.author=罗贯中
book.price=30
- 或application.yml
//yml文件还能支持列表,如:persons
book:
name: 水浒
author_name: 施耐庵
price: 30
persons:
- 武松
- 12
- chaogai
- 实体类Book
@Component
@ConfigurationProperties(prefix = "book")
public class Book {
private String name;
private String author;
private Float price;
private List<String> persons;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public List<String> getPersons() {
return persons;
}
public void setPersons(List<String> persons) {
this.persons = persons;
}
}
- BookController
@RestController
public class BookController {
@Autowired
Book book;
@GetMapping("/book")
public Book book(){
return book;
}
}
- 运行结果:
- YAML虽然方便, 但是存在缺陷,如:无法使用 @PropertySource注解加载 YAML文件
1.6.2 开发环境和生产环境中的配置文件区分
可以配置不同的端口号:8080/80
- 开发环境:application-dev.yml
server:
port: 8080
- 生产环境:application-prod.yml
server:
port: 80
然后在application.yml中进行配置:
spring:
profiles:
#表示使用配置文件application-dev.yml启动项目
active: dev
2. SpringBoot 整合视图层
2.1 整合Thymeleaf
2.2 整合FreeMarker
- 如果使用的是目前流行的前后端分离技术, 那么在开发过程中不需要整合视图层技术,后端直接提供接口即可
3.SpringBoot 整合Web 开发
3.1 返回json数据
3.1.1 默认返回
由于pom.xml中添加的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
其中默认加入了jackson-databind 作为JSON处理器,如上面例子中返回book对象就属于这种情况。
3.1.2 自定义json处理器
- 除了jackson-databind之外的
3.1.2.1 使用Gson
3.1.2.2 使用fastjson
- 首先除去jackson-databind依赖,引入fastjson依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
- 在SpringBoot 项目中,当开发者引入spring-boot-starter-web 依赖之后,该依赖又依赖了spring-boot-autoconfigure , 在这个自动化配置中,有一个WebMvcAutoConfiguration 类提供了对SpringMVC 最基本的配置, 如果某一项自动化配置不满足开发需求,开发者可以针对该项自定义配置,只需要实现WebMvcConfigurer接口即可
- 配置json解析过程中的一些细节
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setDateFormat("yyyy-MM-dd hh:mm:ss");//日期格式
config.setCharset(Charset.forName("UTF-8"));//数据编码
config.setSerializerFeatures(
SerializerFeature.WriteClassName,//是否在生成的JSON 中输出类名
SerializerFeature.WriteMapNullValue,//是否输出value为null的数据
SerializerFeature.PrettyFormat,//生成的json格式化
SerializerFeature.WriteNullListAsEmpty,//空集合输出[]而非null
SerializerFeature.WriteNullStringAsEmpty//空字符串输出""而非null
);
converter.setFastJsonConfig(config);
converters.add(converter);
}
}
3.2 静态资源访问
3.2.1 默认策略
不同位置静态资源的优先级:
- resources/META-INF/resources
- resources/resources
- resources/static
- resources/public
- IntelliJ IDEA 创建SpringBoot 项目,会默认创建出resources/static目录,一般静态资源放在此目录下即可
3.2.1 自定义策略
- 默认的静态资源过滤策略满足不了要求时(很少)
- 配置文件定义
- java编码定义
3.3 文件上传
java中文件上传一般涉及两个组件:
- CommonsMultipartResolver:使用commons-fileupload工具包。
文件上传的原理是IO流实现的,通过二进制流的方式向服务器传输数据,服务器再通过流读取到数据,然后解析成文件,最终保存到服务器上。
commons-fileupload工具包里面封装了对流操作的过程,简化了实现文件上传的代码复杂度。
参考:commons-fileupload实现文件上传 - StandardServletMultipartResolver
3.3.1 单文件上传
1. 在resources 目录下的static 目录中创建一个upload.html 文件,作为上传文件界面
- 上传接口是**/upload**,请求方法是post, enctype 是multipart/form-data,意思是以二进制数据流的方式传输
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" value="请选择文件">
<input type="submit" value="上传">
</form>
</body>
</html>
2. 创建文件上传处理接口
package com.cewell.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
/**
* ClassName:FileUploadController
* Package:com.cewell.controller
* Description:文件上传
*
* @date:2019/11/26 18:24
* @author:[email protected]
*/
@RestController
public class FileUploadController {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
@PostMapping("/upload")
public String upload(MultipartFile uploadFile, HttpServletRequest req){
//第27代码表示规划上传文件的保存路径为项目运行目录下的uploadFile 文件夹,并在文件夹中通过日期对所上传的文件归类保存。
String realPath = req.getSession().getServletContext().getRealPath("/uploadFile/");
String format = sdf.format(new Date());
File folder = new File(realPath + format);
//如果目录不存在,创建
if (!folder.isDirectory()) {
folder.mkdirs();
}
//给上传的文件重命名
String oldName = uploadFile.getOriginalFilename(); //得到上传时的文件名
//UUID.randomUUID().toString() 是JDK提供的一个自动生成主键的方法
//* 截取字符串substring()方法的用法
// 1.substring(int beginIndex); 截取开始索引beginIndex到结束
// "mybaby".substring(3) returns"aby"
// 2.substring(int beginIndex, int endIndex); 截取开始索引beginIndex到结束索引endIndex-1
// "hamburger".substring(3,8) returns "burge"
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."),oldName.length());
//UUID + 截取的文件后缀名
try {
//文件保存 地址,重命名的名字
uploadFile.transferTo(new File(folder,newName));
//生成上传文件的访问路径,并将访问路径返回。
String filePath =
req.getScheme() + "://" //协议
+ req.getServerName() + ":" //ip
+ req.getServerPort() + "/uploadFile/" //端口
+ format + newName;
return filePath;
} catch (IOException e) {
e.printStackTrace();
}
return "上传失败";
}
}
- 执行完成后,返回上传文件的访问路径
- 由访问路径访问文件内容
3.还可以对上传细节进行配置
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=0
spring.servlet.multipart.location=E:\\temp
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.resolve-lazily=false
- 第1 行表示是否开启文件上传支持,默认为true。
- 第2 行表示文件写入磁盘的闽值,默认为0 。
- 第3 行表示上传文件的临时保存位直。
- 第4 行表示上传的羊个文件的最大大小,默认为1MB
- 第5 行表示多文件上传时文件的总大小,默认为10MB
- 第6 行表示文件是否延迟解析,默认为false 。
3.3.2 多文件上传
1. 在resources 目录下的static 目录中创建一个uploadMultiple.html 文件,作为上传文件界面(比单个的时候input标签中加一个multiple)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/uploadMultiple" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFiles" value="请选择文件" multiple/>
<input type="submit" value="上传"/>
</form>
</body>
</html>
2. 创建文件上传处理接口
- 传参改成数组MultipartFile[] uploadFiles
@PostMapping("/uploadMultiple")
public List<String> uploadMultiple(MultipartFile[] uploadFiles, HttpServletRequest req) {
//定义一个list用来存放三张图片上传之后的链接
List<String> filePathList = new ArrayList<String>();
for (int i = 0; i < uploadFiles.length; i++) {
//第27代码表示规划上传文件的保存路径为项目运行目录下的uploadFile 文件夹,并在文件夹中通过日期对所上传的文件归类保存。
String realPath = req.getSession().getServletContext().getRealPath("/uploadFile/");
String format = sdf.format(new Date());
File folder = new File(realPath + format);
//如果目录不存在,创建
if (!folder.isDirectory()) {
folder.mkdirs();
}
//给上传的文件重命名
String oldName = uploadFiles[i].getOriginalFilename(); //得到上传时的文件名
//UUID.randomUUID().toString() 是JDK提供的一个自动生成主键的方法
//* 截取字符串substring()方法的用法
// 1.substring(int beginIndex); 截取开始索引beginIndex到结束
// "mybaby".substring(3) returns"aby"
// 2.substring(int beginIndex, int endIndex); 截取开始索引beginIndex到结束索引endIndex-1
// "hamburger".substring(3,8) returns "burge"
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length());
//UUID + 截取的文件后缀名
try {
//文件保存 地址,重命名的名字
uploadFiles[i].transferTo(new File(folder, newName));
//生成上传文件的访问路径,并将访问路径返回。
String filePath =
req.getScheme() + "://" //协议
+ req.getServerName() + ":" //ip
+ req.getServerPort() + "/uploadFile/" //端口
+ format + newName;
filePathList.add(filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
//return "上传失败";
return filePathList;
}
- 返回一个访问路径的list
- 然后可以由访问路径访问文件内容
3.4 @ControllerAdvice全局处理数据
3.4.1 全局异常处理
- 如:3.3中上传文件过大会抛出MaxUploadSizeExceededException异常
- 在系统中定义CustomExceptionHandler 类,然后添加
@ControllerAdvice注解,系统启动时,该类被扫描到spring容器中。 - 如果MaxUploadSizeExceededException改为Exception,表明该方法用来处理所有类型的异常
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(MaxUploadSizeExceededException.class)
public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter(); //取一个响应客户端的流对象,用来在客户端输出
out.write("上传文件大小超出限制"); //通过PrintWrite,以流方式输出,返回给浏览器
out.flush(); //清空缓冲区的数据流
out.close(); //关闭读写流
//flush()这个函数是清空的意思,用于清空缓冲区的数据流,进行流的操作时,数据先被读到内存中,然后再用数据写到文件中,
// 那么当你数据读完时,我们如果这时调用close()方法关闭读写流,这时就可能造成数据丢失,为什么呢,因为,读入数据完成时不代表写入数据完成,
// 一部分数据可能会留在缓存区中,为了理解这个问题,我们举一个例子:
//
//比如,在农村,几乎每家都有抽水机,抽水机的作用是什么呢,就是把水井里的水抽到水缸中,这时我们就会用水管连接抽水机和水缸(水管就好比是缓冲区),
// 当我们想把水井中的水都抽到水缸中时,我们就让抽水机工作抽水,如果我们发现水井里的水刚好抽完时,我们就会关掉抽水机的开关停止抽水,那么这时,
// 管道里就会遗留一部分水,抽水就是读数据,水缸进水就是写数据,水管充当缓存区的角色,不知道这样是不是具象化了呢
//
//那么这样一来我们如果中途调用close()方法,输出区也还是有数据的,就像水缸里有水,只是在缓冲区遗留了一部分,这时如果我们先调用flush()方法,
// 就会强制把数据输出,缓存区就清空了,最后再关闭读写流调用close()就完成了。
}
}
3.4.2 添加全局数据
- @ModelAttribute中的value属性(“info”)表示这条返回数据的key,而方法的返回值是返回数据的value
@ControllerAdvice
public class GlobalConfig {
//注解@ModelAttribute中的value属性表示这条返回数据的key,而方法的返回值是返回数据的value
@ModelAttribute(value = "info")
public Map<String,String> userInfo(){
HashMap<String,String> map = new HashMap<>();
map.put("writer","罗贯中");
map.put("bookName","三国演义");
return map;
}
}
- 此时在任意请求的Controller 中,通过方法参数中的Model 都可以获取info 的数据。
@RestController
public class HelloController {
@GetMapping("/helloBook")
public String helloBook(Model model){
Map<String,Object> map = model.asMap();
return map.toString(); //{info={writer=罗贯中, bookName=三国演义}}
}
}
3.4.3 请求参数预处理
- @ControllerAdvice 结合 @InitBinder 还能实现请求参数预处理,即将表单中的数据绑定到实体类上时进行一些额外处理。
参考:SpringMVC表单多对象传递小技巧——@InitBinder
3. SpringBoot 整合持久层
3.1 整合Mybatis
3.1.1 pom.xml添加相关依赖
- 添加MyBatis依赖、数据库驱动依赖以及数据库连接池依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
3.1.2 创建数据库和表
3.1.3 创建数据库配置
- 在application.yml中配置数据库基本连接信息
# 数据库配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/exercise?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
username: root
password: root123
3.1.4 创建bean、controller、service、mapper、mapper.xml
//bean
public class Masterpiece {
private Integer id;
private String name;
private String author;
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;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
<?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="com.cewell.dao.MasterpieceMapper">
<resultMap id="BaseResultMap" type="com.cewell.bean.Masterpiece">
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="author" jdbcType="VARCHAR" property="author"/>
</resultMap>
<select id="getMasterpiece" resultMap="BaseResultMap">
select * from masterpiece
</select>
</mapper>
3.1.5 在pom.xml中配置扫描 java 目录下的xml文件
- Maven工程中,XML 配置文件建议写在resources目录下
Mapper.xml文件写在java包下,Maven在运行时会忽略包下的XML文件,因此需要在pom.xml文件中重新指明资源文件位置
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<!--<include>**/*.properties</include>
<include>**/*.dic</include>
<include>**/*.xsd</include>-->
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<!--<includes>
<include>**/*.xml</include>
<include>**/*.yml</include>
<include>**/*.ftl</include>
</includes>-->
</resource>
</resources>
3.1.6 controller运行结果
3.2 MyBatis多数据源(暂缺)
4. SpringBoot 整合NoSQL
4.1 整合Redis
4.1.1 redis基础
1.
- redis可以看作一个独立的hashMap,不是在JVM中运行,而是以一个独立进程的形式运行
2. Key-Value数据库
3.
- 当作缓存使用。 因为它比数据库(mysql)快,所以常用的数据,可以考虑放在这里,这样就提高了性能
4.
redis-server.exe | redis-cli.exe |
---|---|
服务端 | 客户端 |
启动redis程序 | 进入redis的命令界面 |
必须启动 | 用jedis之类的操作redis的话就无须启动 |
5.
有5种数据类型 :
- String(字符串)
- List(列表)
- Hash(字典)
- Set(集合)
- Sorted Set(有序集合)
6. jedis:
- 除了使用各种Redis自带客户端的命令行–方式访问Redis服务。 在实际工作中更多用Java代码访问,使用第三方jar包 Jedis就能方便地访问Redis的各种服务了。
import redis.clients.jedis.Jedis;
7. Jedis 和 JedisPool 连接池
1>.Jedis直连
生成Jedis对象
Jedis执行命令
返回执行结果
关闭Jedis连接
Jedis jedis = new Jedis("127.0.0.1","6379");
jedis.set("hello","world");
String value = jedis.get("hello");
2>.使用Jedis连接池
从资源池借Jedis对象
Jedis执行命令
返回执行结果
归还Jedis对象给连接池
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
JedisPool jedisPool = new JedisPool(poolConfig ,"12.0.0.1",6379);
Jedis jedis = null ;
try{
jedis = jedisPool.getResource();
}catch(Exception e ){
e.printStackTrace;
}finally{
}
8.Redis、Jedis、SpringDataRedis及RedisTemplate关系
(1)Redis、Jedis、SpringDataRedis及RedisTemplate关系
1>.Redis是一个基于内存的Key-Value数据库
2>.Jedis是Redis官方推出的面向Java的客户端Client,提供了很多接口和方法,可以让Java操作使用Redis
3>.SDR是Spring框架集成Redis操作的一个子框架,封装了Redis的很多命令;比Jedis多了自动管理连接池的特性
4>.RedisTemplate是SpringDataRedis中对JedisApi的高度封装
(2)jedis : 操作redis是很简单的,通过new的方式,获取jedis对象,然后增删改查(set,get,del,exists)等,简单来说就是代码的方式来实现操作的;
RedisTemplate : 也可以做到操作redis缓存, 使用spring注入方式的配置
一个比较原生,一个经过spring托管控制;RedisTemplate只做缓存,没有队列,相对jedis功能更少;
单线程使用RedisTemplate缓存即可,如果有多线程,需要使用jedis
4.1.2 SpringBoot整合redis
1. pom.xml 添加相关依赖
<!--添加redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<!--从spring-boot-starter-data-redis中排除Lettuce并引入Jedis-->
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--引入Jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2. 创建redis配置(application.yml 中)
spring:
# 配置Redis
redis:
# 基本连接信息
database: 0 #数据库索引,共16个,编号1-15
host: 127.0.0.1
port: 6379
password:
# 连接池信息
jedis:
pool:
#最大连接数
max-active: 8
#最大空闲连接数
max-idle: 8
#最大阻塞等待时间(负数表示没限制)
max-wait: -1ms
#最小空闲
min-idle: 0
3. 创建实体类bean
//一个类只有实现了Serializable接口,它的对象才是可序列化的
//Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。
public class Masterpiece implements Serializable {
private Integer id;
private String name;
private String author;
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;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "name: " + this.name + " " + "author: " + this.author;
}
}
4. 创建controller
@RestController
@RequestMapping("api")
@GetMapping("/getMasterpieceRedis")
public void getRedis(){
//向redis中存一条记录,再将其读取
ValueOperations<String,String> opsl = stringRedisTemplate.opsForValue(); //获取一个键值操作器
opsl.set("name","三国演义");
String name = opsl.get("name");
System.out.println(name);
//向redis中存一个对象,再将其读取
ValueOperations opsl2 = redisTemplate.opsForValue();
Masterpiece m = new Masterpiece();
m.setId(1);
m.setAuthor("罗贯中");
m.setName("三国演义");
opsl2.set("m",m);
Masterpiece masterpiece = (Masterpiece) opsl2.get("m");
System.out.println(masterpiece.toString());
}
}
5. 访问后结果