SpringBoot2.3,使用MySQL數據庫,通過JPA實現ORM,再用Redis實現數據庫的緩存。
代碼實現:
pom.xml
<!-- 集成redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!-- 集成data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
application.properties
#數據庫索引(默認爲0)
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=
#連接超時時間
spring.redis.timeout=10000
#最大連接數
spring.redis.jedis.pool.max-active=8
#最大阻塞等待時間(負數表示沒限制)
spring.redis.jedis.pool.max-wait=-1
#最大空閒
spring.redis.jedis.pool.max-idle=8
#最小空閒
spring.redis.jedis.pool.min-idle=0
#==================mysql========================
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/woxiang_test?setUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=000000
#====================jps======================
# 數據庫類型
spring.jpa.database=mysql
# 輸出日誌
spring.jpa.show-sql=true
# JPA配置
spring.jpa.hibernate.ddl-auto=update
在Springboot2TestApplication添加註解(@EnableCaching)
一定要注意加上該註解,否則不生效!!!
@SpringBootApplication
@EnableCaching
public class Springboot2TestApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot2TestApplication.class, args);
}
}
RedisConfig
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
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.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.lang.reflect.Method;
import java.time.Duration;
/**
* Redis 緩存配置類
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 緩存對象集合中,緩存是以 key-value 形式保存的。
* 當不指定緩存的 key 時,SpringBoot 會使用 SimpleKeyGenerator 生成 key。
*/
// @Bean
public KeyGenerator wiselyKeyGenerator() {
// key前綴,用於區分不同項目的緩存,建議每個項目單獨設置
final String PRE_KEY = "test";
final char sp = ':';
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(PRE_KEY);
sb.append(sp);
sb.append(target.getClass().getSimpleName());
sb.append(sp);
sb.append(method.getName());
for (Object obj : params) {
sb.append(sp);
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// 更改值的序列化方式,否則在Redis可視化軟件中會顯示亂碼。默認爲JdkSerializationRedisSerializer
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer());
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration
.defaultCacheConfig()
.serializeValuesWith(pair) // 設置序列化方式
.entryTtl(Duration.ofHours(1)); // 設置過期時間
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
.cacheDefaults(defaultCacheConfig).build();
}
}
實體類User(實現Serializable接口)
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 1l;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String username;
private String password;
public User() {
}
public User(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserMapper
import com.test.springboot2_test.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserMapper extends JpaRepository<User, Integer> {
}
UserService
import com.test.springboot2_test.domain.User;
public interface UserService {
User findById(Integer id);
void save(User user);
}
UserServiceImpl(cacheNames
與value
作用一樣)
import com.test.springboot2_test.domain.User;
import com.test.springboot2_test.repository.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
@CacheConfig(cacheNames = "userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
@Cacheable(value = "user", key = "#p0")
public User findById(Integer id) {
Optional<User> _User = userMapper.findById(id);
return Optional.ofNullable(_User).get().orElse(null);
}
@Override
public void save(User user) {
userMapper.save(user);
}
}
UserController
import com.test.springboot2_test.domain.AjaxResponse;
import com.test.springboot2_test.domain.User;
import com.test.springboot2_test.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@Api(description = "用戶接口")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
@ApiOperation(value = "獲取用戶", notes = "根據id查詢一個用戶")
public AjaxResponse toHello(@PathVariable("id") Integer id) {
System.out.println("只有第一次纔會打印sql語句");
User u = userService.findById(id);
return AjaxResponse.success(u);
}
@PostMapping("/users")
@ApiOperation(value = "增加用戶", notes = "增加一個用戶")
public AjaxResponse saveUser(@RequestBody User user) {
log.info("User:" + user);
userService.save(user);
return AjaxResponse.success();
}
}
測試:
啓動服務後,可以看到 JPA框架自動生成user表。
使用swagger-ui對接口進行操作
1)添加幾個用戶
2)根據id查找用戶
使用Redis客戶端命令登錄redis:
redis-cli -h 127.0.0.1 -p 6379
查看數據:
127.0.0.1:6379> keys *
1) "user::4"
127.0.0.1:6379> get user::4
"{\"@class\":\"com.test.springboot2_test.domain.User\",\"id\":4,\"username\":\"wangnian\",\"password\":\"wang\"}"
127.0.0.1:6379>
此時查看控制檯的信息,第一次調用的時候會打印一句話,隨後會顯示自動生成的查詢語句:
只有第一次纔會打印sql語句
Hibernate: select user0_.id as id1_0_0_, user0_.password as password2_0_0_, user0_.username as username3_0_0_ from user user0_ where user0_.id=?
第二次調用的時候只會打印一句話,並不會顯示查詢語句,此時,緩存生效。