知乎專欄 | 多維度架構 | | | 微信號 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; } }