SpringBoot緩存注解介紹+實戰(zhàn)

聲明

1槽袄、介紹SpringBoot注解

1.1 @Cacheable

  • 運行流程:
    1. 方法運行之前棍掐,先去查詢Cache(緩存組件)淤刃,按照cacheNames指定的名字獲扰А纵隔;如果沒有找到就創(chuàng)建一個cache組件,這里的獲取是由CacheManager來完成的.
    2. 在找到的cache組件中,使用一個參數(shù)key來獲取緩存的內(nèi)容,默認是按照@Cacheable注解所在的方法的參數(shù)罩抗。

1.1.1 Cacheable屬性

  • cacheNames/value
    指定緩存組件的名字,將方法的返回值存放在哪個緩存中,是數(shù)組的方式,可以指定多個緩存.
  • key
    緩存數(shù)據(jù)時使用的key,可以用這個屬性來指定,默認使用方法參數(shù)的值.可以使用SqEL表達式來指定,比如#id方法參數(shù)id的值,#a0 #p0 #root.args[0]代表第一個參數(shù).
  • keyGenerator
    key的生成器求摇,可以自己指定key的生成器的組件id
//自定義配置類配置keyGenerator
@Configuration
public class MyCacheConfig {
    @Bean("myKeyGenerator")
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                return method.getName()+"["+ Arrays.asList(params).toString() +"]";
            }
        };
    }
}
  • cacheManager
    指定緩存管理器窍荧;或者cacheResolver獲取指定解析器
    ?- condition
    指定符合條件的情況下才緩存辉巡;如condition="#id>0"
  • unless
    否定緩存,當unless指定的條件為true蕊退,方法的返回值不會被緩存郊楣,可以獲取到結(jié)果進行判斷;如unless="#result==null";
  • sync
    是否使用異步模式
@Cacheable(cacheNames = "user",keyGenerator = "myKeyGenerator")
    public User getUser(Integer id) {
        System.out.println("查詢" + id + "號用戶");
        User user = userMapper.getUserId(id);
        return user;
    }

1.2 @CachePut

  • 既調(diào)用方法,又更新緩存.
  • 運行流程:
    先調(diào)用目標方法憔恳,將方法結(jié)果添加到緩存中,如果已經(jīng)存在,則更新.
    1、先調(diào)用運行方法净蚤;
    2钥组、將目標方法的結(jié)果緩存起來
    value:緩存名
    key:緩存的key其中#result表示方法返回的結(jié)果(確保更新的key和查詢一致即可做到同時更新數(shù)據(jù)庫數(shù)據(jù)和緩存中的數(shù)據(jù))
@CachePut(value="user",key = "#result.id")
    public User updateUser(User user){
        System.out.println("updateUser:"+user);
        userMapper.updateUser(user);
        return user;
    }

1.3 @CacheEvict 清除緩存

  • 屬性:
    key: 指定要刪除的緩存的key
    allEntries: 指定清除這個緩存中的所有數(shù)據(jù),默認是false.
    beforeInvocation : 清除緩存的在方法執(zhí)行之前還是之后. 默認是false,代表在方法執(zhí)行后清除.(如果方法在執(zhí)行過程中出現(xiàn)了異常,就不會刪除緩存數(shù)據(jù))
@CacheEvict(value = "user",key = "#id")
    public void deleteUser(Integer id){
        System.out.println("deleteUser:"+id);
        userMapper.deleteUserById(id);
    }

1.4 @Caching

  • 定義復(fù)雜的緩存規(guī)則
@Caching(
            cacheable = {
                    @Cacheable()
            },
            put = {
                    @CachePut(),
                    @CachePut()
            },
            evict = {
                    @CacheEvict()
            }
    )
    public 返回值 方法名(參數(shù)類型 參數(shù)){
        return 返回結(jié)果;
    }

1.5 @EnableCaching

  • 開啟緩存注解驅(qū)動,否則后面使用的緩存都是無效的

1.6 @CacheConfig

  • 這個注解的作用就是全局配置緩存今瀑,比如配置緩存的名字(cacheNames)程梦,只需要在類上配置一次,下面的方法就默認以全局的配置為主橘荠,不需要進行第二次配置屿附,節(jié)省了部分代碼。

2哥童、緩存實戰(zhàn)

  • 簡介
    該項目是基于SSM開發(fā)的挺份,工具采用的是idea+mysql+postman。

2.1 項目搭建

搭建一個SpringBoot+Mybatis環(huán)境贮懈,這個就不多說了匀泊。


項目結(jié)構(gòu).png

2.2 pom.xml

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

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

2.3 Dao層

@Mapper
public interface ArtileDao {
   
    /**
     * 通過ID查詢單條數(shù)據(jù)
     *
     * @param id 主鍵
     * @return 實例對象
     */
    Artile queryById(Integer id);

    /**
     * 新增數(shù)據(jù)
     *
     * @param artile 實例對象
     * @return 影響行數(shù)
     */
    int insert(Artile artile);

    /**
     * 修改數(shù)據(jù)
     *
     * @param artile 實例對象
     * @return 影響行數(shù)
     */
    int update(Artile artile);

    /**
     * 通過主鍵刪除數(shù)據(jù)
     *
     * @param id 主鍵
     * @return 影響行數(shù)
     */
    int deleteById(Integer id);

}

2.4 ServiceImpl層

  • 這里的話,我就省略了Service错邦。
  • 我們在service層配置了 @CacheConfig探赫,,并且指定了key,這樣的話撬呢,我們出了第一次之外伦吠,我們都會吧結(jié)果混存起來,以后的結(jié)果魂拦,都會吧這個緩存直接返回毛仪。當我們進行更新數(shù)據(jù)的時候,使用@ CacheEvict來清除緩存芯勘,防止調(diào)用@Cacheable的時候沒有更新緩存箱靴。
@Service("artileService")
@CacheConfig(cacheNames = "articleCache")
public class ArtileServiceImpl implements ArtileService {
    @Resource
    private ArtileDao artileDao;

    /**
    * @Description: 根據(jù)主鍵查詢
    * @Author: wangxianlin
    * @Date: 2020/3/17 10:57 AM
    */ 
    @Cacheable(value = "articleCache")
    @Override
    public Artile queryById(int id) {
        try {
            //模擬耗時操作
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return this.artileDao.queryById(id);
    }

    /**
    * @Description: 新增數(shù)據(jù)
    * @params: [artile]
    * @return: int
    * @Author: wangxianlin
    * @Date: 2020/3/17 10:57 AM
    */ 
    @CachePut
    @Override
    public int insert(Artile artile) {
        return this.artileDao.insert(artile);
    }

    /**
    * @Description: 修改數(shù)據(jù)
    * @params: [artile]
    * @return: com.ustcinfo.cache.entity.Artile
    * @Author: wangxianlin
    * @Date: 2020/3/17 10:57 AM
    */ 
    @CacheEvict(key = "#artile.id")
    @Override
    public int update(Artile artile) {
        return  this.artileDao.update(artile);
    }

    /**
    * @Description: 根據(jù)主鍵刪除
    * @params: [id]
    * @return: boolean
    * @Author: wangxianlin
    * @Date: 2020/3/17 10:58 AM
    */ 
    @CacheEvict(key = "#id")
    @Override
    public boolean deleteById(Integer id) {
        return this.artileDao.deleteById(id) > 0;
    }
}

2.5 Controller層

@RestController
@RequestMapping("artile")
public class ArtileController {
    /**
     * 服務(wù)對象
     */
    @Resource
    private ArtileService artileService;
    
  /**
    * @Description: 根據(jù)主鍵查詢
    * @params: [id]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: wangxianlin
    * @Date: 2020/3/17 1:48 PM
    */ 
    @GetMapping("queryById")
    public Map<String,Object> queryById(@RequestParam("id") int id) {
        Map<String,Object> map = new HashMap<>();
        Long start = System.currentTimeMillis();
        map.put("data",this.artileService.queryById(id));
        Long end = System.currentTimeMillis();
        map.put("time",(end-start));
        return map;
    }

    /**
    * @Description: 新增
    * @params: [artile]
    * @return: int
    * @Author: wangxianlin
    * @Date: 2020/3/17 10:55 AM
    */
    @PostMapping("insert")
    public int insert(@RequestBody Artile artile) {
        return this.artileService.insert(artile);
    }

    /**
    * @Description: 修改
    * @params: [artile]
    * @return: com.ustcinfo.cache.entity.Artile
    * @Author: wangxianlin
    * @Date: 2020/3/17 10:55 AM
    */
    @PostMapping("update")
    public int update(@RequestBody Artile artile) {
        return this.artileService.update(artile);
    }

    /**
    * @Description: 根據(jù)主鍵刪除
    * @params: [id]
    * @return: boolean
    * @Author: wangxianlin
    * @Date: 2020/3/17 10:56 AM
    */
    @GetMapping("deleteById")
    public boolean deleteById(@RequestParam("id") Integer id) {
        return this.artileService.deleteById(id);
    }
}

2.6 啟動類

@MapperScan("com.ustcinfo.cache.dao")
@SpringBootApplication
//開啟緩存注解驅(qū)動,否則后面使用的緩存都是無效的
@EnableCaching
public class CacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }
}

3荷愕、postman測試

3.1 根據(jù)主鍵查詢

  • 第一次進行查詢:


    image.png
  • 第二次進行查詢:


    image.png

3.2 添加

image.png
  • 在查詢一次:


    image.png

    image.png

3.3 修改

image.png
  • 在查詢一次:


    在查詢一次

3.3 刪除

image.png
  • 在查詢一次:


    image.png

    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載衡怀,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末安疗,一起剝皮案震驚了整個濱河市抛杨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荐类,老刑警劉巖怖现,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玉罐,居然都是意外死亡屈嗤,警方通過查閱死者的電腦和手機潘拨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饶号,“玉大人铁追,你說我怎么就攤上這事∶4” “怎么了脂信?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長透硝。 經(jīng)常有香客問我,道長疯搅,這世上最難降的妖魔是什么濒生? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮幔欧,結(jié)果婚禮上罪治,老公的妹妹穿的比我還像新娘。我一直安慰自己礁蔗,他們只是感情好觉义,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浴井,像睡著了一般晒骇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上磺浙,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天洪囤,我揣著相機與錄音,去河邊找鬼撕氧。 笑死瘤缩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的伦泥。 我是一名探鬼主播剥啤,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼不脯!你這毒婦竟也來了府怯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤跨新,失蹤者是張志新(化名)和其女友劉穎富腊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體域帐,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡赘被,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年是整,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片民假。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡浮入,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出羊异,到底是詐尸還是另有隱情事秀,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布野舶,位于F島的核電站易迹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏平道。R本人自食惡果不足惜睹欲,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望一屋。 院中可真熱鬧窘疮,春花似錦、人聲如沸冀墨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诽嘉。三九已至蔚出,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間含懊,已是汗流浹背身冬。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留岔乔,地道東北人酥筝。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像雏门,于是被迫代替她去往敵國和親嘿歌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 前言:緩存在開發(fā)中是一個必不可少的優(yōu)化點茁影,近期在公司的項目重構(gòu)中宙帝,關(guān)于緩存優(yōu)化了很多點,比如在加載一些數(shù)據(jù)比較多的...
    程序員BUG閱讀 892評論 0 0
  • 默認的緩存配置[#] 在諸多的緩存自動配置類中, SpringBoot默認裝配的是SimpleCacheConfi...
    扯淡巴閱讀 416評論 0 0
  • 1、Spring緩存 1.1、緩存依賴 1.2靴患、緩存注解 @EnableCaching:在主入口類上添加該注解仍侥,用...
    木石前盟Caychen閱讀 832評論 0 6
  • 本文為轉(zhuǎn)載,原文地址:http://www.cnblogs.com/yueshutong/p/9381540.ht...
    吟風者閱讀 36,865評論 2 22
  • 又到了星期二通話的時間了鸳君,林江撥通了文清的電話农渊,果然沒有以前的一撥即通,響了許久或颊,電話才被接起來砸紊。也沒有了以前那聲...
    云中燕2018閱讀 222評論 0 1