| 知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency>
<!-- Redis Connection Factory --> <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="192.168.2.1" p:port="6379" p:use-pool="true" /> <!-- redis redisTemplate definition --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnFactory" />
例 8.1. Spring Data Redis Example
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/css/" mapping="/css/**" />
<context:component-scan base-package="cn.netkiller.controller" />
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<!-- <property name="viewNames" value="*.jsp" /> -->
</bean>
<bean id="configuracion"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:resources/development.properties" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.netkiller.mapper" />
</bean>
<bean id="userService" class="cn.netkiller.service.UserService">
</bean>
<!-- Redis Connection Factory -->
<bean id="jedisConnFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="192.168.2.1" p:port="6379" p:use-pool="true" />
<!-- redis redisTemplate definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnFactory" />
</beans>
package cn.netkiller.controller;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import cn.netkiller.model.User;
@Controller
public class CacheController {
// inject the actual redisTemplate
@Autowired
private RedisTemplate<String, String> redisTemplate;
// inject the redisTemplate as ListOperations
@Resource(name = "redisTemplate")
private ListOperations<String, String> listOps;
@RequestMapping("/cache")
public ModelAndView cache() {
String message = "";
User user = new User();
user.setId("1");
user.setName("Neo");
user.setAge(30);
String key = "user";
listOps.leftPush(key, user.toString());
message = listOps.leftPop(key);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.opsForValue().set("key", user.toString());
return new ModelAndView("index/index", "variable", message);
}
}
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<br>
<div style="text-align:center">
<h2>
${variable}
</h2>
</div>
</body>
</html>
請求URL http://your.domain.com/your.html
[root@master ~]# redis-cli redis 127.0.0.1:6379> keys * 1) "\xac\xed\x00\x05t\x00\x04user" 2) "key" redis 127.0.0.1:6379> get key "\xac\xed\x00\x05t\x00\x1dUser [id=1, name=Neo, age=30]"
![]() | 提示 |
|---|---|
|
Spring Redis 預設使用 Byte數據類型存儲Key,在redis-cli中會看到 "\xac\xed\x00\x05t\x00\x04" 首碼不方便get操作,所以我們會設置使用字元串,通過 redisTemplate.setKeySerializer(new StringRedisSerializer()); 實現 |
stringRedisTemplate.opsForValue().set("test", "100",60*10,TimeUnit.SECONDS); //向redis裡存入數據和設置緩存時間
stringRedisTemplate.opsForValue().get("test") //根據key獲取緩存中的val
stringRedisTemplate.getExpire("test") //根據key獲取過期時間
stringRedisTemplate.getExpire("test",TimeUnit.SECONDS) //根據key獲取過期時間並換算成指定單位
stringRedisTemplate.delete("test"); //根據key刪除緩存
stringRedisTemplate.hasKey("546545"); //檢查key是否存在,返回boolean值
stringRedisTemplate.expire("test",1000 , TimeUnit.MILLISECONDS); //設置過期時間
例子:設置 name 緩存 10 秒
redisTemplate.opsForValue().set("name","neo",10, TimeUnit.SECONDS);
redisTemplate.opsForValue().get("name")
結果:由於設置的是10秒失效,十秒之內查詢有結果,十秒之後返回為null
設置:redisTemplate.opsForValue().set("hello","Helloworld");
代碼:System.out.println(redisTemplate.opsForValue().get("hello",0,5));
結果:Hellow
代碼:System.out.println(redisTemplate.opsForValue().get("hello",0,-1));
結果:Helloworld
代碼:System.out.println(redisTemplate.opsForValue().get("hello",-3,-1));
結果:rld
redisTemplate.opsForValue().append("hello","Hello");
System.out.println(redisTemplate.opsForValue().get("hello"));
redisTemplate.opsForValue().append("hello","world");
System.out.println(redisTemplate.opsForValue().get("hello")); // 結果:Helloworld
redisTemplate.opsForValue().set("name","neo");
System.out.println(redisTemplate.opsForValue().getAndSet("name","Jerry"));
// 結果 neo
stringRedisTemplate.opsForValue().set("test", "100"); //向redis裡存入數據
stringRedisTemplate.boundValueOps("test").increment(-50); //val做-60操作
stringRedisTemplate.boundValueOps("test").increment(100); //val +100
stringRedisTemplate.opsForValue().get("test") //根據key獲取緩存中的val
private void cleanNewToday() {
long begin = System.currentTimeMillis();
redisTemplate.delete("news:today");
long end = System.currentTimeMillis();
logger.info("Schedule clean redis {} 耗時 {} 秒", "cleanNewFlash()", (end-begin) / 1000 );
}
redisTemplate.opsForValue().set("key","hello world");
System.out.println(redisTemplate.opsForValue().size("key"));
System.out.println(redisTemplate.opsForValue().setIfAbsent("name","neo")); // name 之前已經存在 false
System.out.println(redisTemplate.opsForValue().setIfAbsent("age","11")); // age 之前不存在 true
Map<String,String> maps = new HashMap<String, String>();
maps.put("multi1","multi1");
maps.put("multi2","multi2");
maps.put("multi3","multi3");
redisTemplate.opsForValue().multiSet(maps);
List<String> keys = new ArrayList<String>();
keys.add("multi1");
keys.add("multi2");
keys.add("multi3");
System.out.println(redisTemplate.opsForValue().multiGet(keys));
輸出結果
[multi1, multi2, multi3]
為多個鍵分別設置它們的值,如果存在則返回false,不存在返回true
Map<String,String> maps = new HashMap<String, String>();
maps.put("multi11","multi11");
maps.put("multi22","multi22");
maps.put("multi33","multi33");
Map<String,String> maps2 = new HashMap<String, String>();
maps2.put("multi1","multi1");
maps2.put("multi2","multi2");
maps2.put("multi3","multi3");
System.out.println(redisTemplate.opsForValue().multiSetIfAbsent(maps)); // 返回 true
System.out.println(redisTemplate.opsForValue().multiSetIfAbsent(maps2)); // 返回 false
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush("books", "Linux");
list.rightPush("books", "Java");
System.out.println(list.range("books", 0, 1));
System.out.println(redisTemplate.opsForList().size("list"));
String[] stringarrays = new String[]{"1","2","3"};
redisTemplate.opsForList().rightPushAll("listarrayright",stringarrays);
System.out.println(redisTemplate.opsForList().range("listarrayright",0,-1));
List<Object> strings = new ArrayList<Object>();
strings.add("1");
strings.add("2");
strings.add("3");
redisTemplate.opsForList().rightPushAll("listcollectionright", strings);
System.out.println(redisTemplate.opsForList().range("listcollectionright",0,-1));
System.out.println("========== KEY 不存在===========");
System.out.println(redisTemplate.opsForList().rightPushIfPresent("rightPushIfPresent","aa"));
System.out.println(redisTemplate.opsForList().rightPushIfPresent("rightPushIfPresent","bb"));
System.out.println("========== KEY 已經存在===========");
System.out.println(redisTemplate.opsForList().rightPushIfPresent("rightPushIfPresent","aa"));
System.out.println(redisTemplate.opsForList().rightPushIfPresent("rightPushIfPresent","bb"));
redisTemplate.opsForList().leftPush("list","java");
redisTemplate.opsForList().leftPush("list","python");
redisTemplate.opsForList().leftPush("list","c++");
批量把一個數組插入到列表中
String[] stringarrays = new String[]{"1","2","3"};
redisTemplate.opsForList().leftPushAll("listarray",stringarrays);
批量把一個集合插入到列表中
使用:List<Object> strings = new ArrayList<Object>();
strings.add("1");
strings.add("2");
strings.add("3");
redisTemplate.opsForList().leftPushAll("listcollection", strings);
System.out.println(redisTemplate.opsForList().range("listcollection",0,-1));
結果:[3, 2, 1]
Redis的Set是無序集合並且集合成員是唯一的,這就意味着集合中不能出現重複的數據。
stringRedisTemplate.opsForSet().add("test", "1","2","3"); //向指定key中存放set集合
stringRedisTemplate.opsForSet().isMember("test", "1") //根據key查看集合中是否存在指定數據
stringRedisTemplate.opsForSet().members("test"); //根據key獲取set集合
//添加 一個 set 集合
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add("Member", "neo");
set.add("Member", "36");
set.add("Member", "178cm");
//輸出 set 集合
System.out.println(set.members("Member"));
package cn.netkiller.api.restful;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import common.pojo.ResponseRestful;
@RestController
@RequestMapping("/news")
public class NewsRestController {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@RequestMapping(value = "/flash/{count}")
public ResponseRestful flash(@PathVariable("count") long count) {
if(count == 0L) {
count=10L;
}
Set<String> news = this.redisTemplate.opsForZSet().reverseRange("news:flash", 0, count);
if (news == null) {
return new ResponseRestful(false, 10, "沒有查詢到結果", news);
}
return new ResponseRestful(true, 0, "返回數據: " + news.size() + " 條", news);
}
public void addRecentUser(long userId, String name) {
String key = RedisKeyGenerator.genRecentBrowsingPositionsKey(String.valueOf(userId));
// 獲取已緩存的最近瀏覽的職位
ZSetOperations<String, String> zSetOperations = redisTempalte.opsForZSet();
//zset內部是按分數來排序的,這裡用當前時間做分數
zSetOperations.add(key, name, System.currentTimeMillis());
zSetOperations.removeRange(key, 0, -6);
}
}
System.out.println("Random member: " + redisTemplate.opsForSet().randomMember("setTest"));
System.out.println("Random member: " + redisTemplate.opsForSet().randomMembers("setTest",5));
// 結果 Random member: [ccc, ddd, ddd, ddd, aaa]
System.out.println("Random members: " + redisTemplate.opsForSet().distinctRandomMembers("setTest",5));
//結果 Random members: [aaa, bbb, ddd, ccc]
redisTemplate.opsForSet().move("key1","aaa","key2");
System.out.println(redisTemplate.opsForSet().members("key1"));
System.out.println(redisTemplate.opsForSet().members("key2"));
String[] arrays = new String[]{"Java","PHP"};
System.out.println(redisTemplate.opsForSet().remove("setTest",arrays));
System.out.println(redisTemplate.opsForSet().members("key"));
System.out.println(redisTemplate.opsForSet().members("otherKey"));
System.out.println(redisTemplate.opsForSet().intersect("key","otherKey"));
List<String> library2 = new ArrayList<String>();
library2.add("Linux");
library2.add("FreeBSD");
System.out.println(redisTemplate.opsForSet().intersect("library1",library2));
System.out.println(redisTemplate.opsForSet().intersectAndStore("key","otherKey","destKey"));
List<String> otherKey = new ArrayList<String>();
otherKey.add("《Netkiller Java 手札》");
otherKey.add("《Netkiller Spring Cloud 手札》");
System.out.println(redisTemplate.opsForSet().intersectAndStore("key",otherKey,"destKey"));
System.out.println(redisTemplate.opsForSet().union("setTest1","setTest2"));
List<String> otherKey = new ArrayList<String>();
otherKey.add("《Netkiller Java 手札》");
otherKey.add("《Netkiller Spring Cloud 手札》");
System.out.println(redisTemplate.opsForSet().union("setTest",otherKey));
System.out.println(redisTemplate.opsForSet().unionAndStore("key","otherKey","destKey"));
System.out.println(redisTemplate.opsForSet().unionAndStore("key",otherKey,"destKey"));
System.out.println(redisTemplate.opsForSet().difference("key","otherKey"));
List<String> otherKey = new ArrayList<String>();
otherKey.add("setTest2");
otherKey.add("setTest3");
System.out.println(redisTemplate.opsForSet().difference("key",otherKey));
System.out.println(redisTemplate.opsForSet().differenceAndStore("key","otherKey","destKey"));
//添加有序的 set 集合
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add("zMember", "neo", 0);
zset.add("zMember", "36", 1);
zset.add("zMember", "178cm", 2);
//輸出有序 set 集合
System.out.println(zset.rangeByScore("zMember", 0, 2));
redisTemplate.opsForHash().put("redisHash","name","neo");
redisTemplate.opsForHash().put("redisHash","age",30);
redisTemplate.opsForHash().put("redisHash","nickname","netkiller");
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", "neo");
map.put("age", "36");
hash.putAll("member", map);
System.out.println(hash.entries("member"));
System.out.println(redisTemplate.opsForHash().get("redisHash","age"));
刪除指定的哈希 hashKeys
System.out.println(redisTemplate.opsForHash().delete("redisHash","name"));
確定哈希hashKey是否存在
System.out.println(redisTemplate.opsForHash().hasKey("redisHash","age"));
List<Object> keys = new ArrayList<Object>();
keys.add("name");
keys.add("age");
System.out.println(redisTemplate.opsForHash().multiGet("redisHash",keys))
System.out.println(redisTemplate.opsForHash().putIfAbsent("redisHash","age",30));
Spring Redis 中設置過期時間方法如下
設置 key
redisTemplate.opsForValue().setIfAbsent("key", "value");
設置過期時間
redisTemplate.expire("key", 30000, TimeUnit.MILLISECONDS);
釋放 key
redisTemplate.delete("key");
這樣存在一個問題,當程序運行一半被強行終止,可能導致setIfAbsent運行完成,但是expire未被執行,這樣 key 便永遠不會釋放。解決方案如下,使用RedisCallback執行原生 Redis 命令。
String result = redisTemplate.execute(new RedisCallback<String>() {
@Override
public String doInRedis(RedisConnection connection) throws DataAccessException {
JedisCommands commands = (JedisCommands) connection.getNativeConnection();
return commands.set(key, value, "NX", "PX", expire);
}
});
setBit Boolean setBit(K key, long offset, boolean value); offset 二進制位置(從左向右數) value 位 ture 表示 0,false 表示 1
// 'a' 的ASCII碼是 97 轉換為二進制是:01100001
// 'b' 的ASCII碼是 98 轉換為二進制是:01100010
// 'c' 的ASCII碼是 99 轉換為二進制是:01100011
redisTemplate.opsForValue().set("bitTest","a");
redisTemplate.opsForValue().setBit("bitTest",7, false); // 01100011
redisTemplate.opsForValue().setBit("bitTest",8, true); // 01100010
System.out.println(redisTemplate.opsForValue().get("bitTest"));
redisTemplate.opsForValue().setBit("bitTest",8, false); // 01100011
System.out.println(redisTemplate.opsForValue().get("bitTest"));
getBit Boolean getBit(K key, long offset); 獲取鍵對應值的ascii碼的在offset處位值
System.out.println(redisTemplate.opsForValue().getBit("bitTest",7));
package cn.netkiller.wallet.redis;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonRedisTemplate extends RedisTemplate<String, Object> {
public JsonRedisTemplate(RedisConnectionFactory connectionFactory, ObjectMapper objectMapper, Class<?> valueType) {
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
super.setKeySerializer(stringSerializer);
super.setHashKeySerializer(stringSerializer);
super.setHashValueSerializer(stringSerializer);
Jackson2JsonRedisSerializer<?> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(valueType);
jsonRedisSerializer.setObjectMapper(objectMapper);
super.setValueSerializer(jsonRedisSerializer);
super.setConnectionFactory(connectionFactory);
super.afterPropertiesSet();
}
}
package cn.netkiller.wallet.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.netkiller.wallet.redis.JsonRedisTemplate;
import cn.netkiller.wallet.redis.RedisMessageSubscriber;
@Configuration
public class RedisConfig {
public RedisConfig() {
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
StringRedisTemplate redisTemplate = new StringRedisTemplate();
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
@Bean
public MessageListenerAdapter messageListener() {
return new MessageListenerAdapter(new RedisMessageSubscriber());
}
@Bean
public ChannelTopic topic() {
return new ChannelTopic("demo");
}
@Bean
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter messageListener) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(messageListener(), topic());
container.addMessageListener(messageListener(), new ChannelTopic("test"));
return container;
}
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
@Bean
public JsonRedisTemplate jsonRedisTemplate(RedisConnectionFactory connectionFactory, ObjectMapper objectMapper) {
return new JsonRedisTemplate(connectionFactory, objectMapper, Object.class);
}
}
package cn.netkiller.wallet.restful;
import java.io.IOException;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import cn.netkiller.wallet.pojo.RestfulResponse;
import cn.netkiller.wallet.redis.JsonRedisTemplate;
import cn.netkiller.wallet.redis.RedisMessagePublisher;
@RestController
public class TestRestController {
private static final Logger logger = LoggerFactory.getLogger(TestRestController.class);
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private JsonRedisTemplate jsonRedisTemplate;
public TestRestController() {
}
@GetMapping("/version")
public String version() throws IOException {
Web3ClientVersion web3ClientVersion = web3j.web3ClientVersion().send();
String clientVersion = web3ClientVersion.getWeb3ClientVersion();
logger.info(clientVersion);
return clientVersion;
}
@GetMapping("/pub/demo")
public String pub() {
RedisMessagePublisher publisher = new RedisMessagePublisher(stringRedisTemplate, new ChannelTopic("demo"));
String message = "Message " + UUID.randomUUID();
publisher.publish(message);
return message;
}
@GetMapping("/pub/test")
public String pub(@RequestParam String message) {
RedisMessagePublisher publisher = new RedisMessagePublisher(stringRedisTemplate, new ChannelTopic("test"));
publisher.publish(message);
return message;
}
@GetMapping("/pub/json")
public RestfulResponse pubJson() {
RestfulResponse restfulResponse = new RestfulResponse(true, 0, null, null);
jsonRedisTemplate.opsForValue().set("test", restfulResponse);
jsonRedisTemplate.convertAndSend("test", restfulResponse);
return restfulResponse;
}
}
package api.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
@Configuration
@EnableRedisRepositories
public class CachingConfigurer {
}
package api.domain;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Reference;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.index.Indexed;
@RedisHash("persons")
public class Person {
public enum Gender {
FEMALE, MALE
}
@Id
private String id;
@Indexed
private String firstname;
@Indexed
private String lastname;
private Gender gender;
private Address address;
@Reference
private List<Person> children;
public Person() {
// TODO Auto-generated constructor stub
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<Person> getChildren() {
return children;
}
public void setChildren(List<Person> children) {
this.children = children;
}
@Override
public String toString() {
return "Person [id=" + id + ", firstname=" + firstname + ", lastname=" + lastname + ", gender=" + gender + ", address=" + address + ", children=" + children + "]";
}
}
package api.domain;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.index.GeoIndexed;
import org.springframework.data.redis.core.index.Indexed;
public class Address {
private @Indexed String city;
private String country;
private @GeoIndexed Point location;
public Address(String city, String country, Point location) {
this.city = city;
this.country = country;
this.location = location;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Point getLocation() {
return location;
}
public void setLocation(Point location) {
this.location = location;
}
}
package api.repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.geo.Circle;
import org.springframework.data.repository.CrudRepository;
import api.domain.Person;
public interface PersonRepository extends CrudRepository<Person, String> {
List<Person> findByLastname(String lastname);
Page<Person> findPersonByLastname(String lastname, Pageable page);
List<Person> findByFirstnameAndLastname(String firstname, String lastname);
List<Person> findByFirstnameOrLastname(String firstname, String lastname);
List<Person> findByAddress_City(String city);
List<Person> findByAddress_LocationWithin(Circle circle);
}
package api.restful;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import api.domain.Person;
import api.domain.Address;
import api.repository.PersonRepository;
@RestController
@RequestMapping("/test")
public class TestRestController {
private static final Logger logger = LoggerFactory.getLogger(TestRestController.class);
@Autowired
private PersonRepository personRepository;
public TestRestController() {
}
@GetMapping("/redis")
public Person redis() {
Person children = new Person();
children.setFirstname("Lisa");
children.setLastname("Chen");
children.setGender(Person.Gender.FEMALE);
Person person = new Person();
person.setFirstname("Neo");
person.setLastname("Chen");
person.setGender(Person.Gender.MALE);
// List<Person> childrens = new ArrayList<Person>();
person.setChildren(Arrays.asList(children));
Point point = new Point(Double.valueOf("28.352734"), Double.valueOf("32.807382"));
Address address = new Address("Shenzhen", "China", point);
person.setAddress(address);
personRepository.save(person);
return person;
}
}