SpringBoot搭建SSM整合Redis缓存数据


SpringBoot_SSM_Redis的整合

前言 :整合的主要功能测试 增删改查,spring.cache配合Redis来实现缓存的功能,以及使用fastjson来转换redis序列器。

阅读注意看代码块里的注释

1.首先构建我们的项目pom.xml
在这里插入图片描述

[项目构建可以使用springboot工具配合开发工具选择自己的需要的依赖]

2.我们开始编写配置文件,
是使用的是application.properties当然自己也可以使用yml配置文件去配置.

#这是连接Mysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/smbms?characterEncoding=utf-8&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

#这是redis的连接根据自己需求也可以配置它的连接池
spring.redis.host=192.168.249.88
spring.redis.port=6379
spring.redis.password=root
spring.redis.database=0

#整合缓存的操作
#SpringCache本身是一个缓存体系的抽象实现,并没有具体的缓存能力,要使用SpringCa要配合具che还需体的缓存实现来完成
spring.cache.type=redis
#开启了一个sql语句执行的日志,这种debug方法有很多
logging.level.com.text.mapper=debug

#这是映射pojo实体类和mapper.xml的映射
mybatis.type-aliases-package=com.text.pojo
mybatis.mapper-locations=classpath:com/text/mapper/*.xml

3.开始配置我们的sptingboot的启动类

package com.text;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication()
//这是一个一个包扫描的注入和直接在接口mapper里面写@mapper差别不大
[好处:这样配置简单]
@MapperScan(basePackages ="com.text.mapper" )
//开启缓存
/*
@EnableCaching注解是spring framework中的注解驱动的缓存管理功能。
自spring版本3.1起加入了该注解。如果你使用了这个注解,
那么你就不需要在XML文件中配置cache manager了。

当你在配置类(@Configuration)上使用@EnableCaching注解时,
会触发一个post processor,
这会扫描每一个spring bean,查看是否已经存在注解对应的缓存。如果找到了,
就会自动创建一个代理拦截方法调用,使用缓存的bean执行处理。
 */
@EnableCaching
public class BootSsmRedsiDemoApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(BootSsmRedsiDemoApplication.class, args);
    }
}

4.我们先写一个缓存的配置,首先pom.xml引入fastjson,配置application.properties
开启 spring.cache.type=redis,在项目包下创建一个config的配置包,随后来注入配置RedisCacheManager,下面就是配置注入的代码块,所有的配置前面都配置了大家可以自己看一下。

package com.text.config;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

//一个配置类
@Configuration
/*配置redis序列器
 * */
public class RedisCacheConfig {
    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory){
        //redis的写入器
      RedisCacheWriter writer=RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
      RedisCacheConfiguration configuration=RedisCacheConfiguration.defaultCacheConfig()
    /*键序列化器
     * RedisSerializationContext配置序列化器上下文
     */
    .serializeKeysWith(RedisSerializationContext
            .SerializationPair.fromSerializer(new StringRedisSerializer()))
    //值的序列化器
    .serializeValuesWith(RedisSerializationContext
            .SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
   return  new RedisCacheManager(writer,configuration);
    }
}
5.编写pojo实体类
package com.text.pojo;
import org.apache.ibatis.annotations.Mapper;
import java.io.Serializable;
public class User implements Serializable {
    private  Integer id;
    private  String userName;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}

6.编写mapper接口层

package com.text.mapper;
import com.text.pojo.User;
import org.springframework.stereotype.Repository;
import java.util.List;
//@repository则需要在Spring中配置扫描包地址,然后生成dao层的bean
public interface UserMapper {
    //查询
    List<User>all();
    //增加
    int save(User user);
    //根据id查询
    User findById(Integer id);
    //删除
    int  delete(Integer id);
    //修改
    int update(User user);
}

7.编写mybatis的mapper.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="com.text.mapper.UserMapper">

     <select id="all" resultType="User">
          select id,userName from  smbms_user order by id desc
     </select>
     
    <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
         insert into  smbms_user (userName) value (#{userName})
    </insert>
    
     <select id="findById" parameterType="int" resultType="User">
          select id,userName from smbms_user where id=#{id}
     </select>
     
    <delete id="delete" parameterType="int">
          delete  from  smbms_user where id=#{id}
    </delete>
    
    <update id="update" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        update  smbms_user set userName=#{userName} where id=#{id}
    </update>
</mapper>

8.编写service接口层

package com.text.service;
import com.text.pojo.User;
import java.util.List;
public interface UserService {
    //查询
    List<User> all();
    //这里添加数据的时候要使用对象 然后把数据返回给redis
    User save(User user);
    //根据id查询
    User findById(Integer id);
    //删除
    int delete(Integer id);
    //修改
    User modify(User user);
}

9.编写serviceimpl的业务实现层
[大家看到下面的代码在redis缓存中的注解有疑惑把,不慌咱们看下面我会给大家介绍]

package com.text.service.impl;
import com.text.mapper.UserMapper;
import com.text.pojo.User;
import com.text.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl  implements UserService {
    private UserMapper userMapper;

    public UserMapper getUserMapper() {
        return userMapper;
    }
    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
    @Override
    //在Spring缓存注解中的key属性中使用SpEL表达式
    //Cacheable定义缓存,用于触发缓存
    @Cacheable(value = {"user"},key="#root.methodName")
    public List<User> all() {
        return userMapper.all();
    }
    @Override
    //主键记得在xml中回填
    //定义更新缓存,触发缓存更新
    @CachePut(value={"user"},key = "#user.id")
    public User save(User user) {
        userMapper.save(user);
        return  user;
    }
    @Override
    //定义更新缓存,触发缓存更新
    @Cacheable(value = {"user"},key = "#id")
    public User findById(Integer id) {
        return userMapper.findById(id);
    }
    @Override
    //从数据库中删除数据同时,从缓存中移除对象
    //定义清除缓存,触发缓存清除
    @CacheEvict(value = {"user"},key = "#id")
    public int delete(Integer id) {
        return userMapper.delete(id);
    }
    @Override
    //定义更新缓存,触发缓存更新
    @CachePut(value={"user"},key = "#user.id")
    public User modify(User user) {
        userMapper.update(user);
        return user;
    }
}

在Spring缓存注解中的key属性中使用SpEL表达式

在这里插入图片描述

Spring Cache-缓存注解

在这里插入图片描述

  • 注解@Cacheable 和@CachePut 都可以保存缓存键值对,只是它们的方式略有不同,
    请注意二者的区别,它们只能运用于有返回值的方法中。 而删除缓存 key 的@CacheEvict 则可以用在 void
    的方法上,因为它并不需要去保存任何值 。
    上述注解都能标注到类或者方法之上,如果放到类上,则对所有的方法都有效,如果放到方法上,则只是对方法有效。 在大部分情况下,会放置到方法上。
    @Cacheable 和 @CachePut 可以配置的属性接近。 一般而言,对于查询,我们会考虑使用@Cacheable
    对于插入和修改,考虑使用@CachePut 对于删除操作,我们会考虑使用@CacheEvict。
    10.开始写Controller层
    描述这里都是使用的json值的测试并没有WEB
package com.text.controller;
import com.text.pojo.User;
import com.text.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
    private UserService userService;

    public UserService getUserService() {
        return userService;
    }
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    @GetMapping("/all")
    public List<User> all(){
        return  userService.all();
    }
    @GetMapping("/save")
    public User save(){
      User user=new User();
      user.setUserName("手撕");
      userService.save(user);
        return user;
    }
    @RequestMapping("/{id}")
    public  User findById(@PathVariable("id")Integer id){
        return  userService.findById(id);
    }
    @GetMapping("/delete")
    public int delete(Integer id){
        return  userService.delete(id);
    }
    @GetMapping("/update")
    public  User update(){
        User user=new User();
        user.setId(59);
        user.setUserName("哈哈");
        return userService.modify(user);
    }
}

下面展示项目的目录结构
在这里插入图片描述

本次演练结束!!!有兴趣的可以在学习一下多级缓存 实现缓存的方式也有很多大家可以百度学习

一、什么是缓存
1、Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问
2、凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为 Cache
二、缓存的分类
1、基于web应用的系统架构图

2、在系统架构的不同层级之间,为了加快访问速度,都可以存在缓存
操作系统磁盘缓存->减少磁盘机械操作
数据库缓存->减少文件系统I/O
应用程序缓存->减少对数据库的查询
Web服务器缓存->减少应用服务器请求
客户端浏览器缓存->减少对网站的访问

