天天看點

mybatis redis_SpringBoot + Mybatis + Redis 整合入門項目

mybatis redis_SpringBoot + Mybatis + Redis 整合入門項目

作者 | M-Anonymous

來源 | cnblogs.com/M-Anonymous/p/13158049.html

這篇文章我決定一改以往的風格,以幽默風趣的故事博文來介紹如何整合 SpringBoot、Mybatis、Redis。

很久很久以前,森林裡有一隻可愛的小青蛙,他邁着沉重的步伐走向了找工作的道路,結果發現許多的招聘要求都要會 Redis。

小青蛙就想啥是 Redis 呢,為什麼要用 Redis 呢?

難道是因為 Mysql 的币格不夠高嗎,小青蛙點開了收藏已久的網站:

十萬個為什麼發現原來随着使用網站的使用者越來越多,表中的資料也越來越多,查詢速度越來越慢。

MySql 的性能遇到了瓶頸,是以許多網站都用 Redis 作緩存。

 然而能作緩存的不僅隻有 Redis,還有 Memcache,那為什麼要用 Redis 呢?

1、性能方面:

它們都是将資料存放在記憶體中,是以性能基本相似。

2、資料類型方面:

Redis 支援五種資料資料類型:

字元串、散列、清單、集合、有序集合,而 Memcache 僅僅支援簡單的 key-value。

3、資料持久化方面:

Redis 可以通過 RDB快照、AOF日志 等方式進行資料持久化,但是 Memcache 不可以。

4、資料備份方面:

Redis  支援 master-slave 主從模式的資料備份。

 在了解到許多 Redis 的好處後,小青蛙已經迫不及待的想了解它了。

為了更好的使用 Redis,了解 Redis 的五種資料類型适應場景是很有必要的。

1、String 類型:

一個 key 對應一個 value,而 value 不僅僅是 String,也可以是數字、甚至是一個序列化對象。

2、Hash 類型:

一個 key 對應 多個 field,一個 field 對應 yige value,實際上該類型最适合存儲序列化對象。

           key 相當于資料庫表名字,field  相當于主鍵,value 也就是序列化對象。

3、List 類型:

簡單的字元串清單,按照插入順序排序,該結構類似于資料結構中的雙向連結清單,可以從頭部插也可以從尾部插。

4、Set 類型:

它是字元串集合,隻不過它是無序的且不存在重複的字元串,但是它可以實作 交集、并集、差集。

5、ZSet 類型:

它也是字元串集合,它和 Set 的差別是該集合的元素存在 score 屬性,按照 score 屬性的高低排序。

可以應用在排行榜上。

值得注意的是,不要習慣性的認為 Redis 字元串隻能存字元串,實際上,它可以存儲任何序列化後的對象,當然也可以讀出來。

 小青蛙知道了 Redis 的五種資料類型應用場景後,迫不及待的想要實踐它了。

為了知道如何讓它作為緩存,以及如何操作資料,小青蛙打開了珍藏已久的視訊網站來學習:

青蛙愛學習在該視訊網站上,小青蛙沉迷其中無法自拔,額,呸呸。

緩過神來,發現了一個很好的視訊。

小青蛙幽默的說:

快進我的收藏夾吃灰去吧。

小青蛙向來都不是一個收藏從未停止,學習從未開始的青蛙。

它模仿着視訊建了一個 SpringBoot 項目。

此時,小青蛙想為什麼要勾選 Lombok 呢,因為它可以簡化類,并且提供了 log 等功能。

之後小青蛙為了連上 Mysql 和 Redis 就開始配置 application.properties 檔案:

# 資料源配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&characterEncoding=utf-8
spring.datasource.username=root
[email protected]

# Redis 配置
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
spring.redis.lettuce.shutdown-timeout=100
           

配置好該檔案後,需要 redisTemplate 模闆 Bean,因為自動配置的 redisTemplate Bean 沒有提供序列化操作:

(因為是入門版的,是以這樣最好了解)

