zoukankan      html  css  js  c++  java
  • 2020.03.17 springboot缓存相关

    出自尚硅谷雷峰阳老师讲解的Spring Boot整合篇,地址:

    http://www.atguigu.com/download_detail.shtml?v=38

    1、JSR107规范

    CachingProvider【管理CacheManager】、CacheManager【管理Cache】、Cache【一个cache仅被一个CacheManager管理】、Entry【一个个缓存的内容】、Expiry【有效期】
    2、Spring的缓存抽象
    注意两点:
    ①确定方法需要被缓存以及他们的缓存策略    
    ②从缓存中读取之前缓存存储的数据
    缓存注解及作用:
    @EnableCaching:开启基于注解的缓存
    @Cacheable:主要针对方法配置,能够根据方法的请求参数对其结果进行缓存【主要用于查询】
    @CachePut:保证方法被调用,又希望结果被缓存。【主要用于修改】
    @CacheEvict:清空缓存【主要用于删除】
    SPEL表达式:
    名字
    位置
    描述
    示例
    methodName 
    root object 当前被调用的方法名 #root.methodName
    result 
    evaluation context
    方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,’cache put’的表达式 ’cache evict’的表达式beforeInvocation=false) 
    #result 
    argument name
    evaluation context 
    方法参数的名字. 可以直接 #参数名 ,也可以使用 #p0或#a0 的形式,0代表参数的索引; 
    #iban 、 #a0 、 #p0

    3、缓存使用

    pom文件:

    <?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>1.5.12.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.study.springboot</groupId>
        <artifactId>cache-study</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>cache-study</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-cache</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- 数据库相关 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jdbc</artifactId>
            </dependency>
    
            <!-- mybatis和springboot整合 -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.0</version>
            </dependency>
    
            <!-- 数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.16</version>
            </dependency>
    
            <!-- 日志 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </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>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

    主启动类:

    package com.study.springboot.cache;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    @SpringBootApplication
    @EnableCaching
    public class CacheStudyApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(CacheStudyApplication.class, args);
    	}
    
    }

    yml文件:

    server:
      port: 8001
      tomcat:
        uri-encoding: UTF-8
    spring:
      application:
        name: springboot-cache
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springboot-cache?useUnicode=true&characterEncoding-utf-8&useSSL=false&serverTimezone=UTC #需要加时区
        username: root
        password: 自己的密码
        initialSize: 5
        minIdle: 5
        maxActive: 20
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1 FROM DUAL
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
        filters: stat,wall,log4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    
      http:
        encoding:
          charset: utf-8
          force: true
          enabled: true
      redis:
        host: 192.168.213.128#自己的redis主机
    mybatis:
      mapperLocations: classpath:mapper/*.xml
      type-aliases-package: com.atguigu.springcloud.entities
      configuration:
        map-underscore-to-camel-case: true
    

      

    controller:

    package com.study.springboot.cache.controller;
    
    import com.study.springboot.cache.entity.Employee;
    import com.study.springboot.cache.service.EmployeeService;
    import lombok.extern.slf4j.Slf4j;
    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.RestController;
    
    @RestController
    @Slf4j
    public class EmpController {
    
        @Autowired
        private EmployeeService employeeService;
    
    
        @GetMapping("/emp/{id}")
        public Employee getEmpById(@PathVariable("id") Integer id){
            return employeeService.queryById(id);
        }
    }

    ------------------------------------------------------------------------------
     
    package com.study.springboot.cache.controller;


    import com.study.springboot.cache.entity.Department;
    import com.study.springboot.cache.service.DepartmentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheConfig;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;


    @RestController
    public class DepartmentController {

    @Autowired
    private DepartmentService departmentService;

    @GetMapping("/dept/{id}")
    public Department getDeptById(@PathVariable("id") Integer id){
    return departmentService.getDeptById(id);
    }
    }
     

    service

    package com.study.springboot.cache.service;
    
    import com.study.springboot.cache.entity.Employee;
    import com.study.springboot.cache.mapper.EmployeeMapper;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.cache.annotation.Caching;
    import org.springframework.stereotype.Service;
    
    @Service
    @Slf4j
    public class EmployeeService {
    
        @Autowired
        private EmployeeMapper employeeMapper;
    
    
        @Caching(
                cacheable = @Cacheable(value="emp",cacheManager = "employmentRedisCacheManager")
        )
        public Employee queryById(Integer id){
            log.info("查询id为:"+id+"数据");
            return employeeMapper.selectEmp(id);
        }
    }

    ------------------------------------------------------------------------------
    package com.study.springboot.cache.mapper;


    import com.study.springboot.cache.entity.Department;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;

    @Mapper
    public interface DepartmentMapper {

    public Department selectDeptById(@Param("id") Integer id);
    }
     

    mapper:

    package com.study.springboot.cache.mapper;
    
    import com.study.springboot.cache.entity.Employee;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    
    @Mapper
    public interface EmployeeMapper {
    
        //根据id查询
        public Employee selectEmp(@Param("id") Integer id);
    
        //修改
        public void updateEmp(Employee employee);
    
    }

    ------------------------------------------------------------------------------

    package com.study.springboot.cache.mapper;


    import com.study.springboot.cache.entity.Department;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;

    @Mapper
    public interface DepartmentMapper {

    public Department selectDeptById(@Param("id") Integer id);
    }
     

    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.study.springboot.cache.mapper.EmployeeMapper">
    
    
    
        <!--public Employee selectEmp(@Param("id") Integer id);-->
        <select id="selectEmp" parameterType="Integer" resultMap="BaseResultMap">
            select * from employee where id = #{id}
        </select>
    
        <!-- public void updateEmp(Employee employee); -->
        <update id="updateEmp" parameterType="com.study.springboot.cache.entity.Employee">
            update employee set
            lastName = #{lastName},
            email = #{email},
            gender = #{gender},
            d_id = #{dId}
            where
            id = #{id}
        </update>
    
        <resultMap id="BaseResultMap" type="com.study.springboot.cache.entity.Employee" autoMapping="true">
    
        </resultMap>
        
    </mapper>

    ------------------------------------------------------------------------------

    <?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.study.springboot.cache.mapper.DepartmentMapper">



    <!--public Department selectDeptById(@Param("id") Integer id);-->
    <select id="selectDeptById" parameterType="Integer" resultMap="BaseResultMap">
    select * from department where id = #{id}
    </select>

    <resultMap id="BaseResultMap" type="com.study.springboot.cache.entity.Department" autoMapping="true">

    </resultMap>

    </mapper>

    只有springboot版本为1.xx时才能自定义,版本为2.xx时没找到对应的构造函数 个人观点【没找到对应的构造函数】

    自定义缓存管理器时注意别写get

     1 import com.study.springboot.cache.entity.Department;
     2 import com.study.springboot.cache.entity.Employee;
     3 import org.springframework.context.annotation.Bean;
     4 import org.springframework.context.annotation.Configuration;
     5 import org.springframework.context.annotation.Primary;
     6 import org.springframework.data.redis.cache.RedisCacheManager;
     7 import org.springframework.data.redis.connection.RedisConnectionFactory;
     8 import org.springframework.data.redis.core.RedisTemplate;
     9 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    10 
    11 import java.net.UnknownHostException;
    12 
    13 
    14 @Configuration
    15 public class MyRedisConfig {
    16 
    17 
    18     @Bean
    19     public RedisTemplate<Object,Employee> getEmployeeRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    20         RedisTemplate<Object,Employee> template = new RedisTemplate<Object,Employee>();
    21         template.setConnectionFactory(redisConnectionFactory);
    22         //自己配置序列化器
    23         Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
    24         template.setDefaultSerializer(serializer);
    25         return template;
    26     }
    27 
    28     @Bean
    29     public RedisTemplate<Object,Department> getDepartmentRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    30         RedisTemplate<Object,Department> template = new RedisTemplate<Object,Department>();
    31         template.setConnectionFactory(redisConnectionFactory);
    32         //自己配置序列化器
    33         Jackson2JsonRedisSerializer<Department> serializer = new Jackson2JsonRedisSerializer<Department>(Department.class);
    34         template.setDefaultSerializer(serializer);
    35         return template;
    36     }
    37 
    38     @Bean
    39     public RedisCacheManager employmentRedisCacheManager(RedisTemplate<Object,Employee> employeeRedisTemplate){
    40         RedisCacheManager redisCacheManager = new RedisCacheManager(employeeRedisTemplate);
    41         redisCacheManager.setUsePrefix(true);
    42 
    43         return redisCacheManager;
    44     }
    45 
    46     @Primary
    47     @Bean
    48     public RedisCacheManager departmentRedisCacheManager(RedisTemplate<Object,Department> departmentRedisTemplate){
    49         RedisCacheManager redisCacheManager = new RedisCacheManager(departmentRedisTemplate);
    50         redisCacheManager.setUsePrefix(true);
    51 
    52         return redisCacheManager;
    53     }
    54 }

    测试类:

    redis命令网址:http://www.redis.cn/commands.html

    package com.study.springboot.cache;
    
    import com.study.springboot.cache.entity.Employee;
    import com.study.springboot.cache.service.EmployeeService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class CacheStudyApplicationTests {
    
        @Test
        public void contextLoads() {
        }
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        @Autowired
        private EmployeeService employeeService;
    
        @Autowired
        private RedisTemplate<Object,Employee> employeeRedisTemplate;
    
        @Test
        public void testRedis(){
            ValueOperations<String, String> stringValueOperations = stringRedisTemplate.opsForValue();
            //stringValueOperations.append("msg","hello");
    
            Employee employee = employeeService.queryById(2);
            //stringValueOperations.append("emp:1",employee.toString());
    
            employeeRedisTemplate.opsForValue().set("emp:1",employee);
    
        }
    
    }

    建表sql(老师提供的课件中有):

    /*
    Navicat MySQL Data Transfer
    
    Source Server         : 本地
    Source Server Version : 50528
    Source Host           : 127.0.0.1:3306
    Source Database       : springboot_cache
    
    Target Server Type    : MYSQL
    Target Server Version : 50528
    File Encoding         : 65001
    
    Date: 2018-04-27 14:54:04
    */
    
    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Table structure for department
    -- ----------------------------
    DROP TABLE IF EXISTS `department`;
    CREATE TABLE `department` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `departmentName` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Table structure for employee
    -- ----------------------------
    DROP TABLE IF EXISTS `employee`;
    CREATE TABLE `employee` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `lastName` varchar(255) DEFAULT NULL,
      `email` varchar(255) DEFAULT NULL,
      `gender` int(2) DEFAULT NULL,
      `d_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
  • 相关阅读:
    try-catch- finally块中, finally块唯一不执行的情况是什么?
    Mac下 pygame.image.load不显示图片解决方法
    Ubuntu中sudo速度慢的解决方法(转载)
    [Mac Terminal] ___中断跳出死循环
    Fuzzy logic
    Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.4 Predicates and Quantifiers
    Bugs -----The largest and most interesting kind of thing.
    A Brief, Incomplete, and Mostly Wrong History of Programming Languages
    MIPS指令集
    >> 计算机的数据表示
  • 原文地址:https://www.cnblogs.com/lxw-all/p/12512149.html
Copyright © 2011-2022 走看看