eclipse创建springboot要注意,基本的包名一定要与java中的包名一致,这样才能找到springgboot主程序的入口;
主程序是在com.lazy.cache;那么test的包也要是com.lazy.cache
src/main/java
com.lazy.cache
CacheApplication.java
src/test/java
com.lazy.cahche
UserTest.java
----
注:#开启mybatis驼峰命名,数据字段名与属性名不一致,如:t_id,tId;需要开启这个,不然查询的结果为null
mybatis.configuration.map-underscore-to-camel-case=true
--------------
springboot知识点:
springboot-cache(缓存):
需要引入springboot缓存依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
--------------
1、开启基于注解的缓存,在主程序入口类上面,使用注解@EnableCaching
MapperScan("com.lazy.cache.mapper")//扫描mapper接口 @SpringBootApplication @EnableCaching public class CacheApplication { public static void main(String[] args) { SpringApplication.run(CacheApplication.class, args); } }
2、标注缓存注解(需要的缓存的方法上,将方法返回结果放入缓存中)
@Cacheable 对方法中的返回结果放入缓存中
/** * @Cacheable(key-value的形式) * 有几个属性: * cacheNames/value指定缓存组件的名字,员工放在emp组件中,里面可以放入多个key-value * key:缓存中的key名字,默认是方法参数的值,比如这里的id=1,那么key就是1;可以知道SpEL表达式指定key值 * #root.args[0]是取方法参数第一个参数等价于#id 自定义key(名为getEmployeeById[id]): key="#root.method.name+‘[‘+#id+‘]‘";方法名加参数的形式 自定义key生成器, * keyGenerator:key的生成器 * key/keyGenerator二选一 * cacheManager:指定缓存管理器 * condition:指定符合条件的情况下进行缓存 * condition="#id>0" * unless:符合条件的不缓存,与condition相反 * #result可以取到结果的返回值 * sync:缓存是否使用异步 */ @Cacheable(cacheNames={"emp"}) public Employee getEmployeeById(Integer id) { System.out.println("查询"+id+"号信息"); Employee employee = employeeMapper.getEmployeeById(id); return employee; }
原理:
1、自动配置类:CacheAutoConfiguration
2、缓存的配置类:默认redis
运行流程:
1、方法运行之前,先去查询cache,按照指定的cacheNames指定的名字获取缓存,第一次获取缓存(是为null)会先创建缓存(名为emp,这里的key是默认id)
2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数;key是按照某种策略生成的;默认是使用keyGenerator生成的,
3、没有查到缓存就调用目标方法
4、将目标方法返回结果,放进缓存中
@Cacheable标注的方法执行之前先检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,如果没有就进入目标方法中,到数据库中查询;数据库查询的结果返回,会将该结果放入到缓存中,下次在进行这个key查询,也会先到缓存中查询,缓存中存在这个key,就直接返回这个结果,不进入方法中。
注:配置前面的直接运行,会出现异常(找不到端口).但开启redis后,可以正常运行。看视频,都能正常运行,也没开rdeis,这是什么原因,还有这样cache的数据是存储在哪里的。版本问题,在1.5springboot版本默认的是SimpleCacheConfiguration,而在2.1版本是默认的是RedisCacheConfiguration缓存生效。所以在缓存需要打开redis服务端,在配置文件配置debug=true;可以看到容器启动加载了多少类。上面的是错误的,默认的还是SimpleCacheConfiguration,造成的原因是导入了redis的starter,它会启动redis的,如果没有导入redis的starter默认的还是SimpleCacheConfiguration。
--------------
@CachePut修改了某数据,更新缓存,同步缓存 /** * @CachePut执行时机:是先执行目标方法,然后将方法的返回结果,更新到缓存中 * key="#employee.id"可以用key="#result.id" * 属性基本相同 */ @CachePut(value="emp",key="#employee.id") public Employee updateEmployee(Employee employee) { System.out.println("更新员工:"+employee); employeeMapper.updateEmployee(employee); return employee; }
@CacheEvict清除缓存 /** * 删除缓存 * allEntries默认是false, * @CacheEvict(value="emp",allEntries=true)")清除emp组件中所有缓存 * beforeInvocation默认是false,清除缓存在方法之后执行。 * 设置为true,可以在方法前执行,尽管方法中出现异常也可以清除数据库 */ @CacheEvict(value="emp",key="#id",allEntries=true) public void DeleteEmployee(Integer id) { System.out.println("将缓存中的数据清除!,这里并没有把数据库中的数据删除"); } ---------- /** * 组合成复杂的缓存, * @Cacheable(value="emp",key="#lastName")执行目标方法前 * @CachePut(value="emp",key="#result.id"), * 将执行方法后以key="#result.id",key="#result.email存入缓存中 * @param lastName * @return * 出现异常信息 */ /*@Caching( cacheable = { @Cacheable(value="emp",key="#lastName") }, put = { @CachePut(value="emp",key="#result.id"), @CachePut(value="emp",key="#result.email") } )*/ public Employee getEmpByLastName(String lastName) { Employee employee = employeeMapper.getEmpByLastName(lastName); return employee; }
springboot整合redis
1、使用docker安装redis,这里使用widows版本,可以在redis官方文档中有详细的信息
2、引入redis的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3、在配置文件中配置redis(不需要指定端口,默认的是6379)
spring.redis.host=127.0.0.1
public class RedisTest { @Autowired private EmployeeMapper employeeMapper; @Autowired private StringRedisTemplate stringRedisTemplate;//key-value是字符串形式 @Autowired private RedisTemplate redisTemplate;//key-value是Object-Object的形式 @Autowired private RedisTemplate<Object, Employee> empRedisTemplate;//自定义的redis模板,以json序列化 /** * 以stringRedisTemplate操作redis * redis可以存储五种类型的数据结构,String类型,hash类型,set,list,zset * stringRedisTemplate.opsForValue()是操作String类型的 * stringRedisTemplate.opsForHash()是操作hash类型 * stringRedisTemplate.opsForSet()是操作Set类型 * stringRedisTemplate.opsForZSet()是操作ZSet类型 * stringRedisTemplate.opsForList()是操List类型 */ @Test public void demoRedis(){ //向redis中添加一个string类型的数据 //stringRedisTemplate.opsForValue().append("msg", "hello"); //获取redis中的元素 //String msg = stringRedisTemplate.opsForValue().get("msg"); //System.out.println(msg); //添加一个list数据,是从左边插入的, //stringRedisTemplate.opsForList().leftPush("mylist", "first"); //stringRedisTemplate.opsForList().leftPush("mylist", "second"); //获取list的数据 String result = stringRedisTemplate.opsForList().leftPop("mylist"); System.out.println(result); } /** * 使用redisTemplate操作存储对象 */ @Test public void testRedis(){ Employee employee = employeeMapper.getEmployeeById(1); //这里存放到redis是jdk序列化的数据,不是像json的数据类型 //如果要对象在redis中以json数据呈现,需要设置配置类,序列化(使用json Serializable) //redisTemplate.opsForValue().set("emp01", employee); empRedisTemplate.opsForValue().set("emp01", employee); } } ---------------- @Configuration public class MyRedisConfig { @Bean public RedisTemplate<Object,Employee> empRedisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>(); template.setConnectionFactory(redisConnectionFactory); //设置序号化形式,以json Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<>(Employee.class); template.setDefaultSerializer(serializer); return template; } }
上面的是测试:现在在项目中运用,保存对象时,还是默认的jdk序列化。要保存json的话:
1、引入redis的starter,cacheMananger变为RedisCacheManager
2、默认创建的RedisCacheManager操作redis的时候使用的是RedisTemplate<Object,Object>,
3、RedisTemplate<Object,Object>默认使用是JDK序列化,
4、自定义CacheMananger,
@RunWith(SpringRunner.class) @SpringBootTest public class RedisTest { @Autowired private EmployeeMapper employeeMapper; @Autowired private StringRedisTemplate stringRedisTemplate;//key-value是字符串形式 @Autowired private RedisTemplate redisTemplate;//key-value是Object-Object的形式 //@Autowired //private RedisTemplate<Object, Employee> empRedisTemplate;//自定义的redis模板,以json序列化 /** * 以stringRedisTemplate操作redis * redis可以存储五种类型的数据结构,String类型,hash类型,set,list,zset * stringRedisTemplate.opsForValue()是操作String类型的 * stringRedisTemplate.opsForHash()是操作hash类型 * stringRedisTemplate.opsForSet()是操作Set类型 * stringRedisTemplate.opsForZSet()是操作ZSet类型 * stringRedisTemplate.opsForList()是操List类型 */ @Test public void demoRedis(){ //向redis中添加一个string类型的数据 //stringRedisTemplate.opsForValue().append("msg", "hello"); //获取redis中的元素 //String msg = stringRedisTemplate.opsForValue().get("msg"); //System.out.println(msg); //添加一个list数据,是从左边插入的, //stringRedisTemplate.opsForList().leftPush("mylist", "first"); //stringRedisTemplate.opsForList().leftPush("mylist", "second"); //获取list的数据 String result = stringRedisTemplate.opsForList().leftPop("mylist"); System.out.println(result); } /** * 使用redisTemplate操作存储对象 */ @Test public void testRedis(){ Employee employee = employeeMapper.getEmployeeById(1); //这里存放到redis是jdk序列化的数据,不是像json的数据类型 //如果要对象在redis中以json数据呈现,需要设置配置类,序列化(使用json Serializable) //redisTemplate.opsForValue().set("emp01", employee); redisTemplate.opsForValue().set("emp01", employee); } } ------------ @Configuration public class MyRedisConfig { /** * 直接使用模板操作redis需要这样设置 * @param redisConnectionFactory * @return * @throws UnknownHostException */ @Bean public RedisTemplate<Object,Employee> empRedisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>(); template.setConnectionFactory(redisConnectionFactory); //设置序号化形式,以json Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<>(Employee.class); template.setDefaultSerializer(serializer); return template; } /** * 这是在项目中,将对象存入redis中以json形式, *,2.x版本没有new RedisCacheManager(RedisTemplate)构造方法 * 使用这个的话new RedisCacheManager(RedisTemplate), * 在项目中需要给每个存储对象都写RedisTemplate<Object,Object); * 下面这个设置可以通用 * @param redisConnectionFactory * @return */ @Bean public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) { //初始化一个RedisCacheWriter RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer(); RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext. SerializationPair.fromSerializer(jsonSerializer); RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(pair); return new RedisCacheManager(redisCacheWriter, defaultCacheConfig); } /** * 缓存管理器 */ /* @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { //初始化一个RedisCacheWriter RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); //设置CacheManager的值序列化方式为json序列化 RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer(); RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair .fromSerializer(jsonSerializer); RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(pair); //设置默认超过期时间是30秒 defaultCacheConfig.entryTtl(Duration.ofSeconds(30)); //初始化RedisCacheManager return new RedisCacheManager(redisCacheWriter, defaultCacheConfig); }*/ }
注:可以使用两种方法进行redis缓存,一种是注入RedisTemplate模板操作,这种操作比较复杂,但比较灵活,在程序指定的位置进行放入。
第二种方式使用注解方式,@Cachalbe,等等
----------
不使用注解:
注入缓存管理器
Cache dept = deptCacheManager.getCache("dept");//dept是上面注解的@Cacheable(value="dept")形式
dept.put("dept:1",department);
原文地址:https://www.cnblogs.com/lazyli/p/10804264.html