کار با Spring boot و Redis -بخش 2

کار با Spring boot و Redis-بخش 1در ابتدا به pom فایل پروژه dependency های زیر را اضافه کنید.<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> </dependencies>یک کلاس config باید ایجاد کنیم و دوتا bean به نام های JedisConnectionFactory و RedisTemplate را به spring معرفی کنیم.@Configuration public class BeanConfig { @Bean RedisConnectionFactory connectionFactory() { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(&quotlocalhost&quot, 6379); return new JedisConnectionFactory(redisStandaloneConfiguration); } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } }می تونید اطلاعات مثل پورت و ip و .. را نیز از طریق فایل application.properties نیز به پروژه اضافه کنید.spring.redis.host=127.0.0.1 spring.redis.password=password spring.redis.port=6379حتی اطلاعاتی چون connection pool مانند زیر :spring.cache.type=redisspring.redis.timeout=60000 spring.redis.jedis.pool.max-idle=100 spring.redis.jedis.pool.min-idle=2 spring.redis.jedis.pool.max-active=200بریم سر وقت عملیات crud با restTemplate بدون ذخیره سازی در دیتابیس:عملیات crud رو بر روی objectای به نام Account با اطلاعات زیر اعمال می کنیم، حتما باید Serializable را implements کرده باشید.public class Account implements Serializable { private Long id; private Double balance; public Account() { } public Account(Long id, Double balance) { this.id = id; this.balance = balance; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Double getBalance() { return balance; } public void setBalance(Double balance) { this.balance = balance; } @Override public String toString() { return &quotAccount{&quot + &quotid=&quot + id + &quot, balance=&quot + balance + '}'; } }سپس یک کلاس repository می سازیم و دو تا object های RedisTemplate و HashOperations را از طریق سازندش مقدار دهی می کنیم و تمام متد های مورد نیاز برای عملیات crud را ایجاد می کنیم.@Repositorypublic class RedisAccountRepository { private static final String KEY = "ACCOUNT"; private HashOperations hashOperations; private RedisTemplate<String, Object> redisTemplate; public RedisAccountRepository(RedisTemplate redisTemplate){ this.redisTemplate = redisTemplate; this.hashOperations = this.redisTemplate.opsForHash(); } public void save(Account account){ hashOperations.put(KEY, account.getId().toString(), account); } public void update(Account account){ save(account); } public void delete(String id){ hashOperations.delete(KEY, id); } public Account findById(String id){ return (Account) hashOperations.get(KEY, id); } public List findAll(){ return hashOperations.values(KEY); } }حتما key که تعریف می کنید static و final باشد.هر 3 متد ذخیره که با hashOperations انجام می شود (put , putIfAbsent , putAll) نیاز به 3 متغیر ورودی دارند.void put(H key, HK hashKey, HV value);مقدار key باید یکتا باشد .برای ویرایش کافی است از همان شیوه ی ذخیره استفاده کنید چون در صورتی که در زمان ذخیره بر اساس key , hashkey رکورد را پیدا کند، مقدار value جدید را جایگزین قبلی می کند.در صورتی که نیاز باشد چند object را باهم از cache بخوانید می توانید از متد multiGet استفاده کنید:public Map<String, List<Account>> multiGetAccount(List<String> accountIds){ Map<String, List<Account>> accountMap = new HashMap<>(); List<Object> accounts = hashOperations.multiGet(KEY, accountIds); for (int i = 0; i < accountIds.size(); i++) { accountMap.put(accountIds.get(i), (List<Account>) accounts.get(i)); } return accountMap; } با یک کلاس کنترلر می تونید تمام موارد را باهم داشته باشد و یکجا تست کنید.@RestController @RequestMapping(path = &quot/redisRepository&quot) public class RedisRepositoryController { @Autowired private RedisAccountRepository repository; @GetMapping(value = &quot/getAll&quot,produces = MediaType.APPLICATION_JSON_VALUE) public List<Account> getAllAccount() { return repository.findAll(); } @PostMapping(value = &quot/save&quot,consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public void save(@RequestBody Account account) { repository.save(account); } @PostMapping(value = &quot/update&quot,consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public void update(@RequestBody Account account) { repository.update(account); } @GetMapping( &quot/deleteById/{id}&quot) public void deleteById(@PathVariable String id) { repository.delete(id); } @GetMapping(value = &quot/getById/{id}&quot,produces = MediaType.APPLICATION_JSON_VALUE) public Account findById(@PathVariable String id) { return repository.findById(id); } } می تونید dependency های مربوط به سویگر و کلاس config اش رو هم به پروژه تون اضافه کنید و به کمک سویگر عملیات crud بر روی redis رو تست کنید.<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>کلاس config مربوط به سویگر:@Configuration@EnableSwagger2public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); }}سویگر با آدرس زیر بر اساس پورتی که پروژه با آن بالا است قابل دسترس می باشد:http://localhost:8082/swagger-ui.htmدر صورتی که بخواهید اطلاعات را از دیتابیس بخوانید و عملیات cache را نیز انجام دهید، باید dependency زیر را به pom فایل اضافه کنید.<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> از @Cacheable بالاسر متد می توان استفاده کرد. در صورتی که در cache بر اساس value , key مقدار وجود داشته باشد دیگر متد اجرا نمی شود و اطلاعات را از cache می خواند در غیر این صورت متد اجرا شده و اطلاعات از دیتابیس فراخوانی می شود. حتما باید @EnableCaching را در کنار @SpringBootApplication در بالاسر کلاس main خود قرار دهید.@Cacheable(value = &quotAccountCache&quot, key=&quot#id&quot) public Account getAccount(String id) { System.out.println(&quotIn getAccount cache Component..&quot); return accountRepository.findOne(Long.valueOf(id)); }از @CacheEvict در بالا سر متدهایی که بر روی اطلاعات تاثیر می ذارند مانند ویرایش - ذخیره و حذف استفاده کنید تا اخرین تغییرات را در سمت cache نیز داشته باشید.@Caching(evict = { @CacheEvict(value=&quotAccountCache&quot, allEntries=true)}) public void saveOrUpdate(Account account) { System.out.println(&quotIn addAccount cache component..&quot); redisAccountRepository.save(account); }کدپروژه