美文网首页java高级
springboot笔记—缓存配置redis和Mongdb

springboot笔记—缓存配置redis和Mongdb

作者: NickYS | 来源:发表于2018-04-25 13:33 被阅读218次

    缓存配置

    当系统的访问量增大时,相应的数据库的性能就逐渐下降。但是,大多数请求都是在重复的获取相同的数据,如果使用缓存,将结果数据放入其中可以很大程度上减轻数据库的负担,提升系统的响应速度。

    本篇将介绍 Spring Boot 中缓存和 NoSQL 的使用。

    整合缓存

    Spring Boot 针对不同的缓存技术实现了不同的封装,本篇主要介绍 EhCache 和 Redis 缓存。

    Spring Boot 提供了以下几个注解实现声明式缓存:

    |

    注解

    |

    说明

    |
    | --- | --- |
    |

    @EnableCaching

    |

    开启缓存功能,放在配置类或启动类上

    |
    |

    @CacheConfig

    |

    缓存配置,设置缓存名称

    |
    |

    @Cacheable

    |

    执行方法前先查询缓存是否有数据。有则直接返回缓存数据;否则查询数据再将数据放入缓存

    |
    |

    @CachePut

    |

    执行新增或更新方法后,将数据放入缓存中

    |
    |

    @CacheEvict

    |

    清除缓存

    |
    |

    @Caching

    |

    将多个缓存操作重新组合到一个方法中

    |

    EhCache 缓存

    添加依赖

    <dependency>

    <groupId>org.springframework.boot</groupId>
    
    <artifactId>spring-boot-starter-cache</artifactId>
    

    </dependency>

    <dependency>

    <groupId>net.sf.ehcache</groupId>
    
    <artifactId>ehcache</artifactId>
    

    </dependency>

    在 src/main/resources 目录下创建 ehcache.xml 文件,内容如下:

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:noNamespaceSchemaLocation="ehcache.xsd">
    
    <cache name="department"
    
           eternal="false"
    
           maxEntriesLocalHeap="0"
    
           timeToIdleSeconds="50">
    
    </cache>
    

    </ehcache>

    application.properties :

    spring.cache.type=ehcache

    spring.cache.ehcache.config=classpath:ehcache.xml

    打印日志,查看 sql

    logging.level.com.light.springboot=DEBUG

    在持久层篇的基础上,结合 Mybatis 测试:

    Service 层:

    @CacheConfig(cacheNames = "department")

    @Service

    public class DepartmentService {

    @Autowired
    
    private DepartmentMapper departmentMapper;
    
    @CachePut(key = "#department.id")
    
    public Department save(Department department) {
    
        System.out.println("保存 id=" + department.getId() + " 的数据");
    
        this.departmentMapper.insert(department);
    
        return department;
    
    }
    
    @CachePut(key = "#department.id")
    
    public Department update(Department department) {
    
        System.out.println("修改 id=" + department.getId() + " 的数据");
    
        this.departmentMapper.update(department);
    
        return department;
    
    }
    
    @Cacheable(key = "#id")
    
    public Department getDepartmentById(Integer id) {
    
        System.out.println("获取 id=" + id + " 的数据");
    
        Department department = this.departmentMapper.getById(id);
    
        return department;
    
    }
    
    @CacheEvict(key = "#id")
    
    public void delete(Integer id) {
    
        System.out.println("删除 id=" + id + " 的数据");
    
        this.departmentMapper.deleteById(id);
    
    }
    

    }

    控制层:

    @Controller

    @RequestMapping("department")

    @ResponseBody

    public class DepartmentController {

    @Autowired
    
    private DepartmentService departmentService;
    
    @RequestMapping("save")
    
    public Map<String,Object> save(Department department) {
    
        this.departmentService.save(department);
    
        Map<String,Object> map = new HashMap<String,Object>();
    
        map.put("code", "200");
    
        map.put("msg", "保存成功");
    
        return map;
    
    }
    
    @RequestMapping("get/{id}")
    
    public Map<String,Object> get(@PathVariable("id") Integer id) {
    
        Department department = this.departmentService.getDepartmentById(id);
    
        Map<String,Object> map = new HashMap<String,Object>();
    
        map.put("code", "200");
    
        map.put("msg", "获取成功");
    
        map.put("data", department);
    
        return map;
    
    }
    
    @RequestMapping("update")
    
    public Map<String,Object> update(Department department) {
    
        this.departmentService.update(department);
    
        Map<String,Object> map = new HashMap<String,Object>();
    
        map.put("code", "200");
    
        map.put("msg", "修改成功");
    
        return map;
    
    }
    
    @RequestMapping("delete/{id}")
    
    public Map<String,Object> delete(@PathVariable("id") Integer id) {
    
        this.departmentService.delete(id);
    
        Map<String,Object> map = new HashMap<String,Object>();
    
        map.put("code", "200");
    
        map.put("msg", "删除成功");
    
        return map;
    
    }
    

    }

    启动类:

    添加 @EnableCaching 注解,开启缓存功能。

    @EnableCaching

    @SpringBootApplication

    public class SpringbootNosqlApplication {

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

    }

    测试说明

    发送保存接口

    [图片上传中...(image-49dfa3-1524634441874-7)]

    发送查询接口

    [图片上传中...(image-a3cef6-1524634441874-6)]

    再次发送查询接口

    [图片上传中...(image-d8f1c8-1524634441874-5)]

    说明数据是从缓存中获取。

    发起修改请求:

    [图片上传中...(image-dce6b1-1524634441874-4)]

    发送查询接口

    [图片上传中...(image-826dd4-1524634441874-3)]

    没有sql日志打印,但返回修改后的对象数据,说明缓存中的数据已经同步。

    发起删除请求:

    [图片上传中...(image-210460-1524634441874-2)]

    删除成功后,立刻发起查询请求,控制台打印 sql 语句,说明缓存数据被删除,需要查询数据库。

    [图片上传中...(image-46c621-1524634441874-1)]

    Redis 缓存

    添加依赖

    <dependency>

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

    </dependency>

    添加配置

    application.properties :

    spring.redis.host=192.168.1.254

    spring.redis.port=6379

    spring.redis.password=123456

    spring.redis.database=6

    spring.redis.pool.max-active=8

    spring.redis.pool.max-idle=8

    spring.redis.pool.max-wait=-1

    spring.redis.pool.min-idle=0

    spring.redis.timeout=0

    注意:spring.cache.type=redis,缓存类型设置成 redis。

    完成上边 2 个步骤后,其他步骤与测试 Ehcache 时的步骤一致。

    测试结果也一致,此处省略。

    整合 Redis

    在添加 redis 依赖包启动项目后,Spring Boot 会自动配置 RedisCacheManger 和 RedisTemplate 的 Bean。如果开发者不想使用 Spring Boot 写好的 Redis 缓存,而是想使用其 API 自己实现缓存功能、消息队列或分布式锁之类的需求时,可以继续往下浏览。

    Spring Data Redis 为我们提供 RedisTemplate 和 StringRedisTemplate 两个模板进行数据操作,它们主要 的访问方法如下:

    |

    方法

    |

    说明

    |
    | --- | --- |
    |

    opsForValue()

    |

    操作简单属性的数据

    |
    |

    opsForList()

    |

    操作含有 list 的数据

    |
    |

    opsForSet()

    |

    操作含有 set 的数据

    |
    |

    opsForZSet()

    |

    操作含有 zset 的数据

    |
    |

    opsForHash()

    |

    操作含有 hash 的数据

    |

    添加依赖

    <dependency>

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

    </dependency>

    配置连接

    spring.redis.host=192.168.1.254

    spring.redis.port=6379

    spring.redis.password=123456

    spring.redis.database=6

    spring.redis.pool.max-active=8

    spring.redis.pool.max-idle=8

    spring.redis.pool.max-wait=-1

    spring.redis.pool.min-idle=0

    spring.redis.timeout=0

    编码

    @Component

    public class RedisDao {

    @Autowired
    
    private StringRedisTemplate stringRedisTemplate;
    
    public void set(String key, String value) {
    
        this.stringRedisTemplate.opsForValue().set(key, value);
    
    }
    
    public String get(String key) {
    
        return this.stringRedisTemplate.opsForValue().get(key);
    
    }
    
    public void delete(String key) {
    
        this.stringRedisTemplate.delete(key);
    
    }
    

    }

    测试

    @RunWith(SpringRunner.class)

    @SpringBootTest

    public class RedisDaoTest {

    @Autowired
    
    private RedisDao redisDao;
    
    @Test
    
    public void testSet() {
    
        String key = "name";
    
        String value = "zhangsan";
    
        this.redisDao.set(key, value);
    
    }
    
    @Test
    
    public void testGet() {
    
        String key = "name";
    
        String value = this.redisDao.get(key);
    
        System.out.println(value);
    
    }
    
    @Test
    
    public void testDelete() {
    
        String key = "name";
    
        this.redisDao.delete(key);
    
    }
    

    }

    测试结果

    [图片上传中...(image-745fa0-1524634441874-0)]

    整合 MongoDB

    Spring Data MongoDB 提供了 MongoTemplate 模板 和 Repository 让开发者进行数据访问。

    添加依赖

    <dependency>

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

    </dependency>

    配置连接

    spring.data.mongodb.host=192.168.2.25

    spring.data.mongodb.port=27017

    spring.data.mongodb.database=test

    编码

    使用 MongoTemplate

    @Component

    public class MongodbDao {

    @Autowired
    
    private MongoTemplate mongoTemplate;
    
    public void insert(User user) {
    
        this.mongoTemplate.insert(user);
    
    }
    
    public void deleteById(int id) {
    
        Criteria criteria = Criteria.where("id").is(id);
    
        Query query = new Query(criteria);
    
        this.mongoTemplate.remove(query, User.class);
    
    }
    
    public void update(User User) {
    
        Criteria criteria = Criteria.where("id").is(User.getId());
    
        Query query = new Query(criteria);
    
        Update update = new Update();
    
        update.set("password", User.getPassword());
    
        this.mongoTemplate.updateMulti(query, update, User.class);
    
    }
    
    public User getById(int id) {
    
        Criteria criteria = Criteria.where("id").is(id);
    
        Query query = new Query(criteria);
    
        return this.mongoTemplate.findOne(query, User.class);
    
    }
    
    public List<User> getAll() {
    
        List<User> userList = this.mongoTemplate.findAll(User.class);
    
        return userList;
    
    }
    

    }

    使用 Repository

    public interface UserRepository extends MongoRepository<User, Integer> {

    }

    测试方式与 Redis 测试大同小异,测试结果省略...

    参考资料

    https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html 官方文档

    相关文章

      网友评论

        本文标题:springboot笔记—缓存配置redis和Mongdb

        本文链接:https://www.haomeiwen.com/subject/zwaelftx.html