SpringBoot學習筆記(10)-----SpringBoot中使用Redis/Mongodb和緩存Ehcache緩存和redis緩存


1. 使用Redis

  在使用redis之前,首先要保證安裝或有redis的服務器,接下就是引入redis依賴。

  pom.xml文件如下

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

  由於在SpringBoot中默認提供了一套配置,所以在使用本地的redis時,可以不用配置任何文件,只需要引入依賴,然后就可以使用了,

  使用Redis中的template類demo如下;

package com.wangx.boot.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
//必須要加Componet使得該組件可以被spring管理起來
@Component
public class RedisDAO {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public void set(String key, String value) {
        ValueOperations operations = redisTemplate.opsForValue();

        if (!redisTemplate.hasKey(key)) {
            operations.set(key,value);
            System.out.println("添加成功!!!");
        } else {
            System.out.println(operations.get(key));
        }
    }

    public String get (String key) {
        return redisTemplate.opsForValue().get(key);
    }

    public void del (String key) {
        redisTemplate.delete(key);
    }
}

  測試三個方法,可以成功保存數據到redis中。不得不再感嘆一句,SpringBoot開發真的太便利了,當然,如果redis服務器不是在本地機器上,那么,就需要配置一下你得主機和端口。SpringBoot提供了如下配置來支持Redis的使用。

spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands
across the cluster.
spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from.
spring.redis.database=0 # Database index used by the connection factory.
spring.redis.url= # Connection URL. Overrides host, port, and password. User is ignored. Example:
redis://user:password@example.com:6379
spring.redis.host=localhost # Redis server host.
spring.redis.jedis.pool.max-active=8 # Maximum number of connections that can be allocated by the pool
at a given time. Use a negative value for no limit.
spring.redis.jedis.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative
value to indicate an unlimited number of idle connections.
spring.redis.jedis.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block
before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.jedis.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in
the pool. This setting only has an effect if it is positive.
spring.redis.lettuce.pool.max-active=8 # Maximum number of connections that can be allocated by the pool
at a given time. Use a negative value for no limit.
spring.redis.lettuce.pool.max-idle=8 # Maximum number of "idle" connections in the pool. Use a negative
value to indicate an unlimited number of idle connections.
spring.redis.lettuce.pool.max-wait=-1ms # Maximum amount of time a connection allocation should block
before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.lettuce.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in
the pool. This setting only has an effect if it is positive.
spring.redis.lettuce.shutdown-timeout=100ms # Shutdown timeout.
spring.redis.password= # Login password of the redis server.
spring.redis.port=6379 # Redis server port.
spring.redis.sentinel.master= # Name of the Redis server.
spring.redis.sentinel.nodes= # Comma-separated list of "host:port" pairs.
spring.redis.ssl=false # Whether to enable SSL support.
spring.redis.timeout= # Connection timeout.
# TRANSACTION (TransactionProperties)
spring.transaction.default-timeout= # Default transaction timeout. If a duration suffix is not
specified, seconds will be used.
spring.transaction.rollback-on-commit-failure= # Whether to roll back on commit failures.

  通過這些配置可以在自己不同的場景下使用redis.

2. 使用mongodb

  同樣的Mongodb也提供了一套默認的配置,所以我們只需要保證本機中有mongodb服務器,並啟動。引入依賴,就可以直接編寫我們的mongodb的持久層。

  pom.xml文件:

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

  使用mongodb的代碼如下:

  

package com.wangx.boot.mongo;

import com.wangx.boot.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.List;

//必須要加Componet使得該組件可以被spring管理起來
@Component
public class MongoDAO {

    @Autowired
    private MongoTemplate mongoTemplate;

    public void insert(User user) {
        mongoTemplate.insert(user);
        System.out.println("添加成功");
    }

    public void update(User user) {
        Criteria criteria = Criteria.where("id").in(user.getId());
        Query query = new Query(criteria);
        Update update = new Update();
        update.set("name", user.getName());
        update.set("age", user.getAge());
        mongoTemplate.updateMulti(query, update, User.class);
        System.out.println("更新成功!!!");
    }

    public List<User> select (Integer id) {
        Criteria criteria = Criteria.where("id").in(id);
        Query query = new Query(criteria);
        return mongoTemplate.find(query,User.class);
    }

    public void delById (Integer id) {
        Criteria criteria = Criteria.where("id").in(id);

        Query query = new Query(criteria);

        mongoTemplate.remove(query, User.class);
        System.out.println("刪除成功!!!");
    }

    public List<User> findAll () {
        return mongoTemplate.findAll(User.class);
    }
}

  示例中提供了增刪改查四個方法,測試,數據能成功保存到mongodb數據庫中。可以說。在SpringBoot下,大部分的工具中間件的使用方式都是比較簡單的。

3. Ehcache緩存的使用

  使用緩存需要引入依賴  

  pom.xml文件

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

  配置文件中配置ehcache的配置文件位置,如下:

# 指定當前cache類型,當有多種緩存在同一個系統時可以使用
spring.cache.type=
spring.cache.ehcache.config=classpath:/conf/encache.xml

  還需要再啟動類上添加注解@EnableCaching表示開啟注解。

  encache.xml

