Springboot2.x使用JPA整合Redis

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(cacheNamesvalue作用一樣)


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=?

第二次調用的時候只會打印一句話,並不會顯示查詢語句,此時,緩存生效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章