package com.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
    
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplatetemplate = new RedisTemplate();template.setConnectionFactory(factory);
                GenericJackson2JsonRedisSerializer genericJsonRedisSerializer = new GenericJackson2JsonRedisSerializer();template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(genericJsonRedisSerializer);template.setHashKeySerializer(genericJsonRedisSerializer);template.setHashValueSerializer(genericJsonRedisSerializer);template.afterPropertiesSet();return template;
    }
}
           

至此就整合完成了,小青蛙心想這就完事了?,不信?

那就來示範一下:

(先建一個簡單的類測試一下)

package com.test.serviceImpl;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class JustForTest {
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    public void test(String username) {
        
        if(redisTemplate.hasKey(username)) {
            log.info((String)redisTemplate.opsForValue().get(username));
            log.info("get value from redis");
        }else {
            String password = "password";
            log.info(password);
            log.info("get value from mysql");
            log.info("set value to redis");
            redisTemplate.opsForValue().set(username, password);
        }
        
    }

}
           
package com.test;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;
import com.test.serviceImpl.JustForTest;

@SpringBootTest
class TestApplicationTests {
    
    @Autowired
    private JustForTest justFortest;

    @Test
    void contextLoads() {
        justFortest.test("username");
    }
}
           

哦嚯,報錯了,原來是 pom.xml 中少了 commons.pool 依賴,咱給它加上:

<dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-pool2artifactId>
        dependency>
           

再來一次:

再再來一次:

可以看到确實存入 Redis 了,小青蛙便去 Redis 資料庫中看看有沒有:

事實證明确實整合完畢了,小青蛙仍然表示不解,說好的是SpringBoot、Mybatis、Redis的整合呢,怎麼隻看到 Redis 的?

小青蛙剛這麼想,然後視訊裡就說了,心急吃不了熱豆腐,需要慢慢來。

緊接着,小青蛙就看到了完整的項目結構:

為了讓青蛙們隻關注有關整合的部分,視訊裡僅僅隻給出 serviceImpl 中的代碼:

package com.demo.serviceImpl;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import com.demo.pojo.SimpleUser;
import com.demo.dao.SimpleUserDao;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
@SuppressWarnings({"rawtypes","unchecked"})
public class SimpleUserServiceImpl implements UserDetailsService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SimpleUserDao userDao;
    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO Auto-generated method stub
        if(redisTemplate.opsForHash().hasKey("user",username)) {
            SimpleUser user = (SimpleUser)redisTemplate.opsForHash().get("user",username);
            return new User(user.getUsername(),user.getPassword(),user.getAuthorities());
        }else {
            SimpleUser user = userDao.findUserByUsername(username);
            if(user != null) {
                redisTemplate.opsForHash().put("user", "username", user);
                return new User(user.getUsername(),user.getPassword(),user.getAuthorities());
            }else {
                throw new UsernameNotFoundException("Username or Password is not correct");
            }
        }
    }
    
    public int addSimpleUser(SimpleUser user) {
        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
        return userDao.addSimpleUser(user);
    }
}
           

和上面測試的簡單小例子相似,僅僅是把 String 換成了對象。

小青蛙對 Mysql 的表結構和Redis中存入的資料比較感心趣:

由于對 String 類型帶有 " 符号,是以需要對其進行轉義。

小青蛙是一個有分享精神的蛙,每次它覺得有價值的東西,它都會分享給它的朋友們,項目位址為:GitHub

小青娃逐漸的弄懂了怎麼去進行整合,但是它還是不太明白為什麼這樣就能整合,也就是 know how but don't konw why!

小青蛙知道:

萬事開頭難,但它不知道的是,後面也很難...從此,小青蛙踏上了探尋源碼的道路!

呱呱呱......

mybatis redis_SpringBoot + Mybatis + Redis 整合入門項目
mybatis redis_SpringBoot + Mybatis + Redis 整合入門項目
  • 程式員值得收藏的精選11套背景登入頁面和管理頁面模版

  • 50份優秀Java求職者履歷

  • SpringCloud前後端分離實戰項目視訊教程分享

  • 2020年全網最全BAT筆試面試題打包分享

感謝點贊支援下哈 

mybatis redis_SpringBoot + Mybatis + Redis 整合入門項目

繼續閱讀