docker启动redis

 docker run -p 6379:6379 --name myredis redis
查看容器 [root@topcheer ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
14b1139f889d f7302e4ab3a8 "docker-entrypoint..." 20 hours ago Up 20 hours 0.0.0.0:6379->6379/tcp myredis
[root@topcheer ~]#
注:本文只讲整合,后面补充docker及redis知识

整合Redis

application.yml 配置文件

 spring:
datasource:
username: scott
password: tiger
url: jdbc:oracle:thin:@//localhost:1521/ORCL
driver-class-name: oracle.jdbc.driver.OracleDriver
redis:
host: 192.168.180.113
port: 6379

pom.xml (选取开发所需的依赖)

    
     <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<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>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.18</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.33</version>
</dependency>

<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1.0</version>
</dependency>

启动类加上注解

 /* 整合redis作为缓存
* Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
* 1、安装redis:使用docker;
* 2、引入redis的starter
* 3、配置redis
* 4、测试缓存
* 原理:CacheManager===Cache 缓存组件来实际给缓存中存取数据
* 1)、引入redis的starter,容器中保存的是 RedisCacheManager;
* 2)、RedisCacheManager 帮我们创建 RedisCache 来作为缓存组件;RedisCache通过操作redis缓存数据的
* 3)、默认保存数据 k-v 都是Object;利用序列化保存;如何保存为json
* 1、引入了redis的starter,cacheManager变为 RedisCacheManager;
* 2、默认创建的 RedisCacheManager 操作redis的时候使用的是 RedisTemplate<Object, Object>
* 3、RedisTemplate<Object, Object> 是 默认使用jdk的序列化机制
* 4)、自定义CacheManager;
*
*/
@MapperScan("com.topcheer.*.*.dao")
@SpringBootApplication
@EnableCaching //开启缓存
public class Oss6Application {

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

}

Web层

 /**
* @author WGR
* @create 2019/9/7 -- 15:14
*/

@RestController
@RequestMapping("/sys/user")
@Slf4j
public class UserController {

@Autowired
UserService userService;

//根据主键查询
@GetMapping("/findById")
public R findById(Integer id) {
return userService.findById(id);
}


}

Service层

/**
* @author WGR
* @create 2019/9/7 -- 15:14
*/
@Service
public class UserService {

@Autowired(required = false)
UserMapper userMapper;

/**
* 缓存的数据能存入redis;
* 第二次从缓存中查询就不能反序列化回来;
* 存的是dept的json数据;CacheManager默认使用RedisTemplate<Object, Employee>操作Redis
*
*
* @param id
* @return
*/
@Cacheable(cacheNames = "user",key="#root.methodName+'['+#id+'}'")
public R findById(Integer id) {
return R.ok().addData(
userMapper.selectById(id)
);
}
}

注解JSR107缓存说明(当pom加入redis时,生效的是RedisCacheConfiguration)

 将方法的运行结果进行缓存;以后再要相同的数据,直接从缓存中获取,不用调用方法;
    CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字;
 
  原理:
1、自动配置类;CacheAutoConfiguration
2、缓存的配置类
org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration
org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration【默认】
org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
3、哪个配置类默认生效:SimpleCacheConfiguration; 4、给容器中注册了一个CacheManager:ConcurrentMapCacheManager
5、可以获取和创建ConcurrentMapCache类型的缓存组件;他的作用将数据保存在ConcurrentMap中; 运行流程:
@Cacheable:
1、方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取;
(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数;
key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key;
SimpleKeyGenerator生成key的默认策略;
如果没有参数;key=new SimpleKey();
如果有一个参数:key=参数的值
如果有多个参数:key=new SimpleKey(params);
3、没有查到缓存就调用目标方法;
4、将目标方法返回的结果,放进缓存中 @Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,
如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据; 核心:
1)、使用CacheManager【ConcurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件
2)、key使用keyGenerator生成的,默认是SimpleKeyGenerator 几个属性:
cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存; key:缓存数据使用的key;可以用它来指定。默认是使用方法参数的值 1-方法的返回值
编写SpEL; #i d;参数id的值 #a0 #p0 #root.args[0]
getEmp[2] keyGenerator:key的生成器;可以自己指定key的生成器的组件id
key/keyGenerator:二选一使用; cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器 condition:指定符合条件的情况下才缓存;
,condition = "#id>0"
condition = "#a0>1":第一个参数的值》1的时候才进行缓存 unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断
unless = "#result == null"
unless = "#a0==2":如果第一个参数的值是2,结果不缓存;
sync:是否使用异步模式   

Dao层

 /**
* @author WGR
* @create 2019/9/7 -- 15:10
*/
public interface UserMapper extends OssMapper<User> {
}

Bo类

 @AllArgsConstructor
