Support of Redis for Spring Data
CAST supports Redis via its
com.castsoftware.nosqljava external link extension.
Details about how this support is provided for Java with Spring
Data source code is discussed below.
Supported Libraries
Library
Version
Supported
RedisConnectionFactory
Up to: 2.7.7
✅
RedisTemplate
Up to: 2.7.7
✅
StringRedisTemplate
Up to: 2.7.7
✅
LettuceConnectionFactory
Up to: 2.7.7
✅
JedisConnectionFactory
Up to: 2.7.7
✅
CrudRepository *
Up to: 2.7.7
✅
JpaRepository *
Up to: 2.7.7
✅
CrudRepository and JpaRepository are supported only if the repository is created using @RedisHash domain.
Supported Operations
Insert
org.springframework.data.redis.core.ValueOperations
org.springframework.data.redis.core.ValueOperations.set
org.springframework.data.redis.core.ValueOperations.multiSet
org.springframework.data.redis.core.ValueOperations.multiSetIfAbsent
org.springframework.data.redis.core.ValueOperations.setIfAbsent
org.springframework.data.redis.core.ValueOperations.append
org.springframework.data.redis.core.ListOperations
org.springframework.data.redis.core.ListOperations.leftPush
org.springframework.data.redis.core.ListOperations.leftPushAll
org.springframework.data.redis.core.ListOperations.rightPush
org.springframework.data.redis.core.ListOperations.rightPushAll
org.springframework.data.redis.core.ListOperations.set
org.springframework.data.redis.core.HashOperations
org.springframework.data.redis.core.HashOperations.putAll
org.springframework.data.redis.core.HashOperations.put
org.springframework.data.redis.core.HashOperations.putIfAbsent
org.springframework.data.redis.core.SetOperations.add
org.springframework.data.repository.CrudRepository.save
org.springframework.data.repository.CrudRepository.saveAll
org.springframework.data.jpa.repository.JpaRepository.save
org.springframework.data.jpa.repository.JpaRepository.saveAll
org.springframework.data.jpa.repository.JpaRepository.saveAndFlush
Select
org.springframework.data.redis.core.ValueOperations
org.springframework.data.redis.core.ValueOperations.get
org.springframework.data.redis.core.ValueOperations.multiGet
org.springframework.data.redis.core.ValueOperations.size
org.springframework.data.redis.core.ValueOperations.bitField
org.springframework.data.redis.core.ValueOperations.getAndDelete
org.springframework.data.redis.core.ValueOperations.getAndSet
org.springframework.data.redis.core.ListOperations
org.springframework.data.redis.core.ListOperations.range
org.springframework.data.redis.core.ListOperations.size
org.springframework.data.redis.core.ListOperations.index
org.springframework.data.redis.core.ListOperations.indexOf
org.springframework.data.redis.core.ListOperations.lastIndexOf
org.springframework.data.redis.core.HashOperations
org.springframework.data.redis.core.HashOperations.hasKey
org.springframework.data.redis.core.HashOperations.get
org.springframework.data.redis.core.HashOperations.multiGet
org.springframework.data.redis.core.HashOperations.keys
org.springframework.data.redis.core.HashOperations.values
org.springframework.data.redis.core.HashOperations.lengthOfValue
org.springframework.data.redis.core.HashOperations.size
org.springframework.data.redis.core.HashOperations.entries
org.springframework.data.redis.core.HashOperations.randomEntries
org.springframework.data.redis.core.HashOperations.randomEntry
org.springframework.data.redis.core.HashOperations.randomKey
org.springframework.data.redis.core.HashOperations.randomKeys
org.springframework.data.redis.core.HashOperations.scan
org.springframework.data.redis.core.SetOperations
org.springframework.data.redis.core.SetOperations.size
org.springframework.data.redis.core.SetOperations.isMember
org.springframework.data.redis.core.SetOperations.members
org.springframework.data.repository.CrudRepository
org.springframework.data.repository.CrudRepository.findAll
org.springframework.data.repository.CrudRepository.count
org.springframework.data.repository.CrudRepository.findById
org.springframework.data.repository.CrudRepository.findAllById
org.springframework.data.repository.CrudRepository.existsById
org.springframework.data.jpa.repository.JpaRepository
org.springframework.data.jpa.repository.JpaRepository.count
org.springframework.data.jpa.repository.JpaRepository.findAll
org.springframework.data.jpa.repository.JpaRepository.findAllById
org.springframework.data.jpa.repository.JpaRepository.exists
org.springframework.data.jpa.repository.JpaRepository.findOne
org.springframework.data.jpa.repository.JpaRepository.findById
org.springframework.data.jpa.repository.JpaRepository.existsById
org.springframework.data.repository.PagingAndSortingRepository.findAll
Delete
org.springframework.data.redis.core.ListOperations
org.springframework.data.redis.core.ListOperations.remove
org.springframework.data.redis.core.ListOperations.rightPop
org.springframework.data.redis.core.ListOperations.leftPop
org.springframework.data.repository.CrudRepository
org.springframework.data.repository.CrudRepository.deleteAll
org.springframework.data.repository.CrudRepository.deleteById
org.springframework.data.repository.CrudRepository.delete
org.springframework.data.jpa.repository.JpaRepository
org.springframework.data.jpa.repository.JpaRepository.deleteInBatch
org.springframework.data.jpa.repository.JpaRepository.deleteAllInBatch
org.springframework.data.jpa.repository.JpaRepository.delete
org.springframework.data.jpa.repository.JpaRepository.deleteAll
org.springframework.data.jpa.repository.JpaRepository.deleteAllById
org.springframework.data.jpa.repository.JpaRepository.deleteById
org.springframework.data.redis.core.HashOperations.delete
org.springframework.data.redis.core.SetOperations.remove
org.springframework.data.redis.core.SetOperations.pop
org.springframework.data.redis.core.ValueOperations.getAndDelete
org.springframework.data.redis.core.RedisTemplate.delete
Update
org.springframework.data.jpa.repository.JpaRepository
org.springframework.data.jpa.repository.JpaRepository.deleteInBatch
org.springframework.data.jpa.repository.JpaRepository.deleteAllInBatch
org.springframework.data.jpa.repository.JpaRepository.delete
org.springframework.data.jpa.repository.JpaRepository.deleteAll
org.springframework.data.jpa.repository.JpaRepository.deleteAllById
org.springframework.data.jpa.repository.JpaRepository.deleteById
org.springframework.data.redis.core.ValueOperations
org.springframework.data.redis.core.ValueOperations.increment
org.springframework.data.redis.core.ValueOperations.decrement
org.springframework.data.redis.core.ValueOperations.getAndSet
org.springframework.data.redis.core.ValueOperations.setIfPresent
org.springframework.data.redis.core.ValueOperations.getAndSet
org.springframework.data.redis.core.ListOperations
org.springframework.data.redis.core.ListOperations.trim
org.springframework.data.redis.core.ListOperations.leftPushIfPresent
org.springframework.data.redis.core.ListOperations.rightPushIfPresent
org.springframework.data.redis.core.HashOperations.increment
Objects
Java Redis
Connection
Java Redis
Collection
Java unknown Redis
Connection
Java Unknown Redis
Collection
Links
parentLink
Between Redis
connection object and Redis collection object
-
useLink
Between the caller
Java method object and Redis collection object
multiGet
get
keys
entries
findAllById
findAll
useSelectLink
Between the caller
Java method object and Redis collection object
multiGet
get
keys
entries
findAllById
findAll
useInsertLink
Between the caller
Java method object and Redis collection object
set
put
putAll
add
leftpush
save
saveAll
useDeleteLink
Between the caller
Java method object and Redis collection object
delete
remove
deleteById
deleteAll
useUpdateLink
Between the caller
Java method object and Redis collection object
What results can you expect? Some example scenarios are shown below:
Redis Connections and Collections @Autowired
private ServiceConfigResource serviceConfigResource ;
RedisConnectionFactory switchRedisMaster () {
return getRedisConnectionFactory ( serviceConfigResource . getSwitchRedisMaster (), serviceConfigResource . getDisRedisPort ());
}
Java based configurations @Configuration
@RefreshScope
@Getter
public class ServiceConfigResource {
@Value ( "${disredis.host.disRedisHost1}" )
private String switchRedisMaster ;
@Value ( "${disredis.host.disRedisHost2}" )
private String switchRedisSlave1 ;
@Value ( "${disredis.host.disRedisHost3}" )
private String switchRedisSlave2 ;
@Value ( "${disredis.port.disRedisPort1}" )
private int disRedisPort ;
@Value ( "${useRoomSharedUsedTable}" )
private int useRoomSharedUsedTable ;
}
Xml based configurations <? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans"
xmlns : xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns : p = "http://www.springframework.org/schema/p"
xmlns : redis = "http://www.springframework.org/schema/redis"
xsi : schemaLocation = "
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis.xsd
" >
<!-- Jedis Connection -->
< bean id = "jedisConnectionFactory" class =" org . springframework . data . redis . connection . jedis . JedisConnectionFactory "
p:host-name=" localhost " p:port=" 6379 " />
<!-- Redis Template -->
<bean id=" redisTemplate " class=" org . springframework . data . redis . core . RedisTemplate ">
<property name=" connectionFactory " ref=" jedisConnectionFactory " />
<property name=" valueSerializer ">
<bean id=" redisJsonSerializer " class=" org . springframework . data . redis . serializer . JacksonJsonRedisSerializer ">
<constructor-arg type=" java . lang . Class " value=" redis . User "/>
</bean>
</property>
</bean>
<bean class=" redis . UserRepository "/>
</beans>
Lettuce public ReactiveRedisConnectionFactory build () {
LettuceClientConfiguration clientConfig ;
LettuceClientConfiguration . LettuceClientConfigurationBuilder builder =
LettuceClientConfiguration . builder ();
if ( ssl ) {
builder . commandTimeout ( Duration . ofSeconds ( timeout )). useSsl ();
}
clientConfig = builder . build ();
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration ();
configuration . setHostName ( host );
configuration . setPassword ( password );
configuration . setPort ( port );
return new LettuceConnectionFactory ( configuration , clientConfig );
RedisHash Domain /*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package io.project.app.domain ;
import java.io.Serializable ;
import lombok.AllArgsConstructor ;
import lombok.Data ;
import lombok.EqualsAndHashCode ;
import lombok.NoArgsConstructor ;
import lombok.ToString ;
import org.springframework.data.redis.core.RedisHash ;
/
*
* @author armena
*/
@RedisHash
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class SearchData implements Serializable {
private String id ; //unique id
private String key ; //key for search
private String title ;
private String content ;
}
Redis Repo Creation using CrudRepository /*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package io.project.app.repositories ;
import io.project.app.domain.SearchData ;
import org.springframework.data.repository.CrudRepository ;
import org.springframework.stereotype.Component ;
import org.springframework.stereotype.Repository ;
/
*
* @author armena
*/
@Repository
@Component
public interface SearchRepository extends CrudRepository < SearchData , String > {
public SearchRepository findByTitle ( String title );
}
Insert Operation @Bean ( name = "switch_redis_master" )
< T > RedisTemplate < String , T > switchMasterRedis () {
RedisTemplate template = new RedisTemplate <> ();
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer ( Object . class );
template . setConnectionFactory ( switchRedisMaster ());
template . setKeySerializer ( new StringRedisSerializer ());
template . setValueSerializer ( fastJsonRedisSerializer );
return template ;
}
@Autowired
@Qualifier ( "switch_redis_master" )
private RedisTemplate < String , Integer > redisTemplate ;
private boolean invokeFrequencyValidate ( String agentCode , Date checkInDate , Date checkOutDate ) {
int openingHotelNum = hotelService . getOpeningHotelNum ();
Date currentDate = new Date ();
// 16-90
if ( AbstractDateUtils . isAfter ( checkInDate , AbstractDateUtils . getDeltaDateByDays ( currentDate , 15 ))) {
Integer count = redisTemplate . opsForValue (). get ( agentCode + "_" + SIXTEEN_TO_NINETY );
if ( count == null ) {
redisTemplate . opsForValue (). set ( agentCode + "_" + SIXTEEN_TO_NINETY , 1 , TIME_PERIOD_THREE , TimeUnit . MINUTES );
return true ;
}
if ( count >= maxQueryBase + openingHotelNum / FIFTEEN_OUTER_DIVIDED ) {
return false ;
}
return true ;
}
CrudRepository Insert Operation @Autowired
private SearchRepository searchRepository ;
public SearchData save ( SearchData googleSearch ) {
return searchRepository . save ( googleSearch );
}
Select Operation private List < RoomShareUsedCountEntity > calculateRoomShareUsedCountWithType ( StandardRoomWithTypeRequest standardRoomWithTypeRequest ) {
List < String > validDateList = calculateAllKeyDate ( standardRoomWithTypeRequest . getCheckInDate (), standardRoomWithTypeRequest . getCheckOutDate ());
List < String > fullKey = Lists . newArrayList ();
List < UsedShareRoomCount > allUsedShareRoomCountList = Lists . newArrayList ();
for ( String key : fullKey ) {
List < UsedShareRoomCount > value = ( List < UsedShareRoomCount > ) usedShareRoomCountSlaveRedisTemplate . opsForValue (). get ( key );
}
if ( CollectionUtils . isEmpty ( allUsedShareRoomCountList )) {
return Lists . newArrayList ();
}
return convert2RoomShareUsedCountEntityFromUsedShareCount ( allUsedShareRoomCountList );
}
CrudRepository Select Operation @Autowired
private SearchRepository searchRepository ;
public Optional < SearchData > find ( String id ) {
return searchRepository . findById ( id );
}
Update Operation private boolean invokeFrequencyValidate ( String agentCode , Date checkInDate , Date checkOutDate ) {
int openingHotelNum = hotelService . getOpeningHotelNum ();
Date currentDate = new Date ();
// 16-90
if ( AbstractDateUtils . isAfter ( checkInDate , AbstractDateUtils . getDeltaDateByDays ( currentDate , 15 ))) {
Integer count = redisTemplate . opsForValue (). get ( agentCode + "_" + SIXTEEN_TO_NINETY );
if ( count == null ) {
redisTemplate . opsForValue (). set ( agentCode + "_" + SIXTEEN_TO_NINETY , 1 , TIME_PERIOD_THREE , TimeUnit . MINUTES );
return true ;
}
if ( count >= maxQueryBase + openingHotelNum / FIFTEEN_OUTER_DIVIDED ) {
return false ;
}
redisTemplate . opsForValue (). increment ( agentCode + "_" + SIXTEEN_TO_NINETY , 1 );
return true ;
}
Delete Operation public void delete ( String key ) {
template . opsForValue (). getOperations (). delete ( key );
}
CrudRepository Delete Operation @Autowired
private SearchRepository searchRepository ;
public Optional < SearchData > delete ( String id ) {
return searchRepository . deleteById ( id );
}
Known Limitations
Unknown Redis connection/collection objects are created in case of
unresolved names.