1.什么是缓存(cache)
简单定义:就是计算机内存中的一段数据。
2.内存中数据的特点
1.读写快 2.断电立即丢失
3.缓存解决了什么问题?
1.提高网站吞吐量,提高网站运行效率。
2.核心解决的 问题:减轻原始数据库的访问压力。
4.既然缓存能提高效率,那项目中的所有数据加入缓存岂不是更好?
注意:使用缓存时一定是数据库中数据极少发生修改,更多用于查询这种情况。
5.本地缓存和分布式缓存区别?
本地缓存:存在应用服务器内存中数据称之为本地缓存(local cache)。
分布式缓存:存储在当前应用服务器内存之外数据称之为分布式缓存(distribute cache)。
集群:将同一种服务的多个节点放在一起共同对系统提供服务过程称之为集群,比如mysql集群,tomcat集群等。
分布式:有多个不同服务集群功能对系统提供服务这个系统称之为分布式系统(distribute system)。
6.利用mybatis自身本地缓存结合redis实现分布式缓存
a.mybatis中应用级缓存(二级缓存) SqlSessionFactory级别缓存 所有会话共享
b.如何开启(二级缓存)
mapper.xml
<cache />
—本地缓存
7.实现
a.引入相关依赖
<!-- 引入mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- 引入mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- 引入阿里巴巴druid依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.19</version>
</dependency>
b.修改相关配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/emp?characterEncoding=UTF-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
mybatis.mapper-locations=classpath:com/wx/mapper/*.xml
mybatis.type-aliases-package=com.wx.entity
logging.level.com.wx.dao=debug
c.实现mybatis相关业务
e.开启mybatis二级缓存
<cache /> --本地缓存
开启二级缓存后,二次访问就不会再首先访问数据库,而是访问缓存列表,但是 要求必须实现对象序列号(implements Serializable
),不然就会报错:
package com.wx.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain=true)
public class User implements Serializable {
private String name;
private Integer age;
private String sex;
}
*ps:本地缓存,当java虚拟机重启之后,放在本地的缓存会随着服务状态发生改变,下一次访问还是得先访问数据库,xianr 本地缓存不好,我们采用分布式缓存,分布式缓存的丢失与应用服务器的关机与断电没有关系,任意一个请求访问任意一个集群,都会将数据放入分布式缓存中
**
8.自定义Rediscache实现
a.使用RedisCache实现
<cache type="org.apache.ibatis.cache.RedisCache" />
b
package com.wx.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.applet.AppletContext;
//用来获取Springboot创建好的工厂
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
//保留下来的工厂
private static ApplicationContext applicationContext;
//将创建好的工厂以参数形式传递给这个类
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
//提供在工厂中获取对象的方法
public static Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
}
c
package com.wx.cache;
import com.wx.util.ApplicationContextUtils;
import org.apache.ibatis.cache.Cache;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
//自定义Redis缓存的实现
public class RedisCache implements Cache {
private final String id;
//必须存在构造方法
public RedisCache(String id){
System.out.println("id:"+id);
this.id=id;
}
//返回cache的唯一标识
@Override
public String getId() {
return this.id;
}
//缓存中放入值 RedisTemplate
@Override
public void putObject(Object key, Object value) {
System.out.println("key:"+key.toString());
System.out.println("value:"+value);
//通过application工具类获取redisTemplate
RedisTemplate redisTemplate=(RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//使用Redis中的hash类型作为缓存存储模型key hashkey value
redisTemplate.opsForHash().put(id.toString(),key.toString(),value);
}
//缓存中获取值
@Override
public Object getObject(Object key) {
System.out.println("key:"+key.toString());
return null;
}
@Override
public Object removeObject(Object o) {
return null;
}
@Override
public void clear() {
}
@Override
public int getSize() {
return 0;
}
}