<ehcache>
    <cache name="wangCache"
           eternal="false"
           maxEntriesLocalHeap="0"
           timeToIdleSeconds="200"></cache>

    <!-- eternal:true表示對象永不過期,此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性,默認為false -->
    <!-- maxEntriesLocalHeap:堆內存中最大緩存對象數,0沒有限制 -->
    <!-- timeToIdleSeconds: 設定允許對象處於空閑狀態的最長時間,以秒為單位。當對象自從最近一次被訪問后,如果處於空閑狀態的時間超過了timeToIdleSeconds屬性值,這個對象就會過期,EHCache將把它從緩存中清空。只有當eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示對象可以無限期地處於空閑狀態 -->
</ehcache>

  下面寫一個帶緩存的持久層代碼

package com.wangx.boot.cache.impl;

import com.wangx.boot.cache.CachingBook;
import com.wangx.boot.dao.impl.BookDAO;
import com.wangx.boot.entity.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;

/**
 *
 * cacheNames 值必須與encache.xml中的某個cache的name一致
 */

@CacheConfig(cacheNames = "wangCache")
@Repository
public class CacheingBookImpl implements CachingBook {

    @Autowired
    private BookDAO bookDAO;

    //value 值必須與encache.xml中的某個cache的name一致
    @Cacheable(value = "wangCache")
    @Override
    public Book findById(String name) {
        System.out.println("緩存中沒有數據");
        return bookDAO.findByName(name);
    }
    //value 值必須與encache.xml中的某個cache的name一致
    @CachePut("wangCache")
    @Override
    public Book updateById(Book book) {
        System.out.println("更新功能:更新緩存。直接寫庫: id=" + book);
        return bookDAO.save(book);
    }
    //value 值必須與encache.xml中的某個cache的name一致
    @CacheEvict("wangCache")
    @Override
    public String deleteById(String id) {
        System.out.println("刪除緩存,直接寫庫 id=" + id);
        return "OK";
    }
}

  測試代碼:

package com.wangx.boot.controller;

import com.wangx.boot.cache.CachingBook;
import com.wangx.boot.entity.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("/api")
public class ApiController {
    
    @Autowired
    private CachingBook cachingBook;

    @RequestMapping(value = "/select", method = RequestMethod.GET)
    public Book get(@RequestParam(defaultValue = "遮天") String name) {
        Book book = cachingBook.findById(name);
        return book;
    }

    @RequestMapping(value = "/update", method = RequestMethod.GET)
    public Book update(@RequestParam(defaultValue = "遮天") String name) {
        Book bean = cachingBook.findById(name);
        bean.setAuthor("耳根");
        cachingBook.updateById(bean);
        return bean;
    }

    @RequestMapping(value = "/del", method = RequestMethod.GET)
    public String del(@RequestParam(defaultValue = "遮天") String name) {
        return cachingBook.deleteById(name);
    }
}

  當調用查詢時,會先去緩存中獲取數據,如果沒有,才會調用CacheingBookImpl 中的find方法,並將查詢出來的值保存到緩存中,下一次再請求時由於緩存中有數據,所以不會再調用持久層的方法,修改方法每次都會調用持久層方法並修改緩存。delete會刪除緩存。cache的幾個注解的含義

  @CacheConfig 緩存配置

  @Cacheable 應用到讀取數據的方法上,即可緩存方法,:如查找方法。先從緩存中讀取,如果沒有再調用方法獲取數據,然后把數據存儲到緩存中,適用於查找。

  @CachePut: 主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存。和@Cacheable不同的是,它每次都會觸發真實的方法調用,適用於更新和插入。

  @CacheEvict:主要根據方法配置,能夠根據一定的條件對緩存進行清空,適用於刪除。

4. 使用Redis緩存

  有了前面使用緩存的示例之后,redis操作就非常簡單了,只需要引入redis依賴,將配置文件中的spring.cache.type配置為redis,

spring.cache.type=redis.需要注意的是,需要緩存的實體類必須實現序列化,否則會報未序列化的錯誤。如Book.java
package com.wangx.boot.entity;

import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;

@Entity
public class Book implements Serializable {

    @Id
    private int id;
    private String name;
    private String author;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

 其他的代碼都不用改,只是將encache換成redis就可以了,測試也跟使用Ehcache作用相同。

  使用redis還可以使用配置類自定義一些不同的信息,自定義方式如下:

  

package com.roncoo.example.util.configuration;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * redis 自定義緩存管理器
 * 
 * @author wujing
 */
@Configuration
public class RedisCacheConfiguration extends CachingConfigurerSupport {

    /**
     * 自定義緩存管理器.
     * 
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        // 設置默認的過期時間
        cacheManager.setDefaultExpiration(20);
        Map<String, Long> expires = new HashMap<String, Long>();
        // 單獨設置
        expires.put("roncooCache", 200L);
        cacheManager.setExpires(expires);
        return cacheManager;
    }
    
    /**
     * 自定義key. 此方法將會根據類名+方法名+所有參數的值生成唯一的一個key,即使@Cacheable中的value屬性一樣,key也會不一樣。
     */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder();
                sb.append(o.getClass().getName());
                sb.append(method.getName());
                for (Object obj : objects) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }



}

  可以根據自己的業務配置不同的信息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM