基于注解的缓存支持
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
### redis缓存配置
### 默认redis数据库为db0
spring.redis.database=0
### 服务器地址,默认为localhost
spring.redis.host=localhost
### 链接端口,默认为6379
spring.redis.port=6379
### redis密码默认为空
spring.redis.password=
Jackson 处理复杂类型(List,map)的方法
String jsonString="[{'id':'1'},{'id':'2'}]";
ObjectMapper mapper = new ObjectMapper();
List<Bean> beanList = mapper.readValue(jsonString, new TypeReference<List<Bean>>() {});
fastjson 处理复杂类型(List,map)的方法
SerializeWriter:相当于StringBuffer
JSONArray:相当于List<Object>
JSONObject:相当于Map<String, Object>
JSON反序列化没有真正数组,本质类型都是List<Object>
比如说List<Student>
List转Json
List<Student> students = new ArrayList();
String str = JSON.toJSONString(students); // List转json
Json 转List 方法一
String json = ""; //获取的Json数据
List<Student> students = JSON.parseObject(json,new TypeReference<List<Student>>(){}); // Json 转List
Json 转List 方法二
List<Student> students = JSON.parseArray(json,Student.class);
Student 对象要实现Serializable接口
public class Student implements Serializable{
测试
@Resource
private StringRedisTemplate stringRedisTemplate;
@Test
// stringRedisTemplate 测试
public void testRedis(){
//增 key:name,value:ay
stringRedisTemplate.opsForValue().set("name","ay");
String name = (String)stringRedisTemplate.opsForValue().get("name");
System.out.println("---------" + name);
//删除
stringRedisTemplate.delete("name");
// 更新
stringRedisTemplate.opsForValue().set("name","al111");
//查询
name = stringRedisTemplate.opsForValue().get("name");
System.out.println("======" + name);
}
private static final String ALL_USER = "ALL_USER_LIST";
@Autowired
ObjectMapper objectMapper;
@Test
// JackSon 测试 list json 转换
public void testRedis1() throws JsonProcessingException {
String s = stringRedisTemplate.opsForValue().get(ALL_USER);
// List<LinkedHashMap> list = objectMapper.readValue(s, ArrayList.class);
// for (LinkedHashMap linkedHashMap : list) {
// Set set = linkedHashMap.keySet();
// for (Object o : set) {
// String o1 = (String)linkedHashMap.get(o);
// System.out.println(o1);
// }
// }
List<AyUser> ayUserList = objectMapper.readValue(s, new TypeReference<List<AyUser>>() {});
for (AyUser ayUser : ayUserList) {
System.out.println(ayUser);
}
System.out.println("===========");
}
@Test
// fastjson 测试 list json 转换
public void testRedis2() throws JsonProcessingException {
String s = stringRedisTemplate.opsForValue().get(ALL_USER);
List<AyUser> ayUserList = JSON.parseArray(s, AyUser.class);
for (AyUser ayUser : ayUserList) {
System.out.println(ayUser);
}
System.out.println(">>>>>>>>>>>>>>>>");
}
@Test
// 测试 save 和 delete 写的缓存
public void testSaveRedis3(){
AyUser ayUser = new AyUser();
ayUser.setId("5");
ayUser.setName("jg");
ayUser.setPassword("123456");
ayUserService.save(ayUser);
}
@Test
// 测试 save 和 delete 写的缓存
public void testDeleteRedis3(){
ayUserService.delete("5");
}
@Test
public void testFindById(){
Long redisUserSize = 0L;
//查询id = 1 的数据,该数据存在于redis缓存中
AyUser ayUser = ayUserService.findById("1");
redisUserSize = stringRedisTemplate.opsForList().size("ALL_USER_LIST");
System.out.println("目前缓存中的用户数量为:" + redisUserSize);
System.out.println("--->>> id: " + ayUser.getId() + " name:" + ayUser.getName());
//查询id = 2 的数据,该数据存在于redis缓存中
AyUser ayUser1 = ayUserService.findById("2");
redisUserSize = stringRedisTemplate.opsForList().size("ALL_USER_LIST");
System.out.println("目前缓存中的用户数量为:" + redisUserSize);
System.out.println("--->>> id: " + ayUser1.getId() + " name:" + ayUser1.getName());
//查询id = 4 的数据,不存在于redis缓存中,存在于数据库中,所以会把数据库查询的数据更新到缓存中
AyUser ayUser3 = ayUserService.findById("4");
System.out.println("--->>> id: " + ayUser3.getId() + " name:" + ayUser3.getName());
redisUserSize = stringRedisTemplate.opsForList().size("ALL_USER_LIST");
System.out.println("目前缓存中的用户数量为:" + redisUserSize);
}
监听器 利用上下文初始化 方法 加载数据库的所有用户数据 并存入redis缓存中
package cn.stevekung.listener;
import cn.stevekung.pojo.AyUser;
import cn.stevekung.service.AyUserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import javax.annotation.Resource;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@WebListener
// ServletContextListener 对应整个application
public class AyUserListener implements ServletContextListener{
@Resource
ObjectMapper objectMapper;
@Resource
StringRedisTemplate stringRedisTemplate;
@Resource
AyUserService ayUserService;
private static final String ALL_USER = "ALL_USER_LIST";
private static final Logger log = LoggerFactory.getLogger(AyUserListener.class);
@Override
public void contextInitialized(ServletContextEvent sce) {
// 可以在上下文 contextInitialized 方法中查询所有的用户,
// 利用缓存技术把用户数据存放在缓存中 Redis缓存
log.info("ServletContext上下文初始化");
//查询数据库所有的用户
List<AyUser> ayUserList = ayUserService.findAll();
//清除缓存中的用户数据
stringRedisTemplate.delete(ALL_USER);
//将数据存放到redis缓存中
try {
for (AyUser ayUser : ayUserList) {
stringRedisTemplate.opsForList().rightPush(ALL_USER, objectMapper.writeValueAsString(ayUser));
}
List<String> redisStrings = stringRedisTemplate.opsForList().range(ALL_USER, 0, -1);
log.info("缓存中目前的用户数有:" + redisStrings.size() + " 人");
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log.info("ServletContext上下文销毁");
}
}
pojo实现序列化接口
package cn.stevekung.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "ay_user")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AyUser implements Serializable{
@Id
private String id;
private String name;
private String password;
}
更新缓存数据 findById Save Delete
package cn.stevekung.service.impl;
import cn.stevekung.pojo.AyUser;
import cn.stevekung.repository.AyUserRepository;
import cn.stevekung.service.AyUserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
@Service
@Transactional
public class AyUserServiceImpl implements AyUserService {
private static final Logger log = LoggerFactory.getLogger(AyUserServiceImpl.class);
@Autowired
AyUserRepository ayUserRepository;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
ObjectMapper objectMapper;
private static final String ALL_USER = "ALL_USER_LIST";
@Override
public AyUser findById(String id) {
AyUser ayUser = new AyUser();
try {
//step.1 查询Redis缓存中的所有数据
List<String> redisStrings = stringRedisTemplate.opsForList().range(ALL_USER, 0, -1);
List<AyUser> ayUserList = new ArrayList<>();
for (String redisString : redisStrings) {
AyUser user = objectMapper.readValue(redisString, AyUser.class);
ayUserList.add(user);
}
if (null != ayUserList && ayUserList.size() > 0){
for (AyUser user : ayUserList) {
if (user.getId().equals(id)){
return user;
}
}
}
//step.2 查询数据库中的数据
ayUser = ayUserRepository.findById(id).get();
if (ayUser != null){
//step.3 将数据插入到Redis缓存中
stringRedisTemplate.opsForList().rightPush(ALL_USER, objectMapper.writeValueAsString(ayUser));
}
} catch (Exception e) {
log.info("AyUserServiceImpl + findById() error");
e.printStackTrace();
}
return ayUser;
}
@Override
public List<AyUser> findAll() {
List<AyUser> result = ayUserRepository.findAll();
return result;
}
@Override
@Transactional
public AyUser save(AyUser ayUser) {
// 更新 和 保存
AyUser save = new AyUser();
try {
// 先更新数据库
save = ayUserRepository.save(ayUser);
// 测试事务回滚
String error = null;
error.split("/");
// 再更新缓存 (即删除缓存 设置缓存)
List<String> redisStrings = stringRedisTemplate.opsForList().range(ALL_USER, 0, -1);
for (String redisString : redisStrings) {
AyUser user = objectMapper.readValue(redisString, AyUser.class);
if (user.getName().equals(ayUser.getName())){
stringRedisTemplate.opsForList().remove(ALL_USER,1, redisString);
}
}
stringRedisTemplate.opsForList().rightPush(ALL_USER, objectMapper.writeValueAsString(save));
} catch (Exception e) {
log.info("AyUserServiceImpl + save() error");
e.printStackTrace();
}
return save;
}
@Override
public void delete(String id) {
try {
// 先更新数据库
ayUserRepository.deleteById(id);
// 再删除缓存
List<String> redisStrings = stringRedisTemplate.opsForList().range(ALL_USER, 0, -1);
for (String redisString : redisStrings) {
AyUser user = objectMapper.readValue(redisString, AyUser.class);
if (user.getId().equals(id)){
stringRedisTemplate.opsForList().remove(ALL_USER, 1, redisString);
}
}
} catch (Exception e) {
log.info("AyUserServiceImpl + delete() error");
e.printStackTrace();
}
}
// 分页
@Override
public Page<AyUser> findAll(Pageable pageable) {
return ayUserRepository.findAll(pageable);
}
@Override
public List<AyUser> findByName(String name) {
return ayUserRepository.findByName(name);
}
@Override
public List<AyUser> findByNameLike(String name) {
return ayUserRepository.findByNameLike(name);
}
@Override
public List<AyUser> findByIdIn(Collection<String> ids) {
return ayUserRepository.findByIdIn(ids);
}
}