springBoot2.0 MyBatis Redis 及RedisCache 整合附demo
阿新 • • 發佈:2019-01-06
springboot2.0 + mybatis 或者 springboot2.0 + redis 在網上可以找到很多資料,但是大都不全或者有這樣那樣的問題,所以便自己動手寫了個demo,能只用 yaml 配置的,儘量不再寫程式碼。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.carlton</groupId> <artifactId>MybatisDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>MybatisDemo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <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.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.hynnet</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.yml
--- server: port: 8080 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/trymaster?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123123 driver-class-name: com.mysql.jdbc.Driver hikari: #springboot2.X 預設使用hikari作為資料來源 minimum-idle: 5 maximum-pool-size: 15 connection-test-query: select 1 max-lifetime: 1800000 connection-timeout: 30000 pool-name: HikariDataPool redis: host: 127.0.0.1 port: 6379 password: 123123 database: 1 timeout: 60s jedis: pool: max-idle: 50 min-idle: 5 max-wait: -1s max-active: -1 transaction: rollback-on-commit-failure: true cache: type: redis cache-names: redisCache redis: time-to-live: 60s use-key-prefix: true key-prefix: cacheee mybatis: mapper-locations: com/carlton/demo/mapper/*.xml type-aliases-package: com.carlton.demo.entity logging: level: com.carlton.demo.mapper: debug ...
mybatis 因為直接用了springboot配置,不需要重寫配置類。
redis 預設的 RedisTemplate 只支援儲存 RedisTemplate<String, String>,如果希望能儲存物件,則需重寫 RedisTemplate<String, Object>,另外,使用RedisCache的話,為解決亂碼問題,也要重寫CacheManager。
RedisConfig.java
package com.carlton.demo.conf; import java.time.Duration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; 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.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import com.carlton.demo.util.RedisUtil; import com.fasterxml.jackson.databind.ObjectMapper; /*** * <p>Title: RedisConfig</p> * <p>Description: reids配置類</p> * @author Carlton * @date 2018年10月8日 下午4:37:44 */ @Configuration @ConfigurationProperties(prefix = "spring.cache.redis") public class RedisConfig { private Duration timeToLive = Duration.ZERO; private String keyPrefix; /*** * 注入封裝RedisTemplate * * @author Carlton * @date 2018年10月8日 下午4:27:06 * @param redisTemplate * @return */ @Bean(name = "redisUtil") public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) { RedisUtil redisUtil = new RedisUtil(); redisUtil.setRedisTemplate(redisTemplate); return redisUtil; } /*** * 例項化 RedisTemplate 物件 * * @author Carlton * @date 2018年10月8日 下午4:27:26 * @param redisConnectionFactory * @return */ @Bean public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } /*** * 設定資料存入 redis 的序列化方式,並開啟事務 * * @author Carlton * @date 2018年10月8日 下午4:27:18 * @param redisTemplate * @param factory */ private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) { // 如果不配置Serializer,那麼儲存的時候預設使用String,如果用User型別儲存,那麼會提示錯誤User can't cast to // String! redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setEnableTransactionSupport(true); redisTemplate.setConnectionFactory(factory); } /*** * 自定義 RedisCacheManager 類,主要是設定序列化,解決亂碼問題 * * @author Carlton * @date 2018年10月9日 下午2:46:15 * @param factory * @return */ @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>( Object.class); // 解決查詢快取轉換異常的問題 ObjectMapper om = new ObjectMapper(); // om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解決亂碼的問題) RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith( RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues().entryTtl(timeToLive).prefixKeysWith(keyPrefix); RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build(); return cacheManager; } public void setTimeToLive(Duration timeToLive) { this.timeToLive = timeToLive; } public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } }
RedisUtil.java
redis工具類,封裝各種常用方法,定義了一個變數 RedisTemplate<String, Object> redisTemplate
private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
具體程式碼不貼了,有興趣請拉到文末看demo。
myBatis 實體類User 和mapper 省略,不過要注意的是,如果要使用 RedisCache,User 需要實現介面Serializable,否則報錯。
測試類:
MybatisDemoApplicationTests.java
package com.carlton.demo;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import com.carlton.demo.entity.User;
import com.carlton.demo.mapper.UserMapper;
import com.carlton.demo.service.TestService;
import com.carlton.demo.util.RedisUtil;
@RunWith(SpringRunner.class)
@SpringBootTest
@EnableCaching
@ConfigurationProperties(prefix = "spring.cache.redis")
public class MybatisDemoApplicationTests {
private String keyPrefix;
@Autowired
DataSource dataSource;
@Autowired
RedisTemplate<String, String> redisTemplate;
@Autowired
RedisUtil redisUtil;
@Autowired
UserMapper userMapper;
@Autowired
TestService testService;
@Test
public void test() {
System.out.println(dataSource.getClass());
}
@Test
public void set() {
// 測試 redisTemplate
redisTemplate.opsForValue().set("test:set", "testValue1多噢ffff噢噢噢發生的風");
String str = redisTemplate.opsForValue().get("test:set");
System.out.println(str);
// 測試 redisUtil 存取 String
redisUtil.set("eeeee", "1123地地道道的");
str = redisTemplate.opsForValue().get("eeeee");
System.out.println(str);
// 測試 reidsUtil 儲存物件
User user = new User();
user.setAge(555);
user.setName("娃哈哈哈哈哈");
user.setId(55);
redisUtil.set("user:login", user);
}
@Test
public void cacheeMybatis() {
System.out.println("=============================測試cache 從資料庫取=============================");
int id = 9;
User user = userMapper.selectByPrimaryKey(id);
System.out.println("-------------" + user.getId() + "-------------");
Object obj = redisUtil.get(keyPrefix + id);
System.out.println(obj.toString());
User user2 = (User) obj;
System.out.println(user2.getName());
}
@Test
public void cachee() {
System.out.println("=============================測試cache2 自定義生成=============================");
testService.testPrint();
User user = testService.gener(99, "qqq", 55);
System.out.println("-------------" + user.getId() + "-------------");
}
public void setKeyPrefix(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
}
專案demo: