12、SpringBoot-mybatis-plus-ehcache


系列导航

未完待续

1、数据库中创建表

CREATE TABLE TEST_BLOCK_T   
(
  BLOCK_ID         VARCHAR2(10 BYTE) PRIMARY   KEY,    --编码
  BLOCK_NAME       VARCHAR2(200 BYTE)                    --资源名称 
); 

2、pom.xml依赖

 <properties>
        <java.version>1.8java.version>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <spring-boot.version>2.1.16.RELEASEspring-boot.version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>

        
        <dependency>
            <groupId>net.sf.ehcachegroupId>
            <artifactId>ehcacheartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-cacheartifactId>
        dependency>


        
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.2.0version>
        dependency>

        
        <dependency>
            <groupId>com.oraclegroupId>
            <artifactId>ojdbc6artifactId>
            <version>11.2.0.3version>
        dependency>


    dependencies>

3、工程结构

4、配置文件

application.properties

# 应用名称
spring.application.name=demo
# 应用服务 WEB 访问端口
server.port=8080

spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:/config/ehcache.xml

# 数据库设置
spring.datasource.driverClassName=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@192.168.0.100:1521:orcl
spring.datasource.username=zy
spring.datasource.password=1

#mybatis-plus控制台打印sql
mybatis-plus.configuration.log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

ehcache.xml

<ehcache>

    
    <diskStore path="java.io.tmpdir"/>


    <defaultCache
            maxElementsInMemory="10000"
            eternal="true"
            overflowToDisk="false"
    />
    <cache
            name="myCache"
            maxElementsInMemory="10000"
            eternal="true"
            overflowToDisk="false"
    />

    
 

ehcache>
注:配置文件中注意eternal参数,建议设置为true让其一直存在缓存中,否则timeToIdleSeconds、timeToLiveSeconds参数如果设置的时间太短就会导致缓存删除了,导致缓存失效。具体参数含义看配置文件里的注释

5、源码

package com.example.ehcache;

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

@SpringBootApplication
@EnableCaching
@MapperScan("com.example.ehcache.mapper")
public class EhcacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(EhcacheApplication.class, args);
    }

}
package com.example.ehcache.controller;

import com.example.ehcache.domain.Block;
import com.example.ehcache.service.DemoService;
import org.springframework.web.bind.annotation.*;

/**
 * @author lz
 * @date 2018/12/27
 */
@RestController
@RequestMapping("/cache")
public class CacheController {
    private final DemoService demoService;

    public CacheController(DemoService demoService) {
        this.demoService = demoService;
    }

    @PostMapping(  value = "/put" )
    @ResponseBody
    public void put() {
        Block block = new Block();
        block.setBlockId("9999");
        block.setBlockName("哈哈哈");
        demoService.save(block);

    }


    @GetMapping(value = "/get" )
    @ResponseBody
    public void cacheable() {
        Block block = new Block();
        block.setBlockId("9999");
        Block blockResult  =  demoService.findOne(block);
        System.out.println("controller:"+blockResult);

    }


    @PostMapping(  value = "/remove")
    @ResponseBody
    public String evict() {
        String id = "9999";
        demoService.remove(id);
        return "ok";
    }



    @PostMapping(  value = "/put1" )
    @ResponseBody
    public void put1() {
        String id ="oiline";
        String name ="100";
        demoService.put(id, name);

    }


    @GetMapping(value = "/get1" )
    @ResponseBody
    public void cacheable1() {
        String id ="oiline";
        String result = demoService.get(id);
       System.out.println("取到的数据result是:"+result);

    }

    @PostMapping(  value = "/remove1")
    @ResponseBody
    public String evict1() {
        String id ="oiline";
        demoService.delete(id);
        return "ok";
    }

}
package com.example.ehcache.domain;


import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

/**
 * 

* 。 *

* *
@author yc * @since 2021-09-18 */ @TableName(value = "TEST_BLOCK_T") public class Block { private static final long serialVersionUID = 1L; @TableId private String blockId; /** * $field.comment。 * */ private String blockName; public String getBlockId() { return blockId; } public void setBlockId(String blockId) { this.blockId = blockId; } public String getBlockName() { return blockName; } public void setBlockName(String blockName) { this.blockName = blockName; } @Override public String toString() { return "TEST_BLOCK_T{" + "blockId='" + blockId + '\'' + ", blockName='" + blockName + '\'' + '}'; } }
package com.example.ehcache.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import com.example.ehcache.domain.Block;



public interface BlockMapper extends BaseMapper {

}
package com.example.ehcache.service;

import com.example.ehcache.domain.Block;

import java.util.Map;


/**
 * @author lz
 * @date 2018/12/27
 */
public interface DemoService {
    Block save(Block block);

    void remove(String id);

    Block findOne(Block block);

    String put(String id,String value);
    String get(String id);
    void delete(String id);

}
package com.example.ehcache.service.impl;

import com.example.ehcache.domain.Block;
import com.example.ehcache.mapper.BlockMapper;
import com.example.ehcache.service.DemoService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
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.HashMap;
import java.util.Map;

/**
 * @author lz
 * @date 2018/12/27
 */
@Service
@CacheConfig(cacheNames = {"myCache"})
public class DemoServiceImpl implements DemoService {

    /**
     * 注意:如果没有指定key,则方法参数作为key保存到缓存中
     */
    @Autowired
    BlockMapper blockMapper;
    /**
     * @param block
     * @return
     * @CachePut缓存新增的或更新的数据到缓存,其中缓存的名称为people,数据的key是person的id
     */
    @CachePut(key = "#block.blockId")
    @Override
    public Block save(Block block) {
        blockMapper.insert(block);
        System.out.println("新增");
        System.out.println("为id,key为:" + block.getBlockId() + "数据做了缓存");
        return block;
    }

    /**
     * @param id
     * @CacheEvict从缓存people中删除key为id的数据
     */
    @CacheEvict
    @Override
    public void remove(String id) {
        System.out.println("删除");
        System.out.println("删除了id,key为" + id + "的数据缓存");
        //personRepository.deleteById(id);
    }

    /**
     * @param block
     * @return
     * @Cacheable缓存key为person的id数据到缓存people中
     */
    //@Cacheable(value="HelloWorldCache", key="#param")  这里可以用value指定缓存的名称
    // 因为在@CacheConfig(cacheNames = {"myCache"}) 指定过了所以这里不用重复指定
    @Cacheable(key = "#block.blockId")
    @Override
    public Block findOne(Block block) {
        Block BlockResult = blockMapper.selectById(block.getBlockId());
        System.out.println("查询");
        System.out.println("为id,key为:"+ block.getBlockId()  + "数据做了缓存");
        return BlockResult;
    }

    //-----------------------单纯存一个数的缓存,不需要存入数据库里-----------------------------------
    private final Map map=new HashMap<>();


    @Override
    @CachePut( key = "#id")
    public String put(String id, String value) {
        System.out.println("插入数据:"+id+" ==> "+value);
        map.put(id,value);

        return value;
    }

    @Override
    @Cacheable( key = "#id")
    public String get(String id) {
        System.out.println("查询数据:"+id);

       String result=map.get(id);
        if (result==null){
            return "查询的数据不存在";
        }

        return result;
    }


    @CacheEvict( key = "#id")
    public void delete(String id){
        System.out.println("删除数据:"+id);
        map.remove(id);
    }


}

6、测试

(1)get方法 : http://localhost:8080/cache/get  获取数据

  结果:

  说明:此时缓存和数据库里都没有数据。缓存里没有数据所以查了一次数据库。

(2)post方法 : http://localhost:8080/cache/put   新增数据

  结果:

 说明:此时向缓存和数据库里增加了数据。

(3)get方法 : http://localhost:8080/cache/get   获取数据

  结果:

  说明:此时缓存里有数据了,就没有查数据库找数据。(这是该缓存技术的闪光点)

(4)post方法 : http://localhost:8080/cache/remove  删除数据

  结果:

 说明:此时删除了缓存里的数据。注:代码里并没有删除数据库的数据

(5)get方法 : http://localhost:8080/cache/get   再次获取数据

  结果:

  说明:此时由于缓存里有数据,所以查询一次数据库。(这是该缓存技术的闪光点)

(6)get方法 : http://localhost:8080/cache/get   获取数据

  结果:

  说明:经过上一个查询,缓存里又有数据了,所以直接从缓存里取数据。

7、如何只单纯放一个数据在缓存里,不存在数据库里

请看如下Controller中的方法,测试方法和上面一样。

http://localhost:8080/cache/get1      GET

http://localhost:8080/cache/put1      POST

http://localhost:8080/cache/remove1  POST