三、操作系统缓存
1、文件系统提供的Disk Cache:操作系统会把经常访问到的文件内容放入到内存当中,由文件系统来管理

2、当应用程序通过文件系统访问磁盘文件的时候,操作系统从Disk Cache当中读取文件内容,加速了文件读取速度

3、Disk Cache由操作系统来自动管理,一般不用人工干预,但应当保证物理内存充足,以便于操作系统可以使用尽量多的内存充当Disk Cache,加速文件读取速度

4、特殊的应用程序对文件系统Disk Cache有很高的要求,会绕开文件系统Disk Cache,直接访问磁盘分区,自己实现Disk

5、Cache策略
Oracle的raw device(裸设备) – 直接抛弃文件系统
MySQL的InnoDB: innodb_flush_method = O_DIRECT

四、数据库缓存
1、重要性
数据库通常是企业应用系统最核心的部分
数据库保存的数据量通常非常庞大
数据库查询操作通常很频繁,有时还很复杂
以上原因造成数据库查询会引起非常频繁的磁盘I/O读取操作,迫使CPU挂起等待,数据库性能极度低下
2、缓存策略
a、Query Cache
以SQL作为key值缓存查询结果集
一旦查询涉及的表记录被修改,缓存就会被自动删除
设置合适的Query Cache会极大提高数据库性能
Query Cache并非越大越好,过大的Qquery Cache会浪费内存。
MySQL: query_cache_size= 128M
b、Data Buffer
data buffer是数据库数据在内存中的容器
data buffer的命中率直接决定了数据库的性能
data buffer越大越好,多多益善
MySQL的InnoDB buffer:innodb_buffer_pool_size = 2G
MySQL建议buffer pool开大到服务器物理内存60-80%
五、应用程序缓存
1、对象缓存
由O/R Mapping框架例如Hibernate提供,透明性访问,细颗粒度缓存数据库查询结果,无需业务代码显式编程,是最省事的缓存策略
当软件结构按照O/R Mapping框架的要求进行针对性设计,使用对象缓存将会极大降低Web系统对于数据库的访问请求
良好的设计数据库结构和利用对象缓存,能够提供极高的性能,对象缓存适合OLTP(联机事务处理)应用
2、查询缓存
对数据库查询结果集进行缓存,类似数据库的Query Cache
适用于一些耗时,但是时效性要求比较低的场景。查询缓存和对象缓存适用的场景不一样,是互为补充的
当查询结果集涉及的表记录被修改以后,需要注意清理缓存
3、页面缓存
a、作用
针对页面的缓存技术不但可以减轻数据库服务器压力,还可以减轻应用服务器压力
好的页面缓存可以极大提高页面渲染速度
页面缓存的难点在于如何清理过期的缓存
b、分类
I、动态页面静态化
利用模板技术将访问过一次的动态页面生成静态html,同时修改页面链接,下一次请求直接访问静态链接页面
动态页面静态化技术的广泛应用于互联网CMS/新闻类Web应用,但也有BBS应用使用该技术,例如Discuz!
无法进行权限验证,无法显示个性化信息
可以使用AJAX请求弥补动态页面静态化的某些缺点
II、Servlet缓存
针对URL访问返回的页面结果进行缓存,适用于粗粒度的页面缓存,例如新闻发布
可以进行权限的检查
OScache提供了简单的Servlet缓存(通过web.xml中的配置)
也可以自己编程实现Servlet缓存
III、页面内部缓存
针对动态页面的局部片断内容进行缓存,适用于一些个性化但不经常更新的页面(例如博客)
OSCache提供了简单的页面缓存
可以自行扩展JSP Tag实现页面局部缓存

六、web服务器端缓存
基于代理服务器模式的Web服务器端缓存,如squid/nginx
Web服务器缓存技术被用来实现CDN(内容分发网络 content delivery network)
被国内主流门户网站大量采用
不需要编程,但仅限于新闻发布类网站,页面实时性要求不高
七、基于ajax的浏览器缓存

  • 使用AJAX调用的时候,将数据库在浏览器端缓存
  • 只要不离开当前页面,不刷新当前页面,就可以直接读取缓存数据
  • 只适用于使用AJAX技术的页面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值