@NoArgsConstructor
@Data
@TableName("Z010_USER")
@KeySequence(value="SEQ_Z010_USER",clazz=Integer.class)
public class User implements Serializable{

private static final long serialVersionUID = 1L;

@TableId
private Integer id; // 主键
private String account; // 账号,唯一,可供登录(同时作为密码的盐值)
private String name; // 姓名
@JSONField(serialize=false)
private String password; // 密码,MD5盐值加密
@Code
private String gender; // 性别,字典
private Date birthday; // 出生日期
@Code
private String certType; // 证件类型,字典
private String certNumber; // 证件号码
private String telNumber; // 固定电话
private String mobNumber; // 手机号码
private String faxNumber; // 传真号码
private String email; // 电子邮件,唯一,可供登录
private String empId; // 工号,唯一,可供登录
@Code
private String position; // 职位
private Integer managerId; // 直属上级 20180417
@JSONField(format="yyyy-MM-dd")
private Date loginLastTime; // 最后登录时间
private Integer loginSuccessCount; // 登录成功次数(成功登录时+1)
private String passwordStatus; // 密码状态,0-临时密码 1-永久密码(临时密码登录提示修改密码)
private Integer passwordTryCount; // 密码尝试次数(错误累计,成功登录清零)
@JSONField(format="yyyy-MM-dd")
private Date passwordTryLastTime; // 密码最后尝试时间
@JSONField(format="yyyy-MM-dd")
private Date passwordExpiryDate; // 密码过期日期(密码即将过期提示, 已经过期强制修改密码)
private String wxOpenid; // 微信公众号openId private String headPic; // 用户头像 private String createUser; // 创建人员
@JSONField(format="yyyy-MM-dd")
private Date createTime; // 创建时间
private String modifyUser; // 修改人员
@JSONField(format="yyyy-MM-dd")
private Date modifyTime; // 修改时间
@Code
private String status; // 状态, 0-禁用 1-启用
@TableLogic
@JSONField(serialize=false)
private String delFlag; // 数据删除标记, 0-已删除 1-有效
private String remark; // 备注 @TableField(exist=false)
private String permType; // 权限类型


}

Fastjosn进行序列化及Redis配置

 /**
* @author WGR
* @create 2019/10/10 -- 23:47
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {

public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

private Class<T> clazz;

static { //开启白名单,不能序列化的时候会报错
ParserConfig.getGlobalInstance().addAccept("com.topcheer.oss.");
}

public FastJson2JsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}

public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}

public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, clazz);
}

}
/**
* @author WGR
* @create 2019/10/10 -- 23:33
*/
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

@Bean("redisCacheManager")
@Primary
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
//初始化一个RedisCacheWriter
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
FastJson2JsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJson2JsonRedisSerializer<>(Object.class);
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer);
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
//设置过期时间 30天
defaultCacheConfig = defaultCacheConfig.entryTtl(Duration.ofDays(30));
//初始化RedisCacheManager
RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);

ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// ParserConfig.getGlobalInstance().addAccept("com.topcheer.oss.");
return cacheManager;
}

@Bean(name = "redisTemplate")
@SuppressWarnings("unchecked")
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
//使用fastjson序列化
FastJson2JsonRedisSerializer fastJsonRedisSerializer = new FastJson2JsonRedisSerializer(Object.class);
// value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}

}

结果:

最新文章

  1. bufferedimage 转换成 inputstream并保存文件
  2. MVC中利用自定义的ModelBinder过滤关键字
  3. iOS - AVAudioPlayer 音频播放
  4. PHP工程师面临成长瓶颈
  5. 【MooTools】
  6. 现代Web的资源/类型/元素--发展趋势
  7. lightoj 1236 正整数唯一分解定理
  8. NSString 遍历
  9. error2
  10. MyBatis和SpringMVC集成事务在Junit测试下有效但是在实际项目无效的问题
  11. 要你的祝福.lrc
  12. easyui,datagrid表格,行内可编辑
  13. springMVC_01认识springMVC
  14. hackbar增强版 &amp; 在Firefox上安装未通过验证的扩展
  15. Spring AOP的实现及源码解析
  16. css趣味案例:画三角形
  17. 何谓domReady
  18. 用delegate实现.NET应用程序的同步函数的异步调用-.NET多线程编程实践之一
  19. [Scikit-learn] 2.1 Clustering - Gaussian mixture models &amp; EM
  20. [Redis] - 高并发下Redis缓存穿透解决

热门文章

  1. Hadoop点滴-Hadoop分布式文件系统
  2. java8 base64使用
  3. K8s 从懵圈到熟练 – 集群网络详解
  4. Scala Eclipse org.eclipse.e4.workbench异常奔溃修复
  5. spring配置文件默认名称及位置,ContextLoaderListener监听器作用
  6. tomcat容器是如何创建servlet类实例
  7. 各种xml配置文件(所含内部标签及顺序)的提示功能是真的人性化
  8. redis安装详细
  9. KafkStream架构
  10. react16 路由按需加载、路由权限配置