Spring Cache 缓存

Spring从版本3.1开始,支持透明地向现有的Spring应用程序添加缓存。与事务支持类似,缓存抽象允许一致地使用各种缓存解决方案,同时对代码的影响最小。

在Spring Framework 4.1中,缓存抽象得到了显着扩展,支持JSR-107注释和更多自定义选项。

Spring Cache默认使用ConcurrentMapCache实现存储

详情查看官网

注解说明

@Cacheable

用它来划分可缓存的方法,即结果存储在缓存中的方法,以便在后续调用(使用相同的参数)时返回缓存中的值,而不必实际调用该方法。在最简单的形式中,批注声明需要与带批注的方法关联的缓存的名称

@Cacheable("books")
public Book findBook(ISBN isbn) {...}

@CacheEvict

缓存抽象不仅允许填充缓存存储,还允许逐出。此过程对于从缓存中删除陈旧或未使用的数据非常有用。与 相反,划分执行缓存逐出的方法(即充当从缓存中删除数据的触发器的方法)。与其同级类似,需要指定一个或多个受操作影响的缓存,允许指定自定义缓存和密钥分辨率或条件,并具有一个额外的参数 (),该参数指示是否需要执行缓存范围的逐出,而不仅仅是条目逐出(基于密钥)。

@CacheEvict(cacheNames="books", allEntries=true) 
public void loadBooks(InputStream batch)

@Caching

有时,需要指定相同类型(如 或 )的多个批注,例如,因为条件或键表达式在不同缓存之间是不同的。 允许在同一方法上使用多个嵌套 、 和注释。

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)

@CacheConfig

到目前为止,我们已经看到缓存操作提供了许多自定义选项,并且可以为每个操作设置这些选项。但是,如果某些自定义选项应用于类的所有操作,则配置这些选项可能会很繁琐。例如,指定要用于类的每个缓存操作的缓存名称可以替换为单个类级定义。这就是发挥作用的地方。

@CacheConfig("books") 
public class BookRepositoryImpl implements BookRepository {

    @Cacheable
    public Book findBook(ISBN isbn) {...}
}

@EnableCaching

重要的是要注意,即使声明缓存注释不会自动触发它们的操作 - 就像Spring中的许多事情一样,该功能必须以声明方式启用(这意味着如果您怀疑缓存是罪魁祸首,您可以通过仅删除一个配置行而不是代码中的所有注释来禁用它)。

要启用缓存批注,请将该批注添加到其中一个类中:@EnableCaching@Configuration

@Configuration
@EnableCaching
public class AppConfig {
}

用法示例

1.新建springboot项目并启用缓存

@EnableCaching
@SpringBootApplication
public class DemoCacheApplication {

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

}

2.新建Book对象

public class Book {

    private String id;
    private String isbn;
    private String title;

    public Book(String id, String isbn, String title) {
        this.id = id;
        this.isbn = isbn;
        this.title = title;
    }
		
	//Get and Set ....	
}    

3.Repository层

这里简单模拟数据库查询数据

public interface BookRepository {

    List<Book> findAll();

    boolean delBook(String id);

    Book updateBook(Book book);

}
@Repository
public class BookRepositoryImpl implements BookRepository {

    private static List<Book> books = new ArrayList<>();

    @PostConstruct
    private void init(){
        System.out.println("初始化books数据");
        books.add(new Book("1","第一部", "射雕英雄传"));
        books.add(new Book("2", "第二部", "射雕英雄传"));
        books.add(new Book("3", "第三部", "射雕英雄传"));
        books.add(new Book("4","第四部", "射雕英雄传"));
        books.add(new Book("5","第五部", "射雕英雄传"));
    }

    @Override
    public List<Book> findAll() {
        return books;
    }

    @Override
    public boolean delBook(String id) {
        List<Book> collect = books.stream().filter(book -> id.equals(id)).collect(Collectors.toList());
        return books.remove(collect.get(0));
    }

    @Override
    public Book updateBook(Book book) {
        List<Book> collect = books.stream().filter(dbook -> dbook.getId().equals(book.getId())).collect(Collectors.toList());
        books.remove(collect.get(0));
        books.add(book);
        List<Book> newBook = books.stream().filter(dbook -> dbook.getId().equals(book.getId())).collect(Collectors.toList());
        return newBook.get(0);
    }

}

3.Service层

public interface BookService {

    List<Book> findAll();

    boolean delBook(String id);

    Book updateBook(Book book);

}

缓存使用示例(get,put)

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    @Cacheable(value = "book_cache", unless = "#result == null")
    @Override
    public List<Book> findAll() {
        System.out.println("findAll 获取数据时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return bookRepository.findAll();
    }

    @CacheEvict(value = "book_cache", key = "#id")
    @Override
    public boolean delBook(String id) {
        System.out.println("delBook 操作数据时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return bookRepository.delBook(id);
    }

    @CachePut(value = "book_cache", key = "#book.id", unless = "#result == null")
    @Override
    public Book updateBook(Book book) {
        System.out.println("updateBook 操作数据时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return bookRepository.updateBook(book);
    }

}

4.Controller层

用于接口测试查看效果

@RestController
public class BookController {

    @Autowired
    private BookService bookService;

    @GetMapping("books")
    public List<Book> findAll(){
        return bookService.findAll();
    }

    @PutMapping("books")
    public Book putBook(@RequestBody Book book){
        return bookService.updateBook(book);
    }

    @DeleteMapping("books/{id}")
    public boolean delBook(@PathVariable String id){
        return bookService.delBook(id);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值