From 0b568ba547399e06fcf6fff3af498583112282be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=95=E6=9C=89=E7=81=B5=E7=8A=80?= <475660@qq.com> Date: Tue, 18 Sep 2018 09:50:45 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 26 + README.md | 603 ++++++++++++++++ bin/main/application.properties | 101 +++ bin/main/cassandra.properties | 3 + bin/main/couchdb.xml | 10 + bin/main/ehcache.xml | 55 ++ bin/main/log4j2.xml | 61 ++ .../SpringBoot2NoSqlApplication.class | Bin 0 -> 1046 bytes .../config/CassandraConfig.class | Bin 0 -> 2706 bytes .../config/RedissonConfig.class | Bin 0 -> 7406 bytes .../Cassandra/CassandraController.class | Bin 0 -> 3193 bytes .../Ehcache/EhcacheDataController.class | Bin 0 -> 2424 bytes .../ElasticSearch/ESDataController.class | Bin 0 -> 10592 bytes .../ElasticSearch/ESSearchController.class | Bin 0 -> 3798 bytes .../Mongo/MongoDataController.class | Bin 0 -> 5410 bytes .../Redis/RedisDataController.class | Bin 0 -> 1647 bytes .../Redis/RedissonController$1.class | Bin 0 -> 1274 bytes .../Redis/RedissonController$2.class | Bin 0 -> 1274 bytes .../Redis/RedissonController$3.class | Bin 0 -> 1274 bytes .../Redis/RedissonController$4.class | Bin 0 -> 1274 bytes .../controller/Redis/RedissonController.class | Bin 0 -> 11058 bytes .../controller/Solr/SolrController.class | Bin 0 -> 2480 bytes .../CreateIndexFailedException.class | Bin 0 -> 670 bytes .../exception/GetMappingFailedException.class | Bin 0 -> 677 bytes .../IndicesExistsFailedException.class | Bin 0 -> 669 bytes .../exception/PutMappingFailedException.class | Bin 0 -> 674 bytes .../model/Cassandra/Customer.class | Bin 0 -> 1873 bytes .../model/ElasticSearch/Product.class | Bin 0 -> 1637 bytes .../model/Mongo/Department.class | Bin 0 -> 983 bytes .../model/Mongo/Location.class | Bin 0 -> 832 bytes .../SpringBoot2NoSQL/model/Mongo/Person.class | Bin 0 -> 2341 bytes .../SpringBoot2NoSQL/model/Redis/User.class | Bin 0 -> 1284 bytes .../model/Solr/Customer.class | Bin 0 -> 1772 bytes bin/main/xy/SpringBoot2NoSQL/model/User.class | Bin 0 -> 1530 bytes .../Cassandra/CustomerRepository.class | Bin 0 -> 1076 bytes .../SampleProductRepository.class | Bin 0 -> 1060 bytes .../Mongo/DepartmentRepository.class | Bin 0 -> 479 bytes .../repository/Mongo/PersonRepository.class | Bin 0 -> 992 bytes .../repository/Redis/ObjectRepository.class | Bin 0 -> 1542 bytes .../Redis/StringStringRepository.class | Bin 0 -> 1677 bytes .../repository/Redis/UserRepository.class | Bin 0 -> 427 bytes .../Solr/SolrCustomerRepository.class | Bin 0 -> 549 bytes .../service/Ehcache/UserService.class | Bin 0 -> 2829 bytes .../SpringBoot2NoSQL/utils/ESSearchUtil.class | Bin 0 -> 6584 bytes .../utils/IElasticSearchMapping.class | Bin 0 -> 325 bytes .../SpringBoot2NoSQL/utils/RandomUtil.class | Bin 0 -> 2792 bytes .../SpringBoot2NoSQL/utils/RedissonUtil.class | Bin 0 -> 5406 bytes .../SpringBoot2NoSqlApplicationTests.class | Bin 0 -> 664 bytes build.gradle | 49 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54711 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 +++++ gradlew.bat | 84 +++ mvnw | 225 ++++++ mvnw.cmd | 143 ++++ myCache.ehcache/users.data | 0 myCache.ehcache/users.index | Bin 0 -> 4 bytes pom.xml | 117 ++++ settings.gradle | 1 + .../SpringBoot2NoSqlApplication.java | 17 + .../config/CassandraConfig.java | 45 ++ .../config/RedissonConfig.java | 263 +++++++ .../Cassandra/CassandraController.java | 76 ++ .../Couchbase/CouchbaseController.java | 53 ++ .../Ehcache/EhcacheDataController.java | 64 ++ .../ElasticSearch/ESDataController.java | 186 +++++ .../ElasticSearch/ESSearchController.java | 67 ++ .../controller/Mongo/MongoDataController.java | 110 +++ .../controller/Redis/RedisDataController.java | 34 + .../controller/Redis/RedissonController.java | 329 +++++++++ .../controller/Solr/SolrController.java | 51 ++ .../exception/CreateIndexFailedException.java | 7 + .../exception/GetMappingFailedException.java | 7 + .../IndicesExistsFailedException.java | 7 + .../exception/PutMappingFailedException.java | 7 + .../model/Cassandra/Customer.java | 76 ++ .../model/Couchbase/Customer.java | 55 ++ .../model/ElasticSearch/Product.java | 57 ++ .../model/Mongo/Department.java | 35 + .../model/Mongo/Location.java | 38 + .../SpringBoot2NoSQL/model/Mongo/Person.java | 69 ++ .../xy/SpringBoot2NoSQL/model/Redis/User.java | 49 ++ .../SpringBoot2NoSQL/model/Solr/Customer.java | 57 ++ .../java/xy/SpringBoot2NoSQL/model/User.java | 54 ++ .../Cassandra/CustomerRepository.java | 25 + .../CouchbaseCustomerRepository.java | 17 + .../SampleProductRepository.java | 15 + .../Mongo/DepartmentRepository.java | 13 + .../repository/Mongo/PersonRepository.java | 20 + .../repository/Redis/ObjectRepository.java | 27 + .../Redis/StringStringRepository.java | 25 + .../repository/Redis/UserRepository.java | 30 + .../Solr/SolrCustomerRepository.java | 10 + .../service/Ehcache/UserService.java | 49 ++ .../SpringBoot2NoSQL/utils/ESSearchUtil.java | 160 +++++ .../utils/IElasticSearchMapping.java | 14 + .../xy/SpringBoot2NoSQL/utils/RandomUtil.java | 120 ++++ .../utils/RedisCacheUtils.java | 649 ++++++++++++++++++ .../SpringBoot2NoSQL/utils/RedissonUtil.java | 157 +++++ src/main/resources/application.properties | 101 +++ src/main/resources/cassandra.properties | 3 + src/main/resources/couchdb.xml | 10 + src/main/resources/ehcache.xml | 55 ++ src/main/resources/log4j2.xml | 61 ++ .../SpringBoot2NoSqlApplicationTests.java | 16 + ...2\345\272\223\350\204\232\346\234\254.txt" | 15 + 106 files changed, 5061 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 bin/main/application.properties create mode 100644 bin/main/cassandra.properties create mode 100644 bin/main/couchdb.xml create mode 100644 bin/main/ehcache.xml create mode 100644 bin/main/log4j2.xml create mode 100644 bin/main/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplication.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/config/CassandraConfig.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/config/RedissonConfig.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Cassandra/CassandraController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Ehcache/EhcacheDataController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESDataController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESSearchController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Mongo/MongoDataController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedisDataController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$1.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$2.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$3.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$4.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/controller/Solr/SolrController.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/exception/CreateIndexFailedException.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/exception/GetMappingFailedException.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/exception/IndicesExistsFailedException.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/exception/PutMappingFailedException.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/Cassandra/Customer.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/ElasticSearch/Product.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/Mongo/Department.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/Mongo/Location.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/Mongo/Person.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/Redis/User.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/Solr/Customer.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/model/User.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/Cassandra/CustomerRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/ElasticSearch/SampleProductRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/Mongo/DepartmentRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/Mongo/PersonRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/Redis/ObjectRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/Redis/StringStringRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/Redis/UserRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/repository/Solr/SolrCustomerRepository.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/service/Ehcache/UserService.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/utils/ESSearchUtil.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/utils/IElasticSearchMapping.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/utils/RandomUtil.class create mode 100644 bin/main/xy/SpringBoot2NoSQL/utils/RedissonUtil.class create mode 100644 bin/test/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplicationTests.class create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 mvnw create mode 100644 mvnw.cmd create mode 100644 myCache.ehcache/users.data create mode 100644 myCache.ehcache/users.index create mode 100644 pom.xml create mode 100644 settings.gradle create mode 100644 src/main/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplication.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/config/CassandraConfig.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/config/RedissonConfig.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/Cassandra/CassandraController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/Couchbase/CouchbaseController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/Ehcache/EhcacheDataController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESDataController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESSearchController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/Mongo/MongoDataController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedisDataController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedissonController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/controller/Solr/SolrController.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/exception/CreateIndexFailedException.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/exception/GetMappingFailedException.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/exception/IndicesExistsFailedException.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/exception/PutMappingFailedException.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/Cassandra/Customer.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/Couchbase/Customer.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/ElasticSearch/Product.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Department.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Location.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Person.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/Redis/User.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/Solr/Customer.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/model/User.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Cassandra/CustomerRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Couchbase/CouchbaseCustomerRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/ElasticSearch/SampleProductRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/DepartmentRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/PersonRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Redis/ObjectRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Redis/StringStringRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Redis/UserRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/repository/Solr/SolrCustomerRepository.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/service/Ehcache/UserService.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/utils/ESSearchUtil.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/utils/IElasticSearchMapping.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/utils/RandomUtil.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/utils/RedisCacheUtils.java create mode 100644 src/main/java/xy/SpringBoot2NoSQL/utils/RedissonUtil.java create mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/cassandra.properties create mode 100644 src/main/resources/couchdb.xml create mode 100644 src/main/resources/ehcache.xml create mode 100644 src/main/resources/log4j2.xml create mode 100644 src/test/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplicationTests.java create mode 100644 "\350\204\232\346\234\254/Cassandra/\345\273\272\345\272\223\350\204\232\346\234\254.txt" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9243c63 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..6df6278 --- /dev/null +++ b/README.md @@ -0,0 +1,603 @@ +SpringBoot2.0 + NoSQL使用教程, + +## 项目介绍 +All in one一站式SpringBoot for NoSQL开发教程手册。 + +含SpringBoot2.0 + Redis、Ehcache、MongoDB、ElasticSearch、Cassandra、CouchBase、Solr、Neo4j、Gemfire共10种常用NoSQL数据库操作、工具类、演示代码。 + + +重点介绍Redis、MongoDB、ElasticSeach、Cassandra四种数据库,因为它们是各自领域的领先者(分别是KV缓存、文档数据库、搜索数据库、列数据库)。 + +## Redis for SpringBoot 开发介绍 + +内容: + +- SpringBoot配置、控制器、Repository Crud; +- string、list、set、zset、hash操作; +- 同步、异步操作; +- 管道批处理; +- 分布式对象操作:对象桶Object Bucket、二进制流Binary Stream、原子类型、发布订阅、HyperLogLog分布式基数估计算法等;分布式锁; +- 分布式集合操作:哈希、多值哈希、集合、排序集合、队列(双端、阻塞、有界、公平、延迟、优先) +- 性能测试、内存监控 +- 注意:在启动SpringBoot前要先启动Redis服务。 + +##### application.properties配置: + + # Redis + # Redis数据库索引(默认为0) + spring.redis.database=0 + spring.redis.host=127.0.0.1 + spring.redis.port=6379 + #spring.redis.password=123 + # 连接池最大连接数(使用负值表示没有限制) + spring.redis.pool.max-active=60 + # 连接池中的最大空闲连接 + spring.redis.pool.max-idle=30 + # 连接池最大阻塞等待时间(使用负值表示没有限制) + spring.redis.pool.max-wait=-1 + # 连接池中的最小空闲连接 + spring.redis.pool.min-idle=0 + + #redisson配置 + #redis链接地址 + spring.redisson.address=redis://127.0.0.1:6379 + ... + +因为我们还使用了Redisson作为客户端,还需RedissonConfig + + @ConfigurationProperties(prefix = "spring.redisson") + @Configuration + public class RedissonConfig{ + ... + +Spring官方默认支持Lettuce、Jedis客户端,Redis官方的推荐客户端是Redisson,因为Redison提供了诸多分布式的集合工具(这对单机到分布式的扩展非常有益)以及优异的性能,所以非常值得使用Redisson客户端。Spring Boot是一个平台,不必受限于它。我们在代码中配置Redisson连接的模式是单机模式,如想配置集群模式和哨兵模式,请参考官方wiki: https://github.com/redisson/redisson/wiki/ + +##### 模型Model: +见xy.SpringBoot2NoSQL.model.Redis.User + + public class User implements Serializable{ + + private String login; + private String fullName; + ... + + +这完全是一个简单POJO java类.使用登录名(login)作为关键字段。 + +##### 数据层repository: +xy.SpringBoot2NoSQL.repository.Redis.**ObjectRepository** + +以及 + +xy.SpringBoot2NoSQL.repository.Redis.**UserRepository** + +分别是Object类型转换操作的数据类,和泛型User数据操作. + +两者都是扩展自org.springframework.data.redis.core.**ValueOperations** +CRUD操作是RedisTemplate中提供了几个常用的单例对象,全面满足Redis的5大数据结构外,还提供了如地理位置、计数估计HyperLogLog操作。如: + + private @Nullable ValueOperations valueOps;//KV操作 + private @Nullable ListOperations listOps;//列表 + private @Nullable SetOperations setOps;//无排序集合 + private @Nullable ZSetOperations zSetOps;//计分排序集合 + private @Nullable GeoOperations geoOps;//用于地理位置 + private @Nullable HyperLogLogOperations hllOps;//基数估值 + ... + @Override + public ValueOperations opsForValue() { + + if (valueOps == null) { + valueOps = new DefaultValueOperations<>(this); + } + return valueOps; + } + ... + @Override + public ZSetOperations opsForZSet() { + + if (zSetOps == null) { + zSetOps = new DefaultZSetOperations<>(this); + } + return zSetOps; + } + ... + +在RedisTemplate中,已经提供了一个工厂方法:opsForValue()。这个方法会返回一个默认的操作类。另外,我们可以直接通过注解@Resource(name = “redisTemplate”)来进行注入。 + + +##### 控制器controller: +见xy.SpringBoot2NoSQL.controller.Redis.**RedisDataController** + + @RestController + @RequestMapping("/redis") + public class RedisDataController { + + @Autowired + ObjectRepository objRepository; + @Autowired + StringStringRepository stringStringRepository; + + @RequestMapping("/add/{name}") + public String getRecognition(@PathVariable("name") String name){ + User user = new User(name,name); + objRepository.save(user); + + return "add success."; + } + + @RequestMapping("/user/{name}") + public User getUser(@PathVariable("name") String name){ + return (User)objRepository.get(name); + + } + } + +具体代码不再赘述。 +另外,提供了Redisson的控制器: + +xy.SpringBoot2NoSQL.controller.Redis.**RedissonController** + +RedissonController演示了同步\异步操作、分布式集合(哈希、多值哈希、集合、排序集合、队列)、本地缓存、对象桶Object Bucket、二进制流Binary Stream、原子类型、发布订阅、HyperLogLog分布式基数估计算法、累加器、元素淘汰、事件监听、分布式锁、异步批量操作等。 + +比如本地缓存操作: + + @RequestMapping("/getLocalCachedMap/{name}/{key}") + public String getLocalCachedMap(@PathVariable("name") String name,@PathVariable("key") String key){ + + LocalCachedMapOptions options = LocalCachedMapOptions.defaults() + .evictionPolicy(LocalCachedMapOptions.EvictionPolicy.LFU) + .cacheSize(100) + .syncStrategy(LocalCachedMapOptions.SyncStrategy.UPDATE) //同步缓存 + .timeToLive(10, TimeUnit.SECONDS) + .maxIdle(10, TimeUnit.SECONDS); + + RLocalCachedMap map = redisson.getLocalCachedMap(name,options); + map.put(key, "测试值"); + String result = (String)map.get(key); + return result; + } + +##### 运行效果 + +##### 更多详细介绍 + +正在写作... + +## Ehcache for SpringBoot 开发介绍 + +##### application.properties配置: + + # ehcache + spring.cache.type=ehcache + spring.cache.ehcache.config=classpath:ehcache.xml + +ehcache.xml + + + + + + + + + + + + +##### 模型Model: +见xy.SpringBoot2NoSQL.model.User +这完全是一个简单POJO java类.使用登录名(login)作为关键字段。 + + public class User implements Serializable{ + + private String login; + private String fullName; + ... + + +##### 数据服务层Service: +见xy.SpringBoot2NoSQL.service.Ehcache.UserService + +演示简单直接,并没有repository。 getUser() 方法演示了缓存根据配置存在于JVM堆、堆外、磁盘持久化的各种情况。 + +##### 控制器controller: +见xy.SpringBoot2NoSQL.controller.Ehcache.EhcacheDataController + + + + +## MongoDB for SpringBoot 开发介绍 +##### application.properties配置: + + # MONGODB + spring.data.mongodb.host=127.0.0.1 + spring.data.mongodb.port=27017 + spring.data.mongodb.database=test + +##### 模型Model: +见xy.SpringBoot2NoSQL.model.Mongo.Person + + @Document + public class Person { + @Id + private String id; + private String name; + private Integer age; + @Field("locs") + private Collection locations = new LinkedHashSet(); + @DBRef + Department department; + +@Document是org.springframework.data.mongodb.core.mapping.Document的注解。 + +@Id是定义主键。 + +@Field("locs")是定义文档内部对象,在这里是Collection + +@DBRef是链接到外表,Department是链接的表,有点像关系数据库的Inner Join,以Department的id关联。 + + +##### 数据层repository: +见xy.SpringBoot2NoSQL.repository.Mongo.PersonRepository + +继承MongoRepository接口,其中T为仓库保存的bean类,TD为该bean的唯一标识的类型,一般为ObjectId。之后在service中注入该接口就可以使用,无需实现里面的方法,spring会根据定义的规则自动生成。 + + + import org.springframework.data.domain.Page; + import org.springframework.data.domain.Pageable; + import org.springframework.data.mongodb.repository.MongoRepository; + import org.springframework.data.mongodb.repository.Query; + import xy.SpringBoot2NoSQL.model.Mongo.Person; + import java.util.List; + + public interface PersonRepository extends MongoRepository { + + Person findByName(String name); + + @Query("{'age': { '$lt' : ?0}}") + List withQueryFindByAge(Integer age); + + Page findAll(Pageable pageable); + + } + +自定义查询方法,还可以使用格式为“findBy+字段名+方法后缀”,方法传进的参数即字段的值,此外还支持分页查询,通过传进一个Pageable对象,返回Page集合。 +如查询大于age的数据: + + public Page findByAgeGreaterThan(int age,Pageable page) ; + +也可以使用mongodb原生查询语句,使用@Query注解,如: + + @Query("{'age': { '$lt' : ?0}}") + List withQueryFindByAge(Integer age); + + //大于 + {"age" : {"$gt" : age}} + //小于 + {"age" : {"$lt" : age}} + //之间 + findByAgeBetween(int from, int to) + {"age" : {"$gt" : from, "$lt" : to}} + //非空 + findByFirstnameNotNull() + {"age" : {"$ne" : null}} + //模糊查询 + findByFirstnameLike(String name) + {"age" : age} ( age as regex) + //非 + findByFirstnameNot(String name) + {"age" : {"$ne" : name}} + +##### 控制器controller: +见xy.SpringBoot2NoSQL.controller.Mongo.MongoDataController + + @RestController + @RequestMapping("/mongo") + public class MongoDataController { + + @Autowired + PersonRepository personRepository; + @Autowired + DepartmentRepository departmentRepository; + + @RequestMapping("/persons/{name}") + public Person getPerson(@PathVariable("name") String name){ + return personRepository.findByName(name); + } + + @GetMapping("findAll") + public List getUserList() { + List userInfoList = personRepository.findAll(); + return userInfoList; + } + + @GetMapping("insert") + public Person insert(Long id, String username, String password) { + Person user = new Person("test2",22); + return personRepository.insert(user); + } + + @DeleteMapping("/colleagues/{name}") + public ResponseEntity deleteColleague(@PathVariable String name){ + Person person = personRepository.findByName(name); + if(person!=null) { + personRepository.delete(person); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + ... +具体CRUD不再赘述。 + + +## ElasticSearch for SpringBoot 开发介绍 + +##### application.properties配置: + + # elasticsearch + #节点名字,默认elasticsearch + spring.data.elasticsearch.cluster-name=elasticsearch + # 节点地址,多个节点用逗号隔开 + spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300 + #spring.data.elasticsearch.local=false + spring.data.elasticsearch.repositories.enable=true + +##### 模型Model: +见xy.SpringBoot2NoSQL.model.ElasticSearch.Product + + @Document(indexName = "book",type = "book" , shards = 1, replicas = 0, refreshInterval = "-1") + public class Product { + @Id + private String id; + private String name; + ... +Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。 + +在Elasticsearch中存储数据的行为就叫做索引(indexing),不过在索引之前,我们需要明确数据应该存储在哪里。 +在Elasticsearch中,文档归属于一种类型(type),这里是Classname(即book),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统关系型数据库: + + Relational DB -> Databases -> Tables -> Rows -> Columns + Elasticsearch -> Indices -> Types -> Documents -> Fields + +Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列,比如name、age...)。文档中的所有字段都会被索引(拥有一个倒排索引),只有这样他们才是可被搜索的。注意:传统数据库为特定列增加一个索引,一般使用B-Tree索引,Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构。 + + +##### 数据层repository: +见xy.SpringBoot2NoSQL.repository.ElasticSearch.SampleProductRepository + + public interface SampleProductRepository extends ElasticsearchRepository { + List findByName(String name); + List findByDescription(String description); + List findByName(String name, Pageable pageable); + List findByNameAndId(String name, String id); + } + +通过继承ElasticsearchRepository来完成基本的CRUD及分页操作的,和普通的JPA没有什么区别。ElasticsearchRepository继承了ElasticsearchCrudRepository extends PagingAndSortingRepository。 + +另外还可以使用ElasticSearchTemplate,ElasticSearchTemplate更多是对ESRepository的补充,里面提供了一些更底层的方法,主要是一些查询相关的,同样是构建各种SearchQuery条件。比如我们经常需要往ElasticSearch中插入大量的测试数据来完成测试搜索,一条一条插肯定是不行的,ES提供了批量插入数据的功能——bulk。 +JPA的save方法也可以save(List)批量插值,但适用于小数据量,要完成超大数据的插入就要用ES自带的bulk了,可以迅速插入百万级的数据。 +在ElasticSearchTemplate里也提供了对应的方法。 + +##### 控制器controller: +用于CRUD操作: + +xy.SpringBoot2NoSQL.controller.ElasticSearch.ESDataController + +用于查询操作: + +xy.SpringBoot2NoSQL.controller.ElasticSearch.ESSearchController + +其中matchQuery、fuzzyQuery、termsQuery等查询的区别可见: + + + @GetMapping("searchProduct/{key}/{value}/{searchtype}") + public Page searchProduct(@PathVariable String key,@PathVariable String value, @PathVariable String searchtype) { + Page products = null; + + if (searchtype.equals("matchQuery")) { + products = sampleProductRepository.search(ESSearchUtil.matchQuery(key, value), PageRequest.of(0, 5)); + } + + if (searchtype.equals("matchPhraseQuery")) { + products = sampleProductRepository.search(ESSearchUtil.matchPhraseQuery(key, value), PageRequest.of(0, 5)); + } + + if (searchtype.equals("fuzzyQuery")) { + products = sampleProductRepository.search(ESSearchUtil.fuzzyQuery(key, value), PageRequest.of(0, 5)); + } + + if (searchtype.equals("termsQuery")) { + products = sampleProductRepository.search(ESSearchUtil.termsQuery(key, value), PageRequest.of(0, 5)); + } + + return products; + } + +组合查询: + + public QueryBuilder getBoolQuery() { + + return QueryBuilders.boolQuery() + .must(QueryBuilders.matchPhraseQuery("name", "测试产品1")) + //.mustNot(QueryBuilders.termQuery("enabled", true)); + .must(QueryBuilders.matchPhraseQuery("enabled", true)); + } + + +## Cassandra for SpringBoot 开发介绍 +##### 内容 +- SpringBoot配置、控制器、Repository Crud; +- 使用前需要先建表,建表的脚本见“脚本”》“Cassandra”》“建库脚本.txt” +- 注意:如果是3.9版本的Win64的DataStax-DDC版本安装后,是无法启动服务的,需要修改配置文件,配置cdc_raw_directory类似如下: +cdc_raw_directory: "你的cdcraw目录" +,如果是2.X版不存在这个问题。 +- 注意:在启动SpringBoot前必须先启动Cassandra服务。 + +##### 配置: + +cassandra.properties + + #cassandra.properties + cassandra.contactpoints=127.0.0.1 + cassandra.port=9042 + cassandra.keyspace=mydb + +CassandraConfig类 + + @Configuration + @PropertySource(value = { "classpath:cassandra.properties" }) + @EnableCassandraRepositories(basePackages = "xy.SpringBoot2NoSQL.repository.Cassandra") + public class CassandraConfig extends AbstractCassandraConfiguration { + @Autowired + private Environment environment; + + @Override + protected String getKeyspaceName() { + return environment.getProperty("cassandra.keyspace"); + } + + @Override + @Bean + public CassandraClusterFactoryBean cluster() { + ... + } + + @Override + @Bean + public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { + ... + } + + } + +##### 模型Model: + + @Table + public class Customer { + + @PrimaryKey + private String id; + private String firstname; + ... + get、set + ... + +@Table定义了一个持久化的 Cassandra表,@PrimaryKey指定了主键字段,PrimaryKey是Cassandra中用于获取一行数据的key依据。 +可以把Cassandra的数据结构理解为Map> + +主要语句是: + + CREATE TABLE customer( + id text PRIMARY KEY,... +是不是有点像关系数据库? +如果想设置自增的key,可以用SERIAL替代text + +##### 数据层repository: + + public interface CustomerRepository extends CassandraRepository { + + @Query(value="SELECT * FROM customer WHERE firstname=?0") + public List findByFirstname(String firstname); + + @Query("SELECT * FROM customer WHERE age > ?0") + public List findCustomerHasAgeGreaterThan(int age); + + @AllowFiltering + public List findByLastname(String lastname); + + @AllowFiltering + public List findByAgeGreaterThan(int age); + } +和CrudRepository的使用和扩展一样,增删改查一应俱全了,不再赘述。 +CassandraRepository继承于org.springframework.data.repository的CrudRepository +其中ID是primary key的类型,支持单一的key,如果是复合主键(compound primary key),则需要使用{@link MapId}手动定义键值使用。 +@AllowFiltering用于扩展查询,他的作用是不使用@Query注解,而直接使用字段名来查询,还支持大于、小于等操作,但@Query还是来的更直观一些。 + +##### 控制器controller: + + @RestController + @RequestMapping("/cassandra") + public class CassandraController { + + Logger logger = LogManager.getLogger(getClass()); + + @Autowired + CustomerRepository customerRepository; + + @RequestMapping("/add") + public String add(){ + customerRepository.deleteAll(); + Customer cust_1 = new Customer("Test1", "Test1", "Test1", 20); + Customer cust_2 = new Customer("Test2", "Test2", "Test2", 25); + customerRepository.save(cust_1); + customerRepository.save(cust_2); + + return "ok"; + }... + +增删改查操作不再赘述。 + +##### 运行效果 + +##### 更多详细介绍 + +正在写作... + +## CouchBase for SpringBoot 开发介绍 + + +##### application.properties配置: + + #Couchbase + spring.couchbase.bootstrap-hosts=127.0.0.1 + spring.couchbase.bucket.name=mydb + spring.couchbase.bucket.password=123456 + spring.data.couchbase.auto-index=true +##### 模型Model: +见xy.SpringBoot2NoSQL.model.Couchbase.Customer +##### 数据层repository: +见xy.SpringBoot2NoSQL.repository.Couchbase.CouchbaseCustomerRepository +##### 控制器controller: +见xy.SpringBoot2NoSQL.controller.Couchbase.CouchbaseController + + +## Solr for SpringBoot 开发介绍 +##### application.properties配置: + + spring.data.solr.host=http://localhost:8983/solr +##### 模型Model: +见xy.SpringBoot2NoSQL.model.Solr.Customer +##### 数据层repository: +见xy.SpringBoot2NoSQL.repository.Solr.SolrCustomerRepository +##### 控制器controller: +见xy.SpringBoot2NoSQL.controller.Solr.SolrController + + +## Neo4j for SpringBoot 开发介绍 +正在写作... + +## Gemfire for SpringBoot 开发介绍 +正在写作... + +## Hadoop家族 for SpringBoot 开发介绍 +准备另开一个项目,不在此工程(SpringBoot2NoSQL)中,新项目将命名为“SpringBoot2Hadoop” \ No newline at end of file diff --git a/bin/main/application.properties b/bin/main/application.properties new file mode 100644 index 0000000..79c7f91 --- /dev/null +++ b/bin/main/application.properties @@ -0,0 +1,101 @@ +server.port=9092 +debug=true +spring.devtools.restart.exclude=static/** + +#spring.datasource.url=jdbc:mysql://localhost:3306/boot?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true +#spring.datasource.username=root +#spring.datasource.password=mysql +#spring.datasource.driver-class-name=com.mysql.jdbc.Driver + +# MONGODB +spring.data.mongodb.host=127.0.0.1 +spring.data.mongodb.port=27017 +spring.data.mongodb.database=test + +#Cassandra +#spring.data.cassandra.keyspace-name=mydb +#spring.data.cassandra.contact-points=localhost +#spring.data.cassandra.port=9042 + +#Solr +spring.data.solr.host=http://localhost:8983/solr + +#Couchbase +#spring.couchbase.bootstrap-hosts=127.0.0.1 +#spring.couchbase.bucket.name=mydb +#spring.couchbase.bucket.password=123456 +#spring.data.couchbase.auto-index=true + +# Redis +# Redis\u6570\u636e\u5e93\u7d22\u5f15\uff08\u9ed8\u8ba4\u4e3a0\uff09 +spring.redis.database=0 +spring.redis.host=127.0.0.1 +spring.redis.port=6379 +#spring.redis.password=123 +# \u8fde\u63a5\u6c60\u6700\u5927\u8fde\u63a5\u6570\uff08\u4f7f\u7528\u8d1f\u503c\u8868\u793a\u6ca1\u6709\u9650\u5236\uff09 +spring.redis.pool.max-active=60 +# \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5927\u7a7a\u95f2\u8fde\u63a5 +spring.redis.pool.max-idle=30 +# \u8fde\u63a5\u6c60\u6700\u5927\u963b\u585e\u7b49\u5f85\u65f6\u95f4\uff08\u4f7f\u7528\u8d1f\u503c\u8868\u793a\u6ca1\u6709\u9650\u5236\uff09 +spring.redis.pool.max-wait=-1 +# \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5 +spring.redis.pool.min-idle=0 + +#redisson\u914d\u7f6e +#redis\u94fe\u63a5\u5730\u5740 +spring.redisson.address=redis://127.0.0.1:6379 +#\u5f53\u524d\u5904\u7406\u6838\u6570\u91cf * 2 +spring.redisson.thread=4 +#\u6307\u5b9a\u7f16\u89e3\u7801 +spring.redisson.codec=org.redisson.codec.JsonJacksonCodec +#\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5\u6570,\u9ed8\u8ba4\u503c:10,\u6700\u5c0f\u4fdd\u6301\u8fde\u63a5\u6570\uff08\u957f\u8fde\u63a5\uff09 +spring.redisson.connectionMinimumIdleSize=12 +#\u8fde\u63a5\u7a7a\u95f2\u8d85\u65f6\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2 \u9ed8\u8ba410000;\u5f53\u524d\u8fde\u63a5\u6c60\u91cc\u7684\u8fde\u63a5\u6570\u91cf\u8d85\u8fc7\u4e86\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5\u6570\uff0c +#\u800c\u8fde\u63a5\u7a7a\u95f2\u65f6\u95f4\u8d85\u8fc7\u4e86\u8be5\u6570\u503c\uff0c\u8fd9\u4e9b\u8fde\u63a5\u5c06\u4f1a\u81ea\u52a8\u88ab\u5173\u95ed\uff0c\u5e76\u4ece\u8fde\u63a5\u6c60\u91cc\u53bb\u6389 +spring.redisson.idleConnectionTimeout=10000 +#ping\u8282\u70b9\u8d85\u65f6,\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba41000 +spring.redisson.pingTimeout=1000 +#\u8fde\u63a5\u7b49\u5f85\u8d85\u65f6,\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba410000 +spring.redisson.connectTimeout=10000 +#\u547d\u4ee4\u7b49\u5f85\u8d85\u65f6,\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba43000\uff1b\u7b49\u5f85\u8282\u70b9\u56de\u590d\u547d\u4ee4\u7684\u65f6\u95f4\u3002\u8be5\u65f6\u95f4\u4ece\u547d\u4ee4\u53d1\u9001\u6210\u529f\u65f6\u5f00\u59cb\u8ba1\u65f6 +spring.redisson.timeout=3000 +#\u547d\u4ee4\u5931\u8d25\u91cd\u8bd5\u6b21\u6570\uff0c\u9ed8\u8ba4\u503c:3 +spring.redisson.retryAttempts=2 +#\u547d\u4ee4\u91cd\u8bd5\u53d1\u9001\u65f6\u95f4\u95f4\u9694\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba4\u503c:1500 +spring.redisson.retryInterval=1500 +#\u91cd\u65b0\u8fde\u63a5\u65f6\u95f4\u95f4\u9694\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba4\u503c\uff1a3000;\u8fde\u63a5\u65ad\u5f00\u65f6\uff0c\u7b49\u5f85\u4e0e\u5176\u91cd\u65b0\u5efa\u7acb\u8fde\u63a5\u7684\u65f6\u95f4\u95f4\u9694 +spring.redisson.reconnectionTimeout=3000 +#\u6267\u884c\u5931\u8d25\u6700\u5927\u6b21\u6570, \u9ed8\u8ba4\u503c\uff1a3\uff1b\u5931\u8d25\u540e\u76f4\u5230 reconnectionTimeout\u8d85\u65f6\u4ee5\u540e\u518d\u6b21\u5c1d\u8bd5\u3002 +spring.redisson.failedAttempts=2 +#\u8eab\u4efd\u9a8c\u8bc1\u5bc6\u7801 +#spring.redisson.password= +#\u5355\u4e2a\u8fde\u63a5\u6700\u5927\u8ba2\u9605\u6570\u91cf\uff0c\u9ed8\u8ba4\u503c\uff1a5 +spring.redisson.subscriptionsPerConnection=5 +#\u5ba2\u6237\u7aef\u540d\u79f0 +#spring.redisson.clientName= +#\u53d1\u5e03\u548c\u8ba2\u9605\u8fde\u63a5\u7684\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5\u6570\uff0c\u9ed8\u8ba4\u503c\uff1a1\uff1bRedisson\u5185\u90e8\u7ecf\u5e38\u901a\u8fc7\u53d1\u5e03\u548c\u8ba2\u9605\u6765\u5b9e\u73b0\u8bb8\u591a\u529f\u80fd\u3002 +#\u957f\u671f\u4fdd\u6301\u4e00\u5b9a\u6570\u91cf\u7684\u53d1\u5e03\u8ba2\u9605\u8fde\u63a5\u662f\u5fc5\u987b\u7684 +spring.redisson.subscriptionConnectionMinimumIdleSize=1 +#\u53d1\u5e03\u548c\u8ba2\u9605\u8fde\u63a5\u6c60\u5927\u5c0f\uff0c\u9ed8\u8ba4\u503c\uff1a50 +spring.redisson.subscriptionConnectionPoolSize=50 +#\u8fde\u63a5\u6c60\u6700\u5927\u5bb9\u91cf\u3002\u9ed8\u8ba4\u503c\uff1a64\uff1b\u8fde\u63a5\u6c60\u7684\u8fde\u63a5\u6570\u91cf\u81ea\u52a8\u5f39\u6027\u4f38\u7f29 +spring.redisson.connectionPoolSize=64 +#\u6570\u636e\u5e93\u7f16\u53f7\uff0c\u9ed8\u8ba4\u503c\uff1a0 +spring.redisson.database=0 +#\u662f\u5426\u542f\u7528DNS\u76d1\u6d4b\uff0c\u9ed8\u8ba4\u503c\uff1afalse +spring.redisson.dnsMonitoring=false +#DNS\u76d1\u6d4b\u65f6\u95f4\u95f4\u9694\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2\uff0c\u9ed8\u8ba4\u503c\uff1a5000 +spring.redisson.dnsMonitoringInterval=5000 + + +# elasticsearch +#\u8282\u70b9\u540d\u5b57\uff0c\u9ed8\u8ba4elasticsearch +spring.data.elasticsearch.cluster-name=elasticsearch +# \u8282\u70b9\u5730\u5740\uff0c\u591a\u4e2a\u8282\u70b9\u7528\u9017\u53f7\u9694\u5f00 +spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300 +#spring.data.elasticsearch.local=false +spring.data.elasticsearch.repositories.enable=true + +# ehcache +spring.cache.type=ehcache +spring.cache.ehcache.config=classpath:ehcache.xml \ No newline at end of file diff --git a/bin/main/cassandra.properties b/bin/main/cassandra.properties new file mode 100644 index 0000000..6b39d8e --- /dev/null +++ b/bin/main/cassandra.properties @@ -0,0 +1,3 @@ +cassandra.contactpoints=127.0.0.1 +cassandra.port=9042 +cassandra.keyspace=mydb \ No newline at end of file diff --git a/bin/main/couchdb.xml b/bin/main/couchdb.xml new file mode 100644 index 0000000..e7d752b --- /dev/null +++ b/bin/main/couchdb.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/bin/main/ehcache.xml b/bin/main/ehcache.xml new file mode 100644 index 0000000..c645ed7 --- /dev/null +++ b/bin/main/ehcache.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/bin/main/log4j2.xml b/bin/main/log4j2.xml new file mode 100644 index 0000000..00314e0 --- /dev/null +++ b/bin/main/log4j2.xml @@ -0,0 +1,61 @@ + + + + + /tmp/logs + /tmp/logs/7z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bin/main/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplication.class b/bin/main/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..55a0c8b4162a9ce18c51bc9804e8b9fd44c592d1 GIT binary patch literal 1046 zcmb7DTW=CU6#k}#LMZ}Lt=4P30}s2=^udIti6#0(>SYam@M+i%bm}sLGlQ0&<&%vM z{s4cJ@yxbq7vaThcFxYZpYJ>S`_Io`0JhO6V2L3-nTFBWNHyHk+P&D<(fjT{iZ98l z@i>t&cT%eYatyU&{*{LbSHtja|5(J1VP!`u>2?{G8_ga=uA>h{3Cmb5Baan^YF8?; zKN%#$8B(%;XOId>#2!}IQcw$-MRBQ6!gM&ncWvc1Up(b~;k5mykRn;Pb^Jw9XATtm>D~oS|>(j+{7ls z8s&Uv^jH`-Wq8?`uRpJ8&Z|nejk^WhVQ6VH3~kEF!0?gyrp@QDPyC!Sli{O`d$>=i z(=ZJEZ0SzIt!*y?qq``5td$cdF6?MEki&`bfMn{B+M7Mj+zg4L^#z$3N|BzJSiF&* z;jP)ln%SekbHuRu;f#cyw9*$;O1pH=sKWN*K6!j3LVn>GzE-}~4yirU3_ASz|_VA5F7M^0Za5nyH96M0=S_yhb=9`Ed?NeB^pJoZC(XLjy=?tPwTX7cA>zyAT?GISa#fr+hcceN4vL3KuJ zb8$(p-YvPF4%YpuJ1e6|29;3G#^W>w1a9iE>P9hOJ(P9zM2DMhMH=aPyQ_EM)8)v7 z(lb3Y%}^R&2LeN-I|~bQD+2kFC6x{7Z7724bsa=*O;@W_<(71HN?=$8kNr>wbrl$j zjsd+YJRK^R>)g4{T0)PnGy~(;)tVpq<(irf0&QXik-)XSL}eu@V4c!+xb4a|z@2Uy z{lpJdg|wL)Ud<1D^O?ZD!uXoNz^tyQEDqvu8ixeVzS+}!!tNl4BTPkA85$M1R46@? zkEL6av_4y7N~gyEEj#-m@V0|N3<(@8`GHz$*2^lqC+SuoSJIxWt;x{0Annzfkx`+*A{F?VZwQ<>J4ebXe zvMVk+xP;3BhazRTsqM$*_#->0U*gs>xFT?%!`RTF$>JKWr}2rv;ZCnE(qUDF4yJH} zo1-DaNOA5Tco(gh&m4S?FIWkRStc)gu&_A3mc|TCbeNMO&NTg6MTHrB$*nb;q(1M3 zN*YzkKk>~*zGXI_xXnMvVjAJK1uf1E^jXZQ1ch|esagPa+L!_iwDjq_>$_UFWN9QYL@PdP~8 zDF0gkFoI+83^?MA)q=Tv+OLBX&v3jKawLY>r8e3LoaA!=?_#V4zQO?Zn=|nn-pieO zfzv7c%yDgQ8N5E9zMs_ z9enx=MqXn2es1;|=3ZI5kh`^mh1_lai|4yQcXBJ7-NC&V_$GzPj^Lv-2_~O+EJdHD z$TQf)+1S9*L|Dr}28v%F(!9VA_>sl>iO2zt#u{0$pL^4kCa literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/config/RedissonConfig.class b/bin/main/xy/SpringBoot2NoSQL/config/RedissonConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..caf069a164a3737a09a558cbda616921468ef904 GIT binary patch literal 7406 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 literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/Ehcache/EhcacheDataController.class b/bin/main/xy/SpringBoot2NoSQL/controller/Ehcache/EhcacheDataController.class new file mode 100644 index 0000000000000000000000000000000000000000..9f12bb495535b205c1c6fd5ca7312946ee740fd3 GIT binary patch literal 2424 zcmb7FTUQfT7~LmC0%1f2(MnNKsgh6~K}xM4E#Rfph)57`we}=Agn?m(&P=qlt52;z zq)&Zq*J@*}YxM{8H}t9hqnCY75<)Qb@-TDGobz4xx4&=x_~*CZ0gPfjftbL=mz#EW zBXGRpwC_hFbAI+_#?Jd*6!@;I0{ikxUglR+ZM`HTIkR<}KwMz&s(d7ES9(SJMs8K* zBY{@eFBVlGa4h2oMO$td6Z(*TY_6lLcE*T|3v`r16=YTL$jK{#;Y_oDD50-wQP{WY zDztEDq2xu*x>|BVC+Dgu&+{W0IldPPoHr4KCd1`GuB*p>ux96!^g?@C<|9AYwB?q9 zJynYQ$4;OMG;5j6uS-vwTn=YE71`mkt*VgB=&Y*O6mOkyJSUnIXc1j-NRkPvRgBCGeKOiI<^Q^=zRRZws{3W(87# z(ZLsNre0Zyb_g7{unVmMdoqrv=1S{16)Z|3D$tej^U__Cfup~xhw*5|VGff`OZK`P zB61oJT~XTVs^L+J9M{e`VZ{6PtW)%4R0ydOz^xSG|qJ{~i1rFA0mW@pFlpMF9f;PM>&{GPj*>Bj> zzh0rwh5jT`IHRdxQ(}98Dh9?=OS%HX7CK-haSrb#Fv?2Q9T{?17{mJl2_iN}G7Idl z;b9uEYD@e2z`_ME{8lESyn?{#W=^*er6CcLFola2CbhS=$gf;>;3G^YFePyGWz1x| zSeVg?#vO0j*LhvGkU(1!S23Hw#{%{ncDaR5&?%72yGjP8@e;_eeGEK?D^o!rH#K3B zxQ2agxIym`3#k*isj*lP=o_5f-flZHzKTT)x4`Dr_-aP(=%p&WsaG+s19xyQfx7~o z^#FBj7VhIyP6%0GK^j<48J**)dnBCU83${nINLixI09l;;6P(LZf?|Ca%6|jYc`MJ&aVx`y~A{`ko_ow`=GrPV?g|-Ig&@ z#`!WPp5en7czCIdE6;K5?o(XPv|RiF14H`IsLfHWuZ($0myvyj+cDh!E++c+7QX-Y zPc3`oe?+&W{u=s`fyAK`OdF^Mn8Zo;UkbxK8N(13xjw)dWas8H)PA8wH9+Rjh zKTNp?_>8HZQiD~I%5j%BC-J{AmcSj+pX}us`MOjD!7=iy#$^}3*Z5tp Gmir$^c6nU@ literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESDataController.class b/bin/main/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESDataController.class new file mode 100644 index 0000000000000000000000000000000000000000..e17d887ea2ef0f63c715efa3b92b2b4582358cb1 GIT binary patch literal 10592 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 T!F@kt8CosT`vbBPFmw4|_RmHp literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/Mongo/MongoDataController.class b/bin/main/xy/SpringBoot2NoSQL/controller/Mongo/MongoDataController.class new file mode 100644 index 0000000000000000000000000000000000000000..a7838b125f592f0cdd5a87bd47d18ed8c8bac888 GIT binary patch literal 5410 zcmb_fYj+dZ72Q|JNS4Q#D8XQw77{|@R~X|!0LvlxMIZ=cTVU#hK*#b}9xQ9b%m{F4 znl|*2gglxyY13DlzSDP-CK$(ked>q)j*_hYgs#=q)qQ8i(%2dna@!Bm+?l!e>~r?n z_nbR_`}c=`0Gc9VM?H7 ztW6c7vR-M$ff~`(#SqZIb~$>GX|sU3H7Cx#L$)cobGsR3iP(7D@n>Y zGSjKHP~&rSIKLtnG!@SBC4EwzGzwEeg2(g=CEa$8YsI3(5U9JT$xy+) z*d&mcX1x9L!?Z0kSH-D716e<1>sH#Zxet=9ZQi7kW8_u&OeQ8{t3C}_h@0i{H*j~1p)&-0DdemAdF>U?ootv##et|^4b zh27jXRE;&yLF7WWz|Nprj}{y~r(2Y(%XW~+6Sd4+lQW(l-IAAm3ijh6rtp&C%#2F+ z4!gPU%Q0>1H2Ht0=aO6bmfd75+(6W^!2Ln@%A2lAGZO5ef=6+P`tsKH&mWx<*c4pv zRn}D7cpUu#F}sw_>NZP6#Nf;(Z`pvX)>=+(w?~3&%h+MHa>j9r>X>d9Sx@yL7FuVX z!W#Ww*7pW@@v)^?_th-cL6^Zw5lONc`JpY>56Rl&3Q{-}Lt5a08bhncFh*iHA+Y0? zD~^zn3_DE8RxpY&fq37*z|hFap+QPBGzOQ$%Cb}f$8b_s{8Iw0tu-xa8<(z~R`6+w z*wEiMcy4TH^wd!1Bo*bAPTH!qHV8B_g6u3QbUR86Pf?Fym9M(q6VIR&ES9gcK^3HV z2uM|Dw)#oUjU^6^4Z>l+=uRLDJqBv|j>-n{_mqNZFM%^K zBG!!B>Qz$*U{k2isbE-loEET6LHa9GrAo97S) z6O~T|HrU!ly>em@*u}DcyKGeEr(!4xwAa2Mj!VpUj4__ zw-a!1MUwP6Zkk|vt4Ufe8&syi=M~f=(SR@D*%-bka3IW^s?%I0hRP93!Bt6iRB|F9 z$WrH8xF8WVkmntIQgJ*-B0hfk+DC7^9>WU)n}bcHFsn};(d?Ow?j-O$nqqi~$_WcB zxJzUgl&8-)UZL&3-+1Ap4;JEhl@WD!bsb3HMO=yFHNLvJ_~)AoZ^rRW_toy*4R{0J ziQ(HkdRDw}Yj#%JQ}A7UPqvmRQW9GGpO6ZFQ^61L7W=iWJIk)H548BXbo*n)C>w^% z*^lJ;<;MbtLNdN4B}xx|s^Dk%IZF&Zs3cfGy?uGAOm`jIhG(gOBK4W~No6F>-sV~z z2ub859ueAatCnS2*mL9>o+$c5ZQlN9P_`udm%_{hT5RU_;rc3UyLAVsYP`Asztvl` zc)PvePXnxFI`TY+!7t&uy)Vj9Id>`e8$U z6>V`pIahvc?vlG^Z671HQ~6e92G^@|@=F%?u%NBu_iuzhejM;F#*w_nd4;TWtDZIR zo*!`hZ{&NGSHWvt`vNw+%RvMi`7aFscjFHJ%c;_M5_j^-EssrvlrS53*UaDMCn0QX zL5rL%?QNA0ZG6Ioc$7A!dkyXHcpC)T=>j!-(|jN4{2jTcV4Yjo>dhvzofcsl;QhLwmgCWrw!W*#co{5++HMS=fdmM>4o3T%eOtzPDfp z+^TFo%XMpvbL7gcOK>KV7n7G4@Yyt7dYaqr8R?O;+M`iweJqg7t-ePJH}{wDWg-e5 za=sFZdDX@ICo$I(Gv`wA)s5RdD$+}MeqsUFjxXWGiR8=4uPxx~!|wPS$=5mViFQ7? zh;K!3x>NEc2OXW)@qOuS^70~n7(q{6M@!vx{6uof0NyTB>g8K*W$+`Ti5c8XdUh~} zUCiBnJVgbZ!(nL1V3KdA+yD=HZu$W>apf<#ii*Steu-Z(#2pyKukjmF-i3YmEk{vW zxXUG?u3Q+r`M=|Q!9w;f=Xizby|P+HUh%KcKTx=fgBFbJSc3>$E55>%N@5 n%IIyj^OW;!AV1Az#WcIZl@)K1)*|@Og->#{B(0ZS_``ny*SU^V literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedisDataController.class b/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedisDataController.class new file mode 100644 index 0000000000000000000000000000000000000000..0c79dc0a510500531729e8a05e435ad420844ebc GIT binary patch literal 1647 zcmb7FT~8B16g>ll(ozbde4~IOv=kXd`G|-KVtguytu`?{P1~U?wmWra3KHXg(!@Zb zi9f&}WxTVkt-uoTVP|%>bMHC#oIBH>zrOtd@Cd76v@xuHIOf@^=eVV3N}0uNm3@`w z1?3t~mCMrO8Ci66eS9vA*lhk1Mu?&BKpYBQ7H)~Z%pb^tVdzo$gN&>y?HJ`9GpwY8 z5WMD&20}f&6}ZMQlBv1IsmPq8oqSntxUMq7ILg&TJFUDD*FNz*PgLZQ^4{^h6t3ob zqF|x9Xa?|&no&oNCySJJP#arr)*oAd4C_~8S`R!QPKi68IId%!GPEa>Ifl@tD#|F@ z(HlcIVhp`$$CcZ)N?v-e1r@~5pH>A?&I!-4>&C~B*>|YI$AN6F;tWxVm!!$af+`Uq z5{zLck#1R4=f0M__~|lXk7SJ0=-s z10=bqNHP}z6%j)RI-{7zOc-|=mV&_k+0!x1B0-$BI3$^pi9md_1 zvAb=)QTtJ2%!k-T$fr2)9pi6PsZ-qAn)`~W`4imfPkyG5I%M46G(>!d32M}bo~#Ep zph3W6NKx)6RWOfx6v?naH3ZSQe+iv+in3}&EQ!>y`>DzX2;6v6KJ+ literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$1.class b/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$1.class new file mode 100644 index 0000000000000000000000000000000000000000..48bfbb750c7b7e546b2f336bea8d50de2342f5d4 GIT binary patch literal 1274 zcmbVMU2oGc6g_UcmUe-b0UO`rqtLEMgdrqAt@c1wP^D}WE9~7(tkfg3qr{!)&*A|g z@xTw@M$G#`$emLKMeEkOC85$+z7+!vyxPv&6Dtx82dAg?uZ#~!7 z$|O39MB*NZK&I0<)vEh@qrP22fuVN9Pq-U#6}tPwBjKA8iVUt!LN~FV9FaHBb9II^>D8>ls+EK{2$K6;t1)pvqd! zvc=G9dS_*}XOrBvBFh6ADsILJ$varkvE%)zXI~i+ilqGyXeax?N>)&Y#)6_4)=y_? z693B7{$dmh%VVev^f>XwYiX;qk#+H@{(Wo%W%w``-L!$*XG;02dH+LHwWs_@r*zqN zg&FCfgnJCnmuz?kbv$5L4Tag|ahLleinP(33us{My`C@N4B6^4IDJJouN(0+6)Eme zx94fBfYoZY>FF1dqfthM&{eWt(ApxE)}zmGT3>MCQ+DQ}#j+jiEwM&xhkPu0376^3 za0TmhVuS1)u4Zg+GMn}+NgkG@m^tZ;z#g}bQvz#U!*!Z(5IQBd$W1~DxJ6hFw`cU5 S6bcBvi~D#;mX&YC(DM@?>u3)E literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$2.class b/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$2.class new file mode 100644 index 0000000000000000000000000000000000000000..31b6d52b1c8040e194b37854dfa376c0de135e3e GIT binary patch literal 1274 zcmbVMU2hUW6g>kJgsy^BTfaY1C?<{}CTbvkkf0&iwy~JL56fiPx}71jLzSQ9gE8^J zAK;HN-dRwoF)6ai%-%UO_w2bJv)_Mw{RZF}Y6WB%UVfbN{@6q+e5JK*?&r@^l_PN?cq~-N_XkHZum$89xHcg-&Xat&7)ShAjJZ6K z%JMEzPdi2mD~EoRSgE98$lFnrRG*R_e?>tpB56k|vO5gz`pPWZhYY!n9?BvZ&U+}} zTnSl}Jrq%4$kyF~vL7kAH#r_i^G*z6$*|$;K*Wc_L~cC?b1o=`)~aHvO$w?=S)XN# zp;7nG%52vqx#dI_`%$QbofwjLu%u(#|5MMNvNDvW^$%z#{lHpUP=?x)q8K($XK6bA zm8t#ZD3+GTQ0nW63FPa@Rc9;h;#2+m#0ARmej&P91GmnU@>lczhp2K_1+h-(vh7Mc z(!&DoGdy3h;XPFGkYPQPc2|r$A{bGmwfaIpee3S^VgcvKc8|g9DY|)`SR{!|aF@D0 zOJfbJQgKaBzlaQtB1(j=ll6ku4koif(xJ0GZ!6}?l^CQ4O)BTkJgswuXwtjyVg<|3wYoZ3y2MHRIZ5xZ}`>;%wsoR;&?$8vU{7XI< z6CeBm{wU*}1r-vLBAd+Yopa}&J@?L?{qghLcL2{(DTK-xqFAcnwbtg@zV5yA zTwf~_>o63tdng7nnaqh+?LUs{P60WF$}vCXZpc;O9`uieZwkmWxH=Bp*hW%}%OmNY z@W>UXLK(M1)Z@-sB+2i|#0Vu~hP)Zdr23TfcuNXu5=l!cX?7V}^`%+1j~H@oJrG4O zTy#*tg%YwTJ1C;UkgeMdWlt)xKRW4)_&x83f??g$J`az0EbV#<=4?_7&1J<@cPOc% zR?})RH0s{Dm9<4~T9L(`3=}t`nB*NU7})auo@ZAX5s0|?4`?_2z)E_c47CMCF>K6N zX&n8o)WKpD3(I3D_4FwA#T#i)XEW{Mx&D1(6J_`?lij3&o99cJZ{Gh9RqiN1)Cpa- zJz<7=P{0F*7fUw0gDM^}tOmmD@uJGB{mDH?JM?BoPVj zQMYGltbkQ2w(02?k)csUiO^NDUeekkrN-kga2j86>2tbg&0?v?Mt{UQtsRQ7=w)1? zH^WtI(2h;AGq{$ry-jWMS&}R)Nj?qwloHtOHgG~kI1s}tr&WK0iH@|Qvd(} literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$4.class b/bin/main/xy/SpringBoot2NoSQL/controller/Redis/RedissonController$4.class new file mode 100644 index 0000000000000000000000000000000000000000..82391486e5431a95f2e1e7cd111f09b224ffd9fc GIT binary patch literal 1274 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 literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/controller/Solr/SolrController.class b/bin/main/xy/SpringBoot2NoSQL/controller/Solr/SolrController.class new file mode 100644 index 0000000000000000000000000000000000000000..3b52997643a2a001731e8d852c5286315d3d1cf6 GIT binary patch literal 2480 zcmbVNZC4vb6n-WIvV?7$ZULcGYOyZ?v@4X>wn1uuR-q|SQb9zmlk5iM3+5kFsXBdXpt4<)xVnh0}V2iBdxB(BO>-Y?}bFNo1{V@3*kC(-P z>+P8Z!5!b+;YEdS^5zCJTMgU;=?RO%_RLC026GHu>G2JQ_=0PRB)V`)M=z2LXL8aJ zE7fvAcuzRt61kjP0Coqo)t&aUp>bhP(g2Bs$(#`t(}D z7JJGzTdZ}Hix?3iRQB113eMHRCom#%t(g-rXq2W5^Hm%_k$}Ma0vW96g+|V#X zrFtl7eT&vJ8g4UmFYUYPne{w==WGIf68HszL4MO)Ny9}h?gpYJQl87A6kE)lNk$;RgJOg4=gzGR5G zdxTsPLAZPHSjROzsj7Kda(GbnsClxHPSK}1qSBc;>S1a?+g1!#b*y2T80=8*hB+iC znfb$|MTT@cmwNlR%dlEe$DP|0FaM6NC(H7bSph0jN~idOx5#dXFBF{hms?SWo zx-*c%8G6@i4zxN;EBZs=9C@jbr)kws*T6QIkHIkD-xOR0d@=DG-aEoD9b$UX{>123 z*B^889~%YP4ZWgr+-2CN)qu zy~1ZlScqZM_~IABukjcQDGyOj!?;RyxPuYoZ~;$gyjRF}h>L9;Uo<%`VVNX+7{*;H60;%T}ajI=wlol-x`6Or%({3vm@ zEvne+bf@&;fHGZtcm_3DG;-G(Z-+R@sq=CpU@IMG;&%$CbdSlKhSnI<{1x%r+sj=r;2_6OmQvZlg9H=)1T^e}%TePg2seHMCugz9_= z^kaY}UFxtT3}NFJNf#}e>J78$7N{ZIMjHkbXh#R3&sBlURZ4joolCJhe@l1p& z@*7~>T&pr+)BW#TX9-;@+Cff~Y9!6c8>$HHzNnNrINTz+`LYDt)0NPd`@BTL?B9D` ziF#uW#B)X;@z2BZX|Z?8R)h~`lAZBa*yn9a-ZK)*Pe?v89K#TwHs9c)BqtBEm8zFu Y1f%S6F~%^?4I^s;lblVMVlRg2Pe6pTnE(I) literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/exception/GetMappingFailedException.class b/bin/main/xy/SpringBoot2NoSQL/exception/GetMappingFailedException.class new file mode 100644 index 0000000000000000000000000000000000000000..c7bcf4b80d3b7a662dce96c459e76234fa3e0208 GIT binary patch literal 677 zcmbVJ+e#xr5IvPdCmG{qlXbnz2)npm*Z~oiCE|mkB8(B8D2Pv;Nvkc%beMEBewI(W zEa(ULQDTjWCW5}$4c%3B>T*u^!{h&Z0IQg_kRbeS-MD@|QsMcA)@G%s{R7XHtw7d| z(xJN}&7P>&8QvDEDl1zrh=mkk@={z0w<^MO_plinRge|p_K-^8;D zJ(1Eyq_0J}Dhmt8gw&?4$TTv9@0*bnMmnAO&e<~o=S)Y=Zdj2mXZ}ZH-ogN3q}zVK zd?^ECV-Uj@hTcH!$ytox3zOqEHDL&U-XV9|!>--1u+S6gNU)JaK8rr|6NWt%%3`xt zmQg8|LdbbK5Y=N5so3uXQ|3Z7c&7KsM=uaED%M^UwdWaK;T=+hzCbh^4373N?mjWW z_H{D~uQ_m}W15nJ1YVwfX=6 literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/exception/IndicesExistsFailedException.class b/bin/main/xy/SpringBoot2NoSQL/exception/IndicesExistsFailedException.class new file mode 100644 index 0000000000000000000000000000000000000000..e0204f474c3096cc2f742d8c0a5d64d89f1a08b1 GIT binary patch literal 669 zcmbVJTQ37a6#hQvOA@ImM0?N2l!Fq ztd>?H9?T>&=X~e#eP`zF{rMHZI%X{-2%GhL$GZttP~OqntQE9(M1rO9jeo6P6a-R-R{Kx_ldQ zauw=3QLM=P;u#^it4p#QJ%mh?KAW45a@osIdJDaT!B)4!;HLF5T!7P zA=YxK!>TZZjbF4}w25gn%rCYy|1;+aJt`>4dO=h_X7wa}OQ{C|YGzdm&} z?v6PS&l)e{%>(mkv3JT=jAxe8-N_f&=N-%56H+UWNIx)~z%ZXS-{7J&Cy%g|ZIoaX XW9)G;#xcPSV`~yqoK2W!FM*j400Xn@ literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/exception/PutMappingFailedException.class b/bin/main/xy/SpringBoot2NoSQL/exception/PutMappingFailedException.class new file mode 100644 index 0000000000000000000000000000000000000000..de6de663fbc22ce16bb61290b2ac928eff6c9ff2 GIT binary patch literal 674 zcmbVJ+e#xr5Iq&6qhq|q^?qS|ka$^kKo&$IJ}3&p7%!v3vQM2!M_ZEVFzIo#pXHMx z=m+>wVvUI=g1*=d-Bop}>YVC+dcJ=I@Eh|MQiS!!f7h=?D!ka%+N>3{f9$!k5y+ZR zI&_a>b0BIphWCW3$kOf`Vj)eKz7p5Mt%&f#J&8l3s`4Et^lYk7nJvP~lGo1jO~RG$ zh@4(V`kyFPWPbUaklxWH*^55H0&_bpa;N;t?v!=p?1v@UaB_?FoP~bEaJ%6Ozgq3ldsxX9&Pn7-bkk)LNU+xIC^xNpdXa?QrAq;scl!drjl+kH2 z2O;a}Kvd2}q!PasOq)wpXHM^%FP@GfU5v|9IV+q=GQ z*Pqt(j@>lc`kHiIX*C_GuXSC|?ifxQ34!rf@{QEn(rW3Cw_h0zPatMC1tx0YLETdk zD+1YPUCT2&#)j#d+ihdjvTRR!rfs8_uA$B`Z5t?j(lo6?hdqo2BAJBHqo zySt31KXJ^CboL$@dkj6gV>+&9@twd(TOKUqvc(Ni6-X_cmg(ISh!=_*0*N(Nl|dZG zH5|cFfnzn(GS<7DZNqsk38zZ18?wD29aH(e&4l;TB<(`&e>z3JyM@0S@-I8p;>IWh zPHRXarB*o&qrvKohD@+Jt6>b9K+-k5Dw{tUkxUhxYz5~h3&p>43ut`)AZ(+?+XLFYdGx4TZmcwj0S9XTj>L17Er{%@iC z(yL&W(~t9KO(3SkKrc;C*%8{9l7(+63g1!^v|~J{!1+B!Pp1{M$6@_x&S9oUbB}k_t&~p^X3qG#GmJOu zXPOFb^)sbTdI}B1_y5b=qs!%nLi;*DNVUThp z$Xql?ei-B`L9QJFqWY{rE=7Xmhd~x2LFQ3l2qlzoH2FV75sc;zL6!~yQDashMU;B6 z21hgfVQ4hVksz1*RctYpQg(5ooc@mZX1v7t);AM0+4^RZCSTu7(M*5ELj5Zi!%C0( b!mF~LhnPckAW^X=r5Nt|IFNe4rb7tnu<(qHj{QUL(2N7-1qc}wb8Rr*9@zhmz<%Q$;>-$de zZNaEJWmz+JYo_Nbt0+y^sv2)xr`)joI7I~w9-C*TQ8Vp|@w#*@EniSXl?4qK+7Csa zlRgnN^{!$2sxA+dr%E;X+_oLx^p#_Kg0cn2tr(uJf8?5V`N45djI!yQhI#2{?3Ixw zYU5c@e_48#t4=wApt!V6Q@!8trh;08i0J9{hNV*u^i?Ok|by-fnzE~y%b|< zx|yP6AkC$ypHhN)E7IRX-=o>w-v#jO1sHA6yq zyMG7=$Dlk3mrGMLi#}j0It|y7uM{(!YVFM`Z-$^}-3Km%b@PICYmeVEb{wlwm$nar z6Ur{j^8jzOCGVRJES9;Yw+n4T{S;NAv ztkG?}a6ptI%sI3;G`{=Vv3vx;Rk=2`2JOO`6OvH=(UGX(m4wZPIKzYeoYZM%EF48%6#x zNaHj`6S~R<+CZjO6_$dwSmI_FQ-)Vbx1HftLM}nKG!=}-fEKj#l_o#K5Fu`dIpNT- zR_5srUO9Lh-drN4+i1g1YU?b(%;^l{f!8I>SPQ10yP-fboj~S8f!qrRlIaApfO3mn zfG|tUz(OdHnNA@2P#}xpKxR6DtOAJ91qcs`fn+I%vvV}FpFs1~(X598$rV9&nqwbwrR_4~(901t3bKp@ci^jUT%v57`ctabN0w)?UzLp#)C z`P@b$D^K)9#V*v5DHV5 zJm+*7gf z_S~6u?+no&w*Q|uZjc*kcS@GF8qJG98J?!$?G=mpH3}^6Bpei&nQFzZoy7zF%y_8f z<(2OFI|w|yoZisib=a2!8*3S=$%My}Cw4INM?S&vU(R#yNUsG;<$F)6CLJ@vE#JkJE zwWPyNnzewGpFJKyIxD@)t)bkbRD;UjoE4!v7m?bBzG|i^J4`KLRAU AssI20 literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/model/Mongo/Location.class b/bin/main/xy/SpringBoot2NoSQL/model/Mongo/Location.class new file mode 100644 index 0000000000000000000000000000000000000000..bca1b0b8eccfae85bcb8fd8fec51fa211bed54f9 GIT binary patch literal 832 zcma)(%}(1u6otY@+OheDhghXggLR9Tw2bLY&x-?{$t@as2#18iC_1Ufgju78_b5+5U<2zj*G2 zJP%{{qfAE9_2e+fBAHky3N*&Sx4?~qWaNGtjKg6jU|z<-FcfHdvpYXi1rG&^w_%V9 zl#Ze#%6bAjoq5%KrrYPs4`isI0NX|xRe?gM+h2k}-G+&hieA{TP-4c5lJMmEVi2aM z!64QwgpT_`8maRnS0nj)1ZNCN8%K^lL9tS=L`_6Z;5BU+c=HHTONm|p literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/model/Mongo/Person.class b/bin/main/xy/SpringBoot2NoSQL/model/Mongo/Person.class new file mode 100644 index 0000000000000000000000000000000000000000..693cf9ce7603fc7cc5c5bfc7bd1274acc0b8931d GIT binary patch literal 2341 zcmbW2eQ(=T6viK?X+l$%j&04>ZmjDHB~42W9UEgQ8BMc^N}-GeRpL)Kxl6q{cH}sN zeJhZtCV|8U;6ovvbL}K zhr369^M{7j_1ns|zVp3~Z#`E*-}my!8o2Vxeq&p%?RBj0PhP23XdvUX4P0%E51OH9 zRSYb@7IdRp#=lP)>I=G}7K6}ntpne62}ze?)O0$Y9S#D@)KZQ18W*La z5&NlBDfnP|3|&cF`^0MbfwH=Gug8p7&m84SK(lXbcR+|NshNsGTlMT9>?)7h+`bT@ zKC=EF2=&?v^^))9_8iX%tE@vQkyNF+%;ihL1y<%%poVUk4zLWZ(xzHsG~vmLb~gJM#3crLOgC5HXP$ZigW{@c0rDMy#=SCdEyhs!b8 zq(5PMntpaEhoVzFU&^<=VL2BV{J4`1>@dWODm%8XNco?|_UW?bdDlJPx`8My{}(v*YibfJ5Spy{C&{JRc zGpv=j&#?X*Pc!(K&mxh)x3W}T#4?pv_`HP;?%s`5@Ciy>QBR{9dM2Lg+{74aMF$1k7jqUvPvYD7Djf)-t=3~EHk&}w)?>%hMZ CEa#a3 literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/model/Redis/User.class b/bin/main/xy/SpringBoot2NoSQL/model/Redis/User.class new file mode 100644 index 0000000000000000000000000000000000000000..2e25419ff62313c5405dad4b2839b5d86b5c7f91 GIT binary patch literal 1284 zcma)*+fEZv6o&uZBQ1l}(pD*!lLBoyj4|G6xDZ03X)s!8;^hF_vdJ)GW~N5H^~T5W z5j2sIXyOC-F1`Zs-!r9SU`V`}eagSq`qsbq{67Ej3&2C%&m$#p@BIg}`_@xV|B34c z4|d(|i;j8X9!lGMDG!xz?)lQoBO_2cw%%E$Z8?4O`Tnsy2=d4YRKio`nqBEB%T^z) zeOpq@C~kYw^OfuDJ>3=%&jcp6T*nVAC+J!BKxXUbpK{*kFMkBGw%b>ZK)DlF=>{6> zk-*rSfo<4&;u~ub`kG&xY;|3+yJ%FN+N7$YYG_0^eZ@MSgT7 zT+@$mX49OthS$b%iaV3D;GAurq4F)1)i~zD!xCO+U}mcFKgwd#U=dUOJRo zO;IYDhO}HSKGF`PZq>AHLz*f%Vi8LqtXDYpG_cySTv?G0Q=+SeWw`51%I5ZXVvD^d z5XS8!I&n*&t6*4iw_ZJv&KsS)Rd;qtH}`bMQ0rhb;vO1oBv<%P{aAT9+dwFg>BgNi z(z(5M2n;6ChNy~$l1TW`og_Mt6lkkScZV0z*P?{#vaRC(@6G0}RuqWw_^zj1jEQ~} z<=%#pvA+@Xf)bTvu9wkw3H2;RAnw|Jn=#}B2AVyxSvSnGbmEv4=sfdTX5T2UC6L9m zx{py6X-Pc7EbHmV$I@b#(~XP*A+Pooz^}wH&kmHX-_$d&ga<0 zQ}dh!=eGP0bbs?;QXCa9(1QqiIl=>B5?6g(DS-X}z+`5Gd%X%EKY4zd7XdMzo=LBqL$Bn zgeapPe!rh}jvo#11@0mfU}>Cv8NOrSD?vk0GAJEE?ORDO)|yDVnaDWHJ-mj9e`5mo zS`tY&6UntCavu+ZE-oq3puVrjG>ObyL&Udvk(p+e3_dy3jJvTJ|E9opuTgLR~>FfRJb^##EYkd8lI5}c#G=9pfN4h31 ziAk)*W341ZHW(swHY|p8DL^W_f}VctecCY1eSSg^ag*0w$`Y|DFSg+trnbvnog$-~ zhGn>03_ZDgg(18{^Cr-PQ3Zn-61#B)8B9>kn(ppUu{y(GF5lKwUT!2Xi7PQ=8D=kn zzt1gBGb)(EG{I3#Zz6_b?w^|Z|LPD2^;4jrpCMT?EPcOma;Q6xJOk1tyGr_Va)Au- zFT?JUK{HI1F1DMrS!^frwQXbcZ}JrZp(+?aQtXx#q>zkZg<(Ki(~>)ZWsHiDs|qe5 z?MdoeGxV3Ffsu77kT7q!3yrX>k2KtC+1*D8!ATMN2L7l2G-)Bxl!|B(#0>gvf)LRp zQMMaSRo^qjdmR^lhZQj!rfHfU`bOxJK@7dLkJEoDgakdw7P%*7HP#L_!P z&tW=kQx2mwrJi9#Ro`Rm11>i)^Hyfe(Q|-0fnvi{HA(9{ofIzz3s|I+sF(BWJ*Q|9 zKi^SLEi{o=mzpT3pRoM+3|bSbL6Z!klr-u$86&)L`eZPN3E6PUE9y6-^1^lrF)wVF zL#$!lhtOyhLq*hg$iJaYhzfyPh|6r-1d-MRMO^cfw^q)0Y_ySfHTN7rD`0tE7Dk}2!p}ab}+~mx|FrQ)A>rAjCmlf^BK&BGE(RgLm{;{ zgd7B;L}=-Th)2}#7bwL>HBnBs#4l;(Wh{zHX@^c~Wf^=6#w-3j5vEO;Q@0o=M0qDH z2jx=D+x05dvlFl0)!n-|E?3K5vnR**!#xI@sYbod9HT8p;)fCFgsJ^T#b9;&=LmsH z!@uv);Pb0IF%n+EOF1re`WRrZjfF7F_Z4`)r6hBkPYzsJ|2g>@oFwMxi^$1)tW2!33Qt+RsT^tt`wy24?A%fjO9` vd!DQdbQUcvkwXsheTU_j4lCraI)pGy(Q5?H;KNXG*G7;ZpK`8ubAS2|TW&>j literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/repository/ElasticSearch/SampleProductRepository.class b/bin/main/xy/SpringBoot2NoSQL/repository/ElasticSearch/SampleProductRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..e7804c2a5b37077a581f76325ddc6d94c6fe0c8f GIT binary patch literal 1060 zcmb_bO;5r=5S>-Df**i-^yon^Zeom=8WIVbkTi(y!Sm8x>f*NBY_}>$|B64ugFnC@ zWn3r$f+Ydsp@-MmnfGSq&G*me7XVzqp#y6O8gG3}VlASeu9P`%DRS>&&101aqjVqN zNSYYo6Hc}Ngb58}$=h17)He^~R}K^qRC@G#XPH=WR?F?W`PL_f>KvRtln?gG6;@Oya^#OgAUx&>{n`p#GXiui=aqE5K)tA zoAS6o%9WQlkWeu$XJ#>)f?KmJ)l6A~C%zW35h_B^%3<^7PJ^kCiU_x9z-dSFyjI@- zwcu)vmM1H?j#!f+xXe?v$Y#V!iL1#j5tVA6-wJ7Ma5TroX9Lv;KBjz?8QGn`wq;Gc zy!i! E0qzD_f&c&j literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/repository/Mongo/DepartmentRepository.class b/bin/main/xy/SpringBoot2NoSQL/repository/Mongo/DepartmentRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..a712f7608c7d594f6d53d453d14552b39c572ed1 GIT binary patch literal 479 zcmbu6!Ab)$5QZmJyS6Iy+BeWk1L8#@B1Jr{Et)4tyJ<+>%`DSY-KX${3_PdxTLAQ^EvDFcSRZ02mu}KT`+M;-1oMD r{Z6LRf26wli{%aUPvUFEQx&ks>wrH`@Z=LXAu&j*!`R4az=IQz25dbz|&Vd|(&FePxn?|T`S8Ka=sQnX<8s5~gu-dfg zfmWfW$K1qP)!xGn^bsgF*cGFasgNGk8~n^VFhIc7CZusjJU1-jEp0Aoz$~LtiVEuA z=pR@Dg>#{T-S#0S64+YuK1%pDHR&#UKN*g6z~v{eE`iCGuoou@H|@O)S`Cr8*vZ^i zmWSLRG^>+XA*m-~i^)U22o zEulNE3Gm@6b^~X<5ESFoi9}x%zG~~LAm2kCof74+B|T}j8RD62nWV2&O(YS=ObS!D z#xUthPwcgu6`>C})sA7>RaM?7b1m&U6b_k>k_z$My;7IiaD0AD@NA|pp-E9S!WMn! z3th;T$G~tqg>j^kSj4>q?lLU(^WJNl!hJko7_AHAs=D+TW-{4G-;|8KB!zJ-VL5?E z)Z2r!cF*Cau!0N~)fa|gB@@ASZdjj24a(o9Z%0(>LjpVVr)bpJ|*XWrt=)^YH3- zT>nBpG0f6vX}|>LXiRk!a054KMNbHB(P)j|5X?q1x%w3gxo^0WJIBK~E-}eqdzPHf z1*o}>dWa%JWU)#xsstW~&|T88&~yMj$CDU-VevCbqM^-4c9%2h(<9qeH>t?Rhx2{sI_J;dpT7WXU?&2DA@#XtWh$=i6yHjz)(&LmC~di- zB0XD4w`LuSg6&xur7e7U-25|wFvI8>zu;DhJ4Nd-cP8?RVL*v;rNotBSWip0Xn73> zr!FsxOX;3l1+F+b(ad@23g5{|07@|oX6&NFRn;YikGE&oPPbz6V@`EzcFE85an(_F zS!8X`&XvTT<4DDoEgg?xtEbya}-Os!CqkloQeRZ`+Qob{Rs6WR@ZP zP8LKIA;e4!!DNV~ZATnb%Q@kmaPrGAo|buD%5vA%_dpp|pKJ+q9pV?o9GolR{L8sv5pOf zVe;21>dm{+SO6^`b>kJbBG|lPH#*=ZEWGaBhxU5WE-KMWqv?%iWYx`!eOo`1ncjP7 zMK_6IspoWgO1MI*T1Bs!tF@NG9L;%%_8^0yhn-}EZUzQ0NM}FkqjZMpq$f*qm~IxG zjLyEr9~k*c9|lHAYGV*^jHEUt1B~MioeXhIkksHKa;F`}7QbQgJMJzm*YPlf7EP4s zfD!t|8dS5sc|b)#JjJsHeGK#TWzhEm5&`{tx@-K{6@48^1HbY73n|;<9B+_M`o>N2 xv4EUWk}m?vbU+yoDC=0IBG>WKz=zJTCn?{lHs*MfIUX<@c+-d^)hzHf@DJWRy6XS{ literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/repository/Redis/UserRepository.class b/bin/main/xy/SpringBoot2NoSQL/repository/Redis/UserRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..f63522deb3cfed812052c006c3526f693fc4c5e4 GIT binary patch literal 427 zcmbVIy-tEb5S-&z5d^WawDTwN5|s*Lq9#^fFoMz_u;L=zlDk9Yv8+rid;lNHc;6Q_ zv9+1GnZ0Co=i~G39l$Y~W#kl&o|n2ecWlS!BH^$jz3W6fnv3TkZmGL8Vy|yKx$du7 zMnR!5F^@)1jUDT&!GwlEp>)EQ!>K}kXSc6VxR4Q5kjH8jMU)ik30vwcW&?6JW-uj% zW+Fo~?Hk9b{x%EYp1ndV`NwK)g-TBrZb+A$25kP_{2*OgVXM2afoIfb&oTGRS_vkw z*ciK?h#PC4RdVOdjGn|jXdlRtgyo!KBR}P|v5k0aY!i`HdSt|MR65f@aqkr?FVV=M c5-}YEHLOLfX76I;S~g$Lu#QIL^xp>X1sT$BrT_o{ literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/repository/Solr/SolrCustomerRepository.class b/bin/main/xy/SpringBoot2NoSQL/repository/Solr/SolrCustomerRepository.class new file mode 100644 index 0000000000000000000000000000000000000000..0b8efdb9223e0c3e999db5d4cde7b892d5284b16 GIT binary patch literal 549 zcmbtRJx{|x4E2?d(DEU~%E|x>Cm|*db!Y`s)Cw{%AI&vfN#e?P0s0^Mix~I;{3wKz zw4_1|l^A?F+w$}Cd!JwL9{_L(2LZGMT)oX?G$orSJw$&o!00ZNWTxn>N8%o)R6YH| zdCUym|MUXb6mU4vFIuKLPvr1%Vn#lIZ2<}?k*)RLB|wI; zN$cB}cdIU=cOookWNvNB@W-V#%XY*6yrd~$zCyQFMuq=SWqqD2dlxcw6^VA=|SXp4&5bdzqo-Hp4OLP132 zL(~G!;4p|U4nF7$Gw5hiEaUj(gMSC1zWEP0j_2-flQe`6r_;^dbI(2JcYo(=|NQsY z-vD&tvKKWB;)y9So-q_H-L30ZN539F7!ys|m{gLo*gKk(lB2SCgamO%=7oo$X-t}w zL{-w#;=u5joU|Agsd_ps8w~4Wx{(&8jD3&`$+SqnonvCmR*91G4nQN=rWLOpq#Y%o{VbqVMSms55VZ-CR_DPyV-~=qk z3Wj>J=|ExV3_fHt^u!C)gW(wgby&pE7*jO4KRYoj8;7M~Rb~jp^rWOFBtzlvuFzwR zDs+dfvHwXok>yXSvSjpdJ{ejLWi?BgkQ0ijkoDb~rdyJw=$dVub70!ROc~OId|Wri zMJIw%QBkxl^-_E-Zd_8;Ud=KT*{r3kU<_VjhsV2un>guc>1e3x1tutds+}bik>|0| zix(JLHQ5r)lqkDNWcw{fViST44diRTW?GV#q`R%506*qT)Q2!bU6!z!+)JB)c5HT2 z#9=2~9?c@+YBmYy7Ib*Am0@|ceE~0`lk$@QGHh|pD!NEjph&86l82Vas5siI$`i6? zk?}6P;>F7h&DAvoY{PbjC1lE*Oh$X>UB=l+*dz5xRl?%_SESHyoPQsb`#N$s};LWda#GeQqfX6!=@^vmKBW) zGL-OPFGEKW!hu9z;o=3ta)0Kw1E(6O_EV>MB=!l|j{^)#71QN#zt$&D=*ASK{G-?( z@*{?RFZ$?QsWDI+qk7Q<4B$=5=1ETMK#C#}94hZ0u3D6{a!5cA;tboK>ZaB2euSZ` zc=v%+YM(4+p8o!C33wZW)L4u6cTF&?CJj$40z97CG-_0fvE%-1I+&KNc2xtr$;-(M?yd6^$j1x!GrK_O)_vNpodUhZuE z{NfpkP+|!sEhe5-O;bCt|GoDERHYx#8jX6ONftC&ONw(XJLi$vY+CnPSRX; z0ax}62Xmz~l;BnHp@7r)h`LTDOI@cm_^9^6XJ#FZRD~D{JVXL@^?HuWofyrPR%|&b zdAJh8+9!2%Dk9nGYYZzZjm>vFhQ)D9N{;tQ8F%9O<9gOe%6k<)6Pu2ZuekFCv6*Ka zL(m?xmD9?!WJA`isf^59E&m81q#adNllB)z#Bl%@Eew4kES!DU~cPvQMulv&4#))?q#E5;C@f(ALr6TQk@Y z2;~szYm4L{{((XJH;0#gN3=iuGnxZCBX{v?E$nq~gm1q-gE#KtpvRFNwq=P0vLRdc z&b+Ms&McyXky#uYjLbmFBNb3`7|%h^!*sk%I$mbcH5h5nSK~ z+gyB&v-rg3_W+$dPrlBPO=oqJn7@FF6rE4WGez|uq`g#7HMm6YHTcYqN`O|M)B6`> KZ~7>hiSU1w?J_F> literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/utils/ESSearchUtil.class b/bin/main/xy/SpringBoot2NoSQL/utils/ESSearchUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..687e35f57995b63beb22a9bde2956bd7f4c610ea GIT binary patch literal 6584 zcmcIo340XB5q&MKG-x$4NLa)qHdrw@LMt&b2<#wVLY9PrBtQ!?f;h=&w?PAYF*^$@ zayWJpJ0#%ThZCI3xf2|mLx%~rypAH23bBWr&PqlRS!MwCQL;E5pV~E5oM?>3MD+H|JBFp=&am zFjKRpZHa4jGvX{*d4}G}#@GxoM6FDc7e|X$o>)BJJDIi58a!p@9V?NStc^s<;u*&n zk%ys4pL^U9?hfq=nPVm#E1NOQWZKFYWWh@CyupQ$ymvX_-j=5GGd!QmX7YTf9i7;$ zp^IUA9V$BRMmIx?G(tZ2h7nQZhXoPkK|9`uts3rO*iqF&V7!j^;{yzu@`AyrWk@*{ zm_MZ9zOt0NVQa^B^k}%BAy$<|C76y6;sJ(^oXvBl&E42BEcBj!&+>Ai!1K<*f|W{g zdnk&X_>hJN8ID!5UPsb{;5vG-ivrDyJW+5+;d?^^t*lIvmUu=;e^_d5tl$)EA)goq zH1t!NsuB#Js$(|{hBg;}oKrd6O$2OW_9P!qS!ZDMpgTaqGeq5|Bkq`q^HXL{^{@7X%}s}syS&Iy zd{5hvYswh$EqYBT3WgCKPhprsWMv#~XUtS!poTGqM{1`mFuWpRqu58CH&<}T^Bnb1 zh8yc~wMLhp7OGrhP z3oF>@sEeKwUGy}=c!PbU9;Ak67>4fv%w2sMwz`&N0nYFsYlexCZm_-pP{3u^C<%(H z?M|@O)Q0nd(`i~e7hvnigOe z(;lyw$Wnu(4dTfW_r%{TTtrdBC92@coYa}DV^PGYH7~cAA`G9>@o5o;)_k^LC%7oy z&+0gYXBo0#y)#spwf(PA;KSv6jOWB2<9UXim5wR9!3i3^z%W{MX!(wz8pTq9c2Y}L ziBa{*FxF`CR0Efyr{%aS2wt){ey8ZFJV{h((@88GD{y;}VJ1Y#fn9>CfUum%)?pB5 zd(n_!zT&RpB@Nd?_te#9<#k-aR~eqJ%}4G2>hYQKJS>r-SGx0@{B5~trV3Q(n`97< zF4$(COZHJ*#kX{P1K$o`cLG6qHzWcUd@38$g_L9YBpKpCw-tVaFB8=wO6%KIysYCp z`2HG?){j3`&fE7W;_xE%tFFo@k>1W&Je3q%Q+g-f9O9K2Qn-A1(aXb6bo>ZEtt*BG z#X06-`+PfO`iD~~X_H}hXm70<+F$5+6~AQIUw5iZbjg;_A!^g72UmOy$)Es~W0k?I zyi>0dDk}50I(~)UQ6~&BSPyK*BV6(#iq~*c!|y|1^n&55n5yG-{DIcfGj=w;hE0R@ zRRKwge+_@q@n-?tCt$ zNjk5@R94I?mm#vRN1!5gZ|k^?zcQQ*N!>c|k9(9$*`#${wnwVdI_pA%DXMVcAHs!y z)_0*n{4f`yak(`aqqlR0&fr(S-Qu+vJ@i)DOrH#ayXcHQ>(Q@9R|Xv!9b5XAvEg+( zX+o5K#bclg?ewd=1L)X6S8W8ak?x4eR|rUe8hxwS#ITAjB<}|+Y#atm)W^McLbZBKz3rQIMIZu{w2(* z#C&Xe;3f@n)9&VBh|E1kS$HBqs>dVMqeyj;3_gxe(9G@h|4EoKm-JdrSLH-*Pg$q&z1DCjAZ{R=HkH1i6YiUy8g1t=mB!3 ziKw>>Rztm;yWr-xA8ZHGfW~9PIUB+lG6;2lYj L;a>#Mgn$1Z4cLT$ literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/utils/IElasticSearchMapping.class b/bin/main/xy/SpringBoot2NoSQL/utils/IElasticSearchMapping.class new file mode 100644 index 0000000000000000000000000000000000000000..8e31fd37a12324278d753f5b0327ad0cd5b33d23 GIT binary patch literal 325 zcmZvYF-rqM5QX0)n$sA;!b-5$#sSgFE}{^Kikyh;x*5(5o84n?PcDDW!XMy|5_gk; zO`4g3d31GvIrfgXXoC6{$Dt{QtEFCTsRJmoeT+wkPhswNs;iVFJULDh9q z71$vh&DE!3t6arT?{m?SFsvkQB!ug;^QjLN%No$E0IdCD;T?C{yC^R5+wFQ7x5myS z+z>_yGI2BMUY4~GjuYnJsf_u`q{>#W5*p(j;dHCjW}U^QZ-bV5V-xUXYov?pF(457 b=`lb*CEUdTIcb5tRo}-jZ3qXc_AvSb{mfm3 literal 0 HcmV?d00001 diff --git a/bin/main/xy/SpringBoot2NoSQL/utils/RandomUtil.class b/bin/main/xy/SpringBoot2NoSQL/utils/RandomUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..526b58d97d208e43af9c510d0f97101be529fddf GIT binary patch literal 2792 zcmb_eTTfJ16#n+i!5M}@ab!@rsfaq<5dkk$T0m5AxX4umtq0}+M`q3$XU-tnCQTdD zrzTC4+9vHoW7^ago7g^#M6AB|u|J?srP`U{!TKik;Ti+Uf zdhzfvfJVIQf>L{E9FVWN;T33F@8-Yw=^gHA&-mF!ziYq*w!EPmy45P+3{;E=C>>@<^T3IG zFY>TmU|Uc(wBAHyQi~0#lVMH9Z%(P<5jCdEb$U~=X7#wh!QkuUnEBc|qZwLEwX{?Q z1^j`oij9eNp;(~c)qJ-nrl+--2SvztVNZrG$z+;H4@!~mK^e+j*q=GK=}bN6#Q_{- z>|xEAv1aYqyQEFPiwabdY(rbHx(w2;5EhThQ0+wxYH2eytH#>WCmj+)y%&ekz!NnZ z)r^opQJ`aEC@IV>(xB0cCNvAUEi)5+eqf^ovn09%9PvqkT^mx9_Qz*qcI~d#<+?OT z4?1ge&{C)7demr|tL>TG_vi~506Q{!LG!v6OYM3f(B?%e3S|O1yf`IM=UAqFr$ddi z7*_3u8T_hU8P0fdHhtSZN!|8kUb(2nR%7>B=4pK)6tua>;3)`nZ&nWyNRJo2=p#w< zQfhtEvUa*RNuPv&-is~?zX*epr6Gapz=l+|Y&1@1*9A(VaIO3X5{9Kmw9bVoEo$ke z;lc%hoonYQ^z8{f9MWQLP{Y~F_dopY_WkAWKKEc06H-){B;ZXzjK~{rOPE&#iZ=@> z?YPAamW1!wkN1{8`s~-mhri!`vi$H{PNaj7bU}$4 zt1R%RU)*9uPw(;3AC^D<nc!lHd|b z`Q6*&Y`u%!RX%sM&z;1+Bn~A}l|EvG0cytDF*izD}G=!AT%kk5e*-Pl27`P}m( zz;8Wv+5jq3kFdQRggow?KntVxvCX}~QzuUHMlKvL;CG?Og;L=sVv7Cs z5$C)%;xb~{PZZ_Edw__`iTKd}gZRx=#0^9)xo{UQ;;kgwW!fBe+EN@ftmDX?PEj^G z|IPmNtM(^1wP$}xXY4(`CJSv}hGXZ+yU4A|tGD@dh+^{j*UNksuyDXm>1LbCMK_u3 zLNS8&Lwi%sR=M1r=F&qBC4&x|K@S|ykxK?eHtFlexipxc=~?=oNQ3DuT}1GNQoLIs zX`wISuSriA(VxV?=v`DSVR&o_qhmf6=6GommwjpyQ^iS4`*co{n0tWmlN#w^V6^6? zx|I9^V;nDHE5=#=6Xf?2DsdV8xWb;Gu48)w5g5ErbTI8m+!(T>bJDsOQC7KPN9UE% zRoeAgc7X9+Lo5}aU^B3_(4P@fy=-et zy(7fZgg8}Yv54ZtJ#WW2VCSNrJC+QQ@h2D~f9}ciysg0;Dj=mnKP|5FRH5fQEO3@Z kpGCOAnUfhQu~VAv zv@vu97;AWphu@f=D>$>(m0T0HVtWYNN<>I3flJNAUo!LV5Yp*ob01rWNn1wnju8OO8a7 z)9xBQtKm63Pa;x|BE_Bx7f5DMo8_`>Q%ET1RpQc&9|G+nT-=0ZJH~8+cfe$|B=#{$ z=xl6VMfIs-zOE-U3}T2uqxAe~hC>yq>$~s{&KK3$tx$TU?Y_0q&=fT_HOyl{ zYU*ZGsit1Q4Yup3($q6jX)5MCO=ZtpDT<|fJx_4rW69Q#2kj>OV}m|bh@;|0n*8kC>YaD_k-U$eM(9{bM^8G>0~_dx&fIhj(I`T9M)&&e z-_iIpJ=7pfS3V6o%Qn+hlLmC(K%*vXL<_y)&L_y4+qHDx$0mkfu%+$s->|y~vr%yF zCb)KT>sSHTf+w(Fz&(ir1oIR<*Pv6to~I`sYq-1TKDuf!+WQlYYDHjSngiK2qD!Fd zk(MqR`QRY>D5yrVi{NRx9wK|5f_&3YZ<=tJ{@3t0pDE`&s^UCM2uA`rk0H8>^B7`+ z^92m}oX5*KUsQ1p5a;ng&SAW?igOqz1?S6n#pgU#&UsqJd5Sns2Xc;Kd==*y&Iry4 zO!}OOa?YfRGfA9Nft=^?>MG82cujD=jyHVHH_JKCt2i$Z=fyzI8KhQm&R|w>8hFd+ zOqX-csW|6}b0Ls3gX}8K403|g!lK)HaT@zQa>?V8%`1E43UOTxE6p@_V=@kgwx?74iovh~e8n YhGl$C$SZe_W!$4T3}4W0QiCu52O}b#$p8QV literal 0 HcmV?d00001 diff --git a/bin/test/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplicationTests.class b/bin/test/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplicationTests.class new file mode 100644 index 0000000000000000000000000000000000000000..e04d34540ce21a88ef67c511ce142b59498105d8 GIT binary patch literal 664 zcmbV}OG^VW5Xb-7zO>f1zR{Zp!3P+S(u*Rf;Av5`QqSo&wyE2sX0x?^EKh<5KY$-f zoLvjn>dDJYCNuM!*Zaro8-N6EMBwEBD_8|S0bpFIc>n+a literal 0 HcmV?d00001 diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..1edb447 --- /dev/null +++ b/build.gradle @@ -0,0 +1,49 @@ +buildscript { + ext { + springBootVersion = '2.0.5.RELEASE' + } + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") + } +} + +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + +group = 'xy' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + + +dependencies { + + compile('org.springframework.boot:spring-boot-starter-cache') + compile('org.springframework.boot:spring-boot-starter-data-cassandra') + compile('org.springframework.boot:spring-boot-starter-data-couchbase') + compile('org.springframework.boot:spring-boot-starter-data-elasticsearch') + compile('org.springframework.boot:spring-boot-starter-data-mongodb') + compile('org.springframework.boot:spring-boot-starter-data-neo4j') + compile('org.springframework.boot:spring-boot-starter-data-redis') + compile('org.springframework.boot:spring-boot-starter-data-solr') + + compile group: 'net.sf.ehcache', name: 'ehcache', version: '2.10.5' + compile group: 'org.redisson', name: 'redisson', version: '3.7.5' + //compile group: 'org.springframework.data', name: 'spring-data-hadoop', version: '2.5.0.RELEASE' + + //compile('org.springframework.boot:spring-boot-starter-freemarker') + //compile('org.springframework.boot:spring-boot-starter-thymeleaf') + compile('org.springframework.boot:spring-boot-starter-web') + compile('org.springframework.kafka:spring-kafka') + runtime('org.springframework.boot:spring-boot-devtools') + + testCompile('org.springframework.boot:spring-boot-starter-test') +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..1ce6e58f1ce8ae3a3be37719a2180b5567cea91d GIT binary patch literal 54711 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..5bf251c --- /dev/null +++ b/mvnw @@ -0,0 +1,225 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +echo $MAVEN_PROJECTBASEDIR +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..019bd74 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,143 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/myCache.ehcache/users.data b/myCache.ehcache/users.data new file mode 100644 index 0000000..e69de29 diff --git a/myCache.ehcache/users.index b/myCache.ehcache/users.index new file mode 100644 index 0000000000000000000000000000000000000000..711006c3d3b5c6d50049e3f48311f3dbe372803d GIT binary patch literal 4 LcmZ4UmVp%j1%Lsc literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..25c6c15 --- /dev/null +++ b/pom.xml @@ -0,0 +1,117 @@ + + + 4.0.0 + + xy + SpringBoot2NoSQL + 0.0.1-SNAPSHOT + jar + + SpringBoot2NoSQL + NoSQL for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.5.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.boot + spring-boot-starter-cache + + + org.springframework.boot + spring-boot-starter-data-cassandra + + + org.springframework.boot + spring-boot-starter-data-couchbase + + + org.springframework.boot + spring-boot-starter-data-elasticsearch + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-data-neo4j + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter-data-solr + + + org.springframework.boot + spring-boot-starter-freemarker + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 1.3.2 + + + org.springframework.kafka + spring-kafka + + + + org.springframework.boot + spring-boot-devtools + runtime + + + mysql + mysql-connector-java + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..531f3fb --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'SpringBoot2NoSQL' diff --git a/src/main/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplication.java b/src/main/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplication.java new file mode 100644 index 0000000..0b916bf --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplication.java @@ -0,0 +1,17 @@ +package xy.SpringBoot2NoSQL; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableCaching +@EnableScheduling +@SpringBootApplication +public class SpringBoot2NoSqlApplication { + + public static void main(String[] args) { + System.setProperty("es.set.netty.runtime.available.processors", "false"); + SpringApplication.run(SpringBoot2NoSqlApplication.class, args); + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/config/CassandraConfig.java b/src/main/java/xy/SpringBoot2NoSQL/config/CassandraConfig.java new file mode 100644 index 0000000..78f601b --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/config/CassandraConfig.java @@ -0,0 +1,45 @@ +package xy.SpringBoot2NoSQL.config; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.data.cassandra.config.AbstractCassandraConfiguration; +import org.springframework.data.cassandra.config.CassandraClusterFactoryBean; +import org.springframework.data.cassandra.core.mapping.BasicCassandraMappingContext; +import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; +import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; + +@Configuration +@PropertySource(value = { "classpath:cassandra.properties" }) +@EnableCassandraRepositories(basePackages = "xy.SpringBoot2NoSQL.repository.Cassandra") +public class CassandraConfig extends AbstractCassandraConfiguration { + private static final Log LOGGER = LogFactory.getLog(CassandraConfig.class); + + @Autowired + private Environment environment; + + @Override + protected String getKeyspaceName() { + return environment.getProperty("cassandra.keyspace"); + } + + @Override + @Bean + public CassandraClusterFactoryBean cluster() { + final CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); + cluster.setContactPoints(environment.getProperty("cassandra.contactpoints")); + cluster.setPort(Integer.parseInt(environment.getProperty("cassandra.port"))); + LOGGER.info("Cluster created with contact points [" + environment.getProperty("cassandra.contactpoints") + "] " + "& port [" + Integer.parseInt(environment.getProperty("cassandra.port")) + "]."); + return cluster; + } + + @Override + @Bean + public CassandraMappingContext cassandraMapping() throws ClassNotFoundException { + return new BasicCassandraMappingContext(); + } +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/config/RedissonConfig.java b/src/main/java/xy/SpringBoot2NoSQL/config/RedissonConfig.java new file mode 100644 index 0000000..63ea866 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/config/RedissonConfig.java @@ -0,0 +1,263 @@ +package xy.SpringBoot2NoSQL.config; + +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.client.codec.Codec; +import org.redisson.config.Config; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.ClassUtils; + +import io.netty.channel.nio.NioEventLoopGroup; + +/** + * redisson 客户端配置,而不是使用spring data redis + * 这里配置连接的模式是单机模式,如想配置集群模式和哨兵模式,请参考官方wiki + * https://github.com/redisson/redisson/wiki/ + */ +@ConfigurationProperties(prefix = "spring.redisson") +@Configuration +public class RedissonConfig{ + + private String address; + private int connectionMinimumIdleSize = 10; + private int idleConnectionTimeout=10000; + private int pingTimeout=1000; + private int connectTimeout=10000; + private int timeout=3000; + private int retryAttempts=3; + private int retryInterval=1500; + private int reconnectionTimeout=3000; + private int failedAttempts=3; + private String password = null; + private int subscriptionsPerConnection=5; + private String clientName=null; + private int subscriptionConnectionMinimumIdleSize = 1; + private int subscriptionConnectionPoolSize = 50; + private int connectionPoolSize = 64; + private int database = 0; + private boolean dnsMonitoring = false; + private int dnsMonitoringInterval = 5000; + + private int thread; //当前处理核数量 * 2 + + private String codec="org.redisson.codec.JsonJacksonCodec"; + + @Bean(destroyMethod = "shutdown") + @ConditionalOnProperty(name="spring.redisson.address") + RedissonClient redisson() throws Exception { + Config config = new Config(); + config.useSingleServer().setAddress(address) + .setConnectionMinimumIdleSize(connectionMinimumIdleSize) + .setConnectionPoolSize(connectionPoolSize) + .setDatabase(database) + .setDnsMonitoringInterval(dnsMonitoringInterval) + .setSubscriptionConnectionMinimumIdleSize(subscriptionConnectionMinimumIdleSize) + .setSubscriptionConnectionPoolSize(subscriptionConnectionPoolSize) + .setSubscriptionsPerConnection(subscriptionsPerConnection) + .setClientName(clientName) + .setRetryAttempts(retryAttempts) + .setRetryInterval(retryInterval) + .setTimeout(timeout) + .setConnectTimeout(connectTimeout) + .setIdleConnectionTimeout(idleConnectionTimeout) + .setPingTimeout(pingTimeout) + .setPassword(password); + Codec codec=(Codec)ClassUtils.forName(getCodec(),ClassUtils.getDefaultClassLoader()).newInstance(); + config.setCodec(codec); + config.setThreads(thread); + config.setEventLoopGroup(new NioEventLoopGroup()); + return Redisson.create(config); + } + + /** + * 哨兵模式自动装配 + * @return + */ +// @Bean +// @ConditionalOnProperty(name="redisson.master-name") +// RedissonClient redissonSentinel() { +// Config config = new Config(); +// SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redssionProperties.getSentinelAddresses()) +// .setMasterName(redssionProperties.getMasterName()) +// .setTimeout(redssionProperties.getTimeout()) +// .setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize()) +// .setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize()); +// +// if(StringUtils.isNotBlank(redssionProperties.getPassword())) { +// serverConfig.setPassword(redssionProperties.getPassword()); +// } +// return Redisson.create(config); +// } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public int getConnectionMinimumIdleSize() { + return connectionMinimumIdleSize; + } + + public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) { + this.connectionMinimumIdleSize = connectionMinimumIdleSize; + } + + public int getIdleConnectionTimeout() { + return idleConnectionTimeout; + } + + public void setIdleConnectionTimeout(int idleConnectionTimeout) { + this.idleConnectionTimeout = idleConnectionTimeout; + } + + public int getPingTimeout() { + return pingTimeout; + } + + public void setPingTimeout(int pingTimeout) { + this.pingTimeout = pingTimeout; + } + + public int getConnectTimeout() { + return connectTimeout; + } + + public void setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public int getRetryAttempts() { + return retryAttempts; + } + + public void setRetryAttempts(int retryAttempts) { + this.retryAttempts = retryAttempts; + } + + public int getRetryInterval() { + return retryInterval; + } + + public void setRetryInterval(int retryInterval) { + this.retryInterval = retryInterval; + } + + public int getReconnectionTimeout() { + return reconnectionTimeout; + } + + public void setReconnectionTimeout(int reconnectionTimeout) { + this.reconnectionTimeout = reconnectionTimeout; + } + + public int getFailedAttempts() { + return failedAttempts; + } + + public void setFailedAttempts(int failedAttempts) { + this.failedAttempts = failedAttempts; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getSubscriptionsPerConnection() { + return subscriptionsPerConnection; + } + + public void setSubscriptionsPerConnection(int subscriptionsPerConnection) { + this.subscriptionsPerConnection = subscriptionsPerConnection; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public int getSubscriptionConnectionMinimumIdleSize() { + return subscriptionConnectionMinimumIdleSize; + } + + public void setSubscriptionConnectionMinimumIdleSize(int subscriptionConnectionMinimumIdleSize) { + this.subscriptionConnectionMinimumIdleSize = subscriptionConnectionMinimumIdleSize; + } + + public int getSubscriptionConnectionPoolSize() { + return subscriptionConnectionPoolSize; + } + + public void setSubscriptionConnectionPoolSize(int subscriptionConnectionPoolSize) { + this.subscriptionConnectionPoolSize = subscriptionConnectionPoolSize; + } + + public int getConnectionPoolSize() { + return connectionPoolSize; + } + + public void setConnectionPoolSize(int connectionPoolSize) { + this.connectionPoolSize = connectionPoolSize; + } + + public int getDatabase() { + return database; + } + + public void setDatabase(int database) { + this.database = database; + } + + public boolean isDnsMonitoring() { + return dnsMonitoring; + } + + public void setDnsMonitoring(boolean dnsMonitoring) { + this.dnsMonitoring = dnsMonitoring; + } + + public int getDnsMonitoringInterval() { + return dnsMonitoringInterval; + } + + public void setDnsMonitoringInterval(int dnsMonitoringInterval) { + this.dnsMonitoringInterval = dnsMonitoringInterval; + } + + public int getThread() { + return thread; + } + + public void setThread(int thread) { + this.thread = thread; + } + + public String getCodec() { + return codec; + } + + public void setCodec(String codec) { + this.codec = codec; + } + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/Cassandra/CassandraController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/Cassandra/CassandraController.java new file mode 100644 index 0000000..848d389 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/Cassandra/CassandraController.java @@ -0,0 +1,76 @@ +package xy.SpringBoot2NoSQL.controller.Cassandra; + +import java.util.List; +import java.util.Optional; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import xy.SpringBoot2NoSQL.model.Cassandra.Customer; +import xy.SpringBoot2NoSQL.repository.Cassandra.CustomerRepository; + + + +@RestController +@RequestMapping("/cassandra") +public class CassandraController { + + Logger logger = LogManager.getLogger(getClass()); + + @Autowired + CustomerRepository customerRepository; + + @RequestMapping("/add") + public String add(){ + customerRepository.deleteAll(); + + Customer cust_1 = new Customer("Test1", "Test1", "Test1", 20); + Customer cust_2 = new Customer("Test2", "Test2", "Test2", 25); + Customer cust_3 = new Customer("Test3", "Test3", "Test3", 30); + Customer cust_4 = new Customer("Test4", "Test4", "Test4", 35); + Customer cust_5 = new Customer("Test5", "Test5", "Test5", 40); + Customer cust_6 = new Customer("Test6", "Test6", "Test6", 45); + + customerRepository.save(cust_1); + customerRepository.save(cust_2); + customerRepository.save(cust_3); + customerRepository.save(cust_4); + customerRepository.save(cust_5); + customerRepository.save(cust_6); + + return "ok"; + } + + + @RequestMapping("/all") + public Iterable getAll(){ + + return customerRepository.findAll(); + } + + @RequestMapping("/getByID/{id}") + public Optional getByID(@PathVariable("id") String id){ + + return customerRepository.findById(id); + } + + @RequestMapping("/getByName/{name}") + public List getByName(@PathVariable("name") String name){ + + return customerRepository.findByLastname(name); + + } + + @RequestMapping("/getByAge/{age}") + public List getByAge(@PathVariable("age") String age){ + + return customerRepository.findByAgeGreaterThan(Integer.valueOf(age)); + + } + + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/Couchbase/CouchbaseController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/Couchbase/CouchbaseController.java new file mode 100644 index 0000000..676c2b9 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/Couchbase/CouchbaseController.java @@ -0,0 +1,53 @@ +//package xy.SpringBoot2NoSQL.controller.Couchbase; +// +//import java.util.Arrays; +//import java.util.List; +//import java.util.Optional; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.PathVariable; +//import org.springframework.web.bind.annotation.RequestMapping; +//import org.springframework.web.bind.annotation.RestController; +// +//import xy.SpringBoot2NoSQL.model.Couchbase.Customer; +//import xy.SpringBoot2NoSQL.repository.Couchbase.CouchbaseCustomerRepository; +// +//@RestController +//@RequestMapping("/couchbase") +//public class CouchbaseController { +// +// @Autowired +// CouchbaseCustomerRepository couchbaseCustomerRepository; +// +// @RequestMapping("/add") +// public String add(){ +// +// couchbaseCustomerRepository.deleteAll(); +// couchbaseCustomerRepository.saveAll(Arrays.asList(new Customer("01", "Jack", "Smith"), +// new Customer("02", "Adam", "Johnson"), +// new Customer("03", "Kim", "Smith"), +// new Customer("04", "David", "Williams"), +// new Customer("05", "Peter", "Davis"))); +// +// return "ok"; +// } +// +// @RequestMapping("/all") +// public Iterable getAll(){ +// +// return couchbaseCustomerRepository.findAll(); +// } +// +// @RequestMapping("/getByID/{id}") +// public Optional getByID(@PathVariable("id") String id){ +// +// return couchbaseCustomerRepository.findById(id); +// } +// +// @RequestMapping("/findByLastName/{name}") +// public List findByLastName(@PathVariable("name") String name){ +// +// return couchbaseCustomerRepository.findByLastName(name); +// } +// +//} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/Ehcache/EhcacheDataController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/Ehcache/EhcacheDataController.java new file mode 100644 index 0000000..43544bb --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/Ehcache/EhcacheDataController.java @@ -0,0 +1,64 @@ +package xy.SpringBoot2NoSQL.controller.Ehcache; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import net.sf.ehcache.CacheManager; +import xy.SpringBoot2NoSQL.model.User; +import xy.SpringBoot2NoSQL.service.Ehcache.UserService; + +@RestController +@RequestMapping("/ehcache") +public class EhcacheDataController { + + Logger logger = LogManager.getLogger(getClass()); + + @Autowired + UserService userService; + + @Autowired + private CacheManager cacheManager; + + /** + * 创建100个测试用户 + * @return + */ + @RequestMapping("/users") + public List getUsers(){ + + logger.info("using cache manager: " + cacheManager.getClass().getName()); + + userService.clearCache(); + + //新建对象 + List users = new ArrayList(); + for (int i=0;i<100;i++){ + users.add(userService.getUser("test"+i)); + } + + for (int i=0;i<100;i++){ + //测试获取对象是否是经过缓存 + userService.getUser("test"+i); + } + + return users; + } + + /** + * 获取测试用户,看看是否经过缓存 + * @return + */ + @RequestMapping("/user/{name}") + public User getUser(@PathVariable("name") String name){ + return userService.getUser(name); + + } + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESDataController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESDataController.java new file mode 100644 index 0000000..5a71565 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESDataController.java @@ -0,0 +1,186 @@ +package xy.SpringBoot2NoSQL.controller.ElasticSearch; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.elasticsearch.action.ActionFuture; +import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; +import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.health.ClusterHealthStatus; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.SearchQuery; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xy.SpringBoot2NoSQL.model.ElasticSearch.Product; +import xy.SpringBoot2NoSQL.repository.ElasticSearch.SampleProductRepository; + +@RestController +@RequestMapping("/es") +public class ESDataController { + + @Autowired + private ElasticsearchOperations elasticsearchOperations; + + @Autowired + SampleProductRepository sampleProductRepository; + + @Autowired + private ElasticsearchTemplate elasticsearchTemplate; + + //服务情况查询 + @GetMapping("details") + public ResponseEntity> getElasticInformation() { + + Client client = elasticsearchOperations.getClient(); + Map asMap = client.settings().getAsMap(); + return ResponseEntity.ok(asMap); + } + + //健康检查 + @GetMapping("checkHealth") + public String checkHealth() { + + return getHealth(); + } + + @GetMapping("insertProduct") + public Product insert() { + Product product = new Product("1", "测试产品1", "测试产品111111.", true); + return sampleProductRepository.save(product); + } + + @GetMapping("insertProductMore") + public String insertProductMore() { + + List productList = new ArrayList(); + + for (int i = 0; i < 100; i++) { + Product product = new Product(String.valueOf(i), "测试产品" + i, "测试产品描述.", true); + productList.add(product); + } + + // 只需要执行一次批量 + sampleProductRepository.saveAll(productList); + + return "success"; + } + + @GetMapping("insertProduct2/{id}/{name}") + public Product insert2(@PathVariable String name, @PathVariable String id) { + Product product = new Product(id, name, name + "产品描述.", true); + return sampleProductRepository.save(product); + } + + @GetMapping("findByNameProducts/{name}") + public List findByNameProducts(@PathVariable String name) { + List list = sampleProductRepository.findByName(name); + return list; + } + + @GetMapping("findByNameAndIdProducts/{name}/{id}") + public List findByNameAndIdProducts(@PathVariable String name, @PathVariable String id) { + List list = sampleProductRepository.findByNameAndId(name, id); + return list; + } + + @GetMapping("findByNameProductsPage/{name}/{page}/{size}") + public List findByNameProductsPage(@PathVariable String name, @PathVariable int page, + @PathVariable int size) { + List list = sampleProductRepository.findByName(name, PageRequest.of(page, size)); + return list; + } + + @GetMapping("count") + public long CountAllElementsInIndex() { + + long count = sampleProductRepository.count(); + return count; + } + + @GetMapping("searchQueries/{id}/{name}/{page}/{size}") + public Page SearchQueries(@PathVariable String name, @PathVariable String id, @PathVariable int page, + @PathVariable int size) { + + BoolQueryBuilder bqb = QueryBuilders.boolQuery(); + bqb.must(QueryBuilders.termQuery("name", name)); + //bqb.must(QueryBuilders.rangeQuery("id").gt(id));// 大于 + + SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(bqb).withPageable(PageRequest.of(page, size)) + .build(); + + Page products = sampleProductRepository.search(searchQuery); + return products; + } + + //根据id删除 + public boolean deleteById(String id) { + try { + elasticsearchTemplate.delete(getEntityClass(), id); + return true; + } catch (Exception e) { + return false; + } + } + + //根据条件删除 + public boolean deleteByQuery(Map filedContentMap) { + try { + DeleteQuery dq = new DeleteQuery(); + + BoolQueryBuilder query=QueryBuilders. boolQuery(); + if(filedContentMap!=null) + for (String key : filedContentMap.keySet()) {//字段查询 + query.must(QueryBuilders.matchQuery(key,filedContentMap.get(key))); + } + dq.setQuery(query); + elasticsearchTemplate.delete(dq, getEntityClass()); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + + //健康检查 + public String getHealth() { + try { + Client client = elasticsearchOperations.getClient(); + ActionFuture health = client.admin() + .cluster().health(new ClusterHealthRequest()); + ClusterHealthStatus status = health.actionGet().getStatus(); + if (status.value() == ClusterHealthStatus.RED.value()) { + return "red"; + } + if (status.value() == ClusterHealthStatus.GREEN.value()) { + return "green"; + } + if (status.value() == ClusterHealthStatus.YELLOW.value()) { + return "yellow"; + } + return "unknow"; + } catch (Exception e) { + + return "unknow"; + } + } + + private Class getEntityClass() { + + return Product.class; + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESSearchController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESSearchController.java new file mode 100644 index 0000000..2e6eaeb --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/ElasticSearch/ESSearchController.java @@ -0,0 +1,67 @@ +package xy.SpringBoot2NoSQL.controller.ElasticSearch; + +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import xy.SpringBoot2NoSQL.model.ElasticSearch.Product; +import xy.SpringBoot2NoSQL.repository.ElasticSearch.SampleProductRepository; +import xy.SpringBoot2NoSQL.utils.ESSearchUtil; + +@RestController +@RequestMapping("/essearch") +public class ESSearchController { + + @Autowired + SampleProductRepository sampleProductRepository; + + @GetMapping("search") + public Page search() { + + return sampleProductRepository.search(getBoolQuery(), PageRequest.of(0, 5)); + } + + @GetMapping("searchAll/{page}") + public Page searchAll(@PathVariable int page) { + + return sampleProductRepository.search(ESSearchUtil.matchAllQuery(), PageRequest.of(page, 5)); + } + + @GetMapping("searchProduct/{key}/{value}/{searchtype}") + public Page searchProduct(@PathVariable String key,@PathVariable String value, @PathVariable String searchtype) { + Page products = null; + + if (searchtype.equals("matchQuery")) { + products = sampleProductRepository.search(ESSearchUtil.matchQuery(key, value), PageRequest.of(0, 5)); + } + + if (searchtype.equals("matchPhraseQuery")) { + products = sampleProductRepository.search(ESSearchUtil.matchPhraseQuery(key, value), PageRequest.of(0, 5)); + } + + if (searchtype.equals("fuzzyQuery")) { + products = sampleProductRepository.search(ESSearchUtil.fuzzyQuery(key, value), PageRequest.of(0, 5)); + } + + if (searchtype.equals("termsQuery")) { + products = sampleProductRepository.search(ESSearchUtil.termsQuery(key, value), PageRequest.of(0, 5)); + } + + return products; + } + + public QueryBuilder getBoolQuery() { + + return QueryBuilders.boolQuery() + .must(QueryBuilders.matchPhraseQuery("name", "测试产品1")) + //.mustNot(QueryBuilders.termQuery("enabled", true)); + .must(QueryBuilders.matchPhraseQuery("enabled", true)); + } + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/Mongo/MongoDataController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/Mongo/MongoDataController.java new file mode 100644 index 0000000..e9e9c4e --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/Mongo/MongoDataController.java @@ -0,0 +1,110 @@ +package xy.SpringBoot2NoSQL.controller.Mongo; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import xy.SpringBoot2NoSQL.model.Mongo.Department; +import xy.SpringBoot2NoSQL.model.Mongo.Location; +import xy.SpringBoot2NoSQL.model.Mongo.Person; +import xy.SpringBoot2NoSQL.repository.Mongo.DepartmentRepository; +import xy.SpringBoot2NoSQL.repository.Mongo.PersonRepository; + +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/mongo") +public class MongoDataController { + + @Autowired + PersonRepository personRepository; + @Autowired + DepartmentRepository departmentRepository; + + @RequestMapping("/persons/{name}") + public Person getPerson(@PathVariable("name") String name){ + return personRepository.findByName(name); + } + + @GetMapping("findAll") + public List getUserList() { + List userInfoList = personRepository.findAll(); + return userInfoList; + } + + @GetMapping("query1") + public Person q1(String name){ + return personRepository.findByName(name); + } + + @GetMapping("query2") + public List q2(Integer age){ + return personRepository.withQueryFindByAge(age); + } + + @GetMapping("delete") + public String delete(String id) { + personRepository.deleteById(id); + return "success"; + } + + @DeleteMapping("/colleagues/{name}") + public ResponseEntity deleteColleague(@PathVariable String name){ + Person person = personRepository.findByName(name); + if(person!=null) { + personRepository.delete(person); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + + @GetMapping("insert") + public Person insert(Long id, String username, String password) { + Person user = new Person("test2",22); + return personRepository.insert(user); + } + + //要先执行添加部门的操作 + @RequestMapping("saveDepartment") + public Department saveDepartment(){ + Department d = new Department("abc001","研发部"); + return departmentRepository.save(d); + } + + //执行这个之前要先执行”saveDepartment“,因为需要一个部门的引用 + @RequestMapping("save") + public Person save(){ + Person p = new Person("王昕",32); + Collection locations = new LinkedHashSet(); + Location loc1 = new Location("上海","2009"); + Location loc2 = new Location("广州","2011"); + locations.add(loc1); + locations.add(loc2); + + p.setLocations(locations); + + Department d = departmentRepository.findByName("研发部"); + p.setDepartment(d); + + return personRepository.save(p); + } + + + @PostMapping("/formsave") + public ResponseEntity addColleague(@RequestBody Person person){ + personRepository.save(person); + return new ResponseEntity<>(HttpStatus.CREATED); + } + +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedisDataController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedisDataController.java new file mode 100644 index 0000000..1343cf3 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedisDataController.java @@ -0,0 +1,34 @@ +package xy.SpringBoot2NoSQL.controller.Redis; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import xy.SpringBoot2NoSQL.model.Redis.User; +import xy.SpringBoot2NoSQL.repository.Redis.ObjectRepository; +import xy.SpringBoot2NoSQL.repository.Redis.StringStringRepository; +import xy.SpringBoot2NoSQL.repository.Redis.UserRepository; + +@RestController +@RequestMapping("/redis") +public class RedisDataController { + + @Autowired + ObjectRepository objRepository; + @Autowired + StringStringRepository stringStringRepository; + + @RequestMapping("/add/{name}") + public String getRecognition(@PathVariable("name") String name){ + User user = new User(name,name); + objRepository.save(user); + + return "add success."; + } + + @RequestMapping("/user/{name}") + public User getUser(@PathVariable("name") String name){ + return (User)objRepository.get(name); + + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedissonController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedissonController.java new file mode 100644 index 0000000..110be44 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/Redis/RedissonController.java @@ -0,0 +1,329 @@ +package xy.SpringBoot2NoSQL.controller.Redis; + +import java.util.concurrent.TimeUnit; + +import org.redisson.Redisson; +import org.redisson.api.BatchOptions; +import org.redisson.api.BatchResult; +import org.redisson.api.LocalCachedMapOptions; +import org.redisson.api.RAtomicDouble; +import org.redisson.api.RBatch; +import org.redisson.api.RBloomFilter; +import org.redisson.api.RBoundedBlockingQueue; +import org.redisson.api.RBucket; +import org.redisson.api.RHyperLogLog; +import org.redisson.api.RLocalCachedMap; +import org.redisson.api.RLongAdder; +import org.redisson.api.RMapCache; +import org.redisson.api.RScoredSortedSet; +import org.redisson.api.RedissonClient; +import org.redisson.api.TransactionOptions; +import org.redisson.api.map.event.EntryCreatedListener; +import org.redisson.api.map.event.EntryEvent; +import org.redisson.api.map.event.EntryExpiredListener; +import org.redisson.api.map.event.EntryRemovedListener; +import org.redisson.api.map.event.EntryUpdatedListener; +import org.redisson.config.Config; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.netty.util.concurrent.Future; +import xy.SpringBoot2NoSQL.config.RedissonConfig; +import xy.SpringBoot2NoSQL.model.Redis.User; +import xy.SpringBoot2NoSQL.utils.RedissonUtil; + + +@RestController +@RequestMapping("/redisson") +public class RedissonController { + + // 单Redis节点模式,默认连接地址 127.0.0.1:6379 + RedissonClient redisson = Redisson.create(); + + + /** + * Map 获取 + * @param name + * @param key + * @return + */ + @RequestMapping("/getMap/{name}/{key}") + public String get(@PathVariable("name") String name,@PathVariable("key") String key){ + + String result = (String) redisson.getMap(name).get(key); + + return result; + } + + /** + * 本地缓存(Local Cache)也叫就近缓存(Near Cache)。 + * 这类映射的使用主要用于在特定的场景下,映射缓存(MapCache)上的高度频繁的读取操作, + * 使网络通信都被视为瓶颈的情况。Redisson与Redis通信的同时,还将部分数据保存在本地内存里。这样的设计的好处是它能将读取速度提高最多 45倍 + * @param name + * @param key + * @return + */ + @RequestMapping("/getLocalCachedMap/{name}/{key}") + public String getLocalCachedMap(@PathVariable("name") String name,@PathVariable("key") String key){ + + LocalCachedMapOptions options = LocalCachedMapOptions.defaults() + .evictionPolicy(LocalCachedMapOptions.EvictionPolicy.LFU) + .cacheSize(100) + .syncStrategy(LocalCachedMapOptions.SyncStrategy.UPDATE) //同步缓存 + .timeToLive(10, TimeUnit.SECONDS) + .maxIdle(10, TimeUnit.SECONDS); + + RLocalCachedMap map = redisson.getLocalCachedMap(name,options); + + map.put(key, "测试值"); + + String result = (String)map.get(key); + + return result; + } + + /** + * 元素淘汰功能(Eviction)和事件监听 + * 带有元素淘汰(Eviction)机制的映射类允许针对一个映射中每个元素单独设定 有效时间 和 最长闲置时间 。 + * @param name + * @param key + * @return + */ + @RequestMapping("/getMapCache/{name}/{key}") + public int getMapCache(@PathVariable("name") String name,@PathVariable("key") String key){ + + RMapCache map = redisson.getMapCache(name); + //LRU有界映射设置 + // 将该映射的最大容量限制设定或更改为10 + map.setMaxSize(10); + + map.put(key, 999); + map.put(key+"_TimeTtoLive", 888, 1, TimeUnit.SECONDS);//有效时间1秒 + + int updateListener = map.addListener(new EntryUpdatedListener() { + @Override + public void onUpdated(EntryEvent event) { +// event.getKey(); // 字段名 +// event.getValue(); // 新值 +// event.getOldValue(); // 旧值 + } + }); + + int createListener = map.addListener(new EntryCreatedListener() { + @Override + public void onCreated(EntryEvent event) { +// event.getKey(); // 字段名 +// event.getValue(); // 值 + } + }); + + int expireListener = map.addListener(new EntryExpiredListener() { + @Override + public void onExpired(EntryEvent event) { +// event.getKey(); // 字段名 +// event.getValue(); // 值 + + } + }); + + int removeListener = map.addListener(new EntryRemovedListener() { + @Override + public void onRemoved(EntryEvent event) { +// event.getKey(); // 字段名 +// event.getValue(); // 值 + } + }); + + map.removeListener(updateListener); + map.removeListener(createListener); + map.removeListener(expireListener); + map.removeListener(removeListener); + try { + Thread.sleep(200);//如果改成1000以上,则无法取出映射的值,因为已删除 + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + int result = map.get(key+"_TimeTtoLive"); + return result; + } + + + /** + * 设置分布式对象桶(Object Bucket) + * @param key + * @param name + * @param value + * @return + */ + @RequestMapping("/setObjectBucket/{key}") + public String setObjectBucket(@PathVariable("key") String key){ + + RBucket bucket = redisson.getBucket(key); + bucket.set(new User("wangxin","王昕")); + + return "objectBucket set success."; + } + + @RequestMapping("/getBucket/{key}") + public User getBucket(@PathVariable("key") String key){ + + User user = (User) RedissonUtil.getRBucket(redisson, key).get(); + + return user; + } + + + /** + * 分布式基数估计算法 + * @param key + * @return + */ + @RequestMapping("/hyperLogLog/{key}") + public Long hyperLogLog(@PathVariable("key") String key){ + + RHyperLogLog log = redisson.getHyperLogLog(key); + + log.add(1); + log.add(2); + log.add(3); + + Long count =log.count(); + + return count; + } + + + /** + * 分布式整长型累加器 + * 基于Redis的Redisson分布式整长型累加器采用了与java.util.concurrent.atomic.LongAdder类似的接口。 + * 通过利用客户端内置的LongAdder对象,为分布式环境下递增和递减操作提供了很高得性能。 + * 据统计其性能最高比分布式AtomicLong对象快 12000 倍。完美适用于分布式统计计量场景。 + * @param key + * @return + */ + @RequestMapping("/longAdder/{key}") + public Long longAdder(@PathVariable("key") String key){ + + RLongAdder atomicLong = redisson.getLongAdder(key); + atomicLong.add(12); + atomicLong.increment(); + atomicLong.increment(); + atomicLong.decrement(); + + Long count =atomicLong.sum(); + + return count; + } + + /** + * 分布式原子双精度浮点 + * 分布式原子双精度浮点RAtomicDouble,弥补了Java自身的不足 + * @param key + * @return + */ + @RequestMapping("/atomicDouble/{key}") + public double atomicDouble(@PathVariable("key") String key){ + + RAtomicDouble atomicDouble = redisson.getAtomicDouble(key); + atomicDouble.set(123.11); + atomicDouble.addAndGet(4.25); + + double value = atomicDouble.get(); + + return value; + } + + /** + * 异步批量执行 + * @param key + * @return + */ + @RequestMapping("/batch") + public String batch(){ + + RBatch batch = redisson.createBatch(BatchOptions.defaults()); + //RTransaction RTransaction = redisson.createTransaction(TransactionOptions.defaults()) + batch.getMap("test").fastPutAsync("1", "2"); + batch.getMap("test").fastPutAsync("2", "3"); + batch.getMap("test").putAsync("2", "新的值"); + + // 将写入操作同步到从节点 + // 同步到2个从节点,等待时间为1秒钟 + //batch.syncSlaves(2, 1, TimeUnit.SECONDS); + + BatchResult res = batch.execute(); + + return res.getResponses().toString(); + } + + + + /** + * 计分排序集(ScoredSortedSet) + * @return + */ + @RequestMapping("/scoredSortedSet") + public String ScoredSortedSet(){ + + RScoredSortedSet set = redisson.getScoredSortedSet("scoredSortedSet"); + set.clear(); + + set.add(3.13, new User("Tom","Tom name")); + set.addAsync(0.123, new User("Dog","Dog name")); + + User user = new User("Cat","Cat name"); + set.add(4.67, user); + set.addScore(user, 0.1); //加分 + + int index = set.rank(user); // 获取元素在集合中的位置 + + Double score = set.getScore(user); // 获取元素的评分 + + return "位置:"+index +",分数:"+score; + } + + + /** + * 有界阻塞队列(Bounded Blocking Queue) + * @return + */ + @RequestMapping("/boundedBlockingQueue") + public String BoundedBlockingQueue(){ + + RBoundedBlockingQueue queue = redisson.getBoundedBlockingQueue("anyQueue"); + queue.clear(); + // 如果初始容量(边界)设定成功则返回`真(true)`, + // 如果初始容量(边界)已近存在则返回`假(false)`。 + queue.trySetCapacity(2); + + queue.offer(new User("Tom","Tom name")); + queue.offer(new User("Cat","Cat name")); + //此时容量已满,add方法会直接阻塞 + //queue.add(new User("Cat2","Cat2 name")); + // 此时容量已满,下面代码将会被阻塞,直到有空闲为止。 + try { + queue.put(new User("Dog","Dog name")); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + User obj = queue.peek();//获取队列第一个元素,但并不从队列中删除 + User obj2 = null; + try { + obj2 = queue.poll(3, TimeUnit.SECONDS);//获取队列第一个元素,并删除 + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + User obj3 = queue.poll(); + return obj.getLogin() +","+ obj2.getLogin()+","+ obj3.getLogin(); + } + + + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/controller/Solr/SolrController.java b/src/main/java/xy/SpringBoot2NoSQL/controller/Solr/SolrController.java new file mode 100644 index 0000000..5366aae --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/controller/Solr/SolrController.java @@ -0,0 +1,51 @@ +package xy.SpringBoot2NoSQL.controller.Solr; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import xy.SpringBoot2NoSQL.model.Solr.Customer; +import xy.SpringBoot2NoSQL.repository.Solr.SolrCustomerRepository; + +@RestController +@RequestMapping("/solr") +public class SolrController { + + @Autowired + SolrCustomerRepository customerRepository; + + @RequestMapping("/add") + public String add(){ + + customerRepository.deleteAll(); + customerRepository.saveAll(Arrays.asList(new Customer("1", "Jack", 20), + new Customer("2", "Adam", 24), + new Customer("3", "Kim", 27), + new Customer("4", "David", 30), + new Customer("5", "Peter", 21))); + + return "ok"; + } + + @RequestMapping("/all") + public Iterable getAll(){ + + return customerRepository.findAll(); + } + + @RequestMapping("/getByID/{id}") + public Optional getByID(@PathVariable("id") String id){ + + return customerRepository.findById(id); + } + + @RequestMapping("/findByNameEndsWith/{name}") + public List findByNameEndsWith(@PathVariable("name") String name){ + + return customerRepository.findByNameEndsWith(name); + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/exception/CreateIndexFailedException.java b/src/main/java/xy/SpringBoot2NoSQL/exception/CreateIndexFailedException.java new file mode 100644 index 0000000..8bc5539 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/exception/CreateIndexFailedException.java @@ -0,0 +1,7 @@ +package xy.SpringBoot2NoSQL.exception; + +public class CreateIndexFailedException extends RuntimeException { + public CreateIndexFailedException(String indexName, Throwable cause) { + super(String.format("Creating Index '%s' failed", indexName), cause); + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/exception/GetMappingFailedException.java b/src/main/java/xy/SpringBoot2NoSQL/exception/GetMappingFailedException.java new file mode 100644 index 0000000..1bcfa8d --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/exception/GetMappingFailedException.java @@ -0,0 +1,7 @@ +package xy.SpringBoot2NoSQL.exception; + +public class GetMappingFailedException extends RuntimeException { + public GetMappingFailedException(String indexName, Throwable cause) { + super(String.format("Create Mapping failed for Index '%s'", indexName), cause); + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/exception/IndicesExistsFailedException.java b/src/main/java/xy/SpringBoot2NoSQL/exception/IndicesExistsFailedException.java new file mode 100644 index 0000000..f31c8dd --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/exception/IndicesExistsFailedException.java @@ -0,0 +1,7 @@ +package xy.SpringBoot2NoSQL.exception; + +public class IndicesExistsFailedException extends RuntimeException { + public IndicesExistsFailedException(String indexName, Throwable cause) { + super(String.format("Indices '%s' failed", indexName), cause); + } +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/exception/PutMappingFailedException.java b/src/main/java/xy/SpringBoot2NoSQL/exception/PutMappingFailedException.java new file mode 100644 index 0000000..85c3b65 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/exception/PutMappingFailedException.java @@ -0,0 +1,7 @@ +package xy.SpringBoot2NoSQL.exception; + +public class PutMappingFailedException extends RuntimeException { + public PutMappingFailedException(String indexName, Throwable cause) { + super(String.format("Put Mapping failed for Index '%s'", indexName), cause); + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/Cassandra/Customer.java b/src/main/java/xy/SpringBoot2NoSQL/model/Cassandra/Customer.java new file mode 100644 index 0000000..1c78fd8 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/Cassandra/Customer.java @@ -0,0 +1,76 @@ +package xy.SpringBoot2NoSQL.model.Cassandra; + +import java.util.HashSet; +import java.util.Set; + +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.PrimaryKey; +import org.springframework.data.cassandra.core.mapping.Table; + +@Table +public class Customer { + + @PrimaryKey + private String id; + private String firstname; + private String lastname; + private int age; + +// @Column +// private Set tags = new HashSet<>(); + + public Customer(){} + + public Customer(String id, String firstname, String lastname, int age){ + this.id = id; + this.firstname = firstname; + this.lastname = lastname; + this.age = age; + } + + public void setId(String id){ + this.id = id; + } + + public String getId(){ + return this.id; + } + + public void setFirstname(String firstname){ + this.firstname = firstname; + } + + public String getFirstname(){ + return this.firstname; + } + + public void setLastname(String lastname){ + this.lastname = lastname; + } + + public String getLastname(){ + return this.lastname; + } + + public void setAge(int age){ + this.age = age; + } + + public int getAge(){ + return this.age; + } + +// public Set getTags() { +// return tags; +// } +// +// public void setTags(final Set tags) { +// this.tags = tags; +// } + + @Override + public String toString() { + return String.format("Customer[id=%d, firstName='%s', lastName='%s', age=%d]", this.id, + this.firstname, this.lastname, this.age); + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/Couchbase/Customer.java b/src/main/java/xy/SpringBoot2NoSQL/model/Couchbase/Customer.java new file mode 100644 index 0000000..71bff3e --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/Couchbase/Customer.java @@ -0,0 +1,55 @@ +//package xy.SpringBoot2NoSQL.model.Couchbase; +// +//import org.springframework.data.couchbase.core.mapping.Document; +// +//import com.couchbase.client.java.repository.annotation.Field; +//import com.couchbase.client.java.repository.annotation.Id; +// +// +//@Document +//public class Customer { +// @Id +// private String id; +// +// @Field +// private String firstName; +// +// @Field +// private String lastName; +// +// public Customer(String id, String firstName, String lastName){ +// this.id = id; +// this.firstName = firstName; +// this.lastName = lastName; +// } +// +// public String getId() { +// return this.id; +// } +// +// public void setId(String id) { +// this.id = id; +// } +// +// public String getFirstName() { +// return this.firstName; +// } +// +// public void setFirstName(String firstName) { +// this.firstName = firstName; +// } +// +// public String getLastName() { +// return this.lastName; +// } +// +// public void setLastName(String lastName) { +// this.lastName = lastName; +// } +// +// @Override +// public String toString() { +// return String.format("Customer[ id=%s, firstName=%s, lastName=%s]", this.id, this.firstName, this.lastName); +// } +//} +// diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/ElasticSearch/Product.java b/src/main/java/xy/SpringBoot2NoSQL/model/ElasticSearch/Product.java new file mode 100644 index 0000000..b4b60a0 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/ElasticSearch/Product.java @@ -0,0 +1,57 @@ +package xy.SpringBoot2NoSQL.model.ElasticSearch; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; + +@Document(indexName = "book",type = "book" , shards = 1, replicas = 0, refreshInterval = "-1") +public class Product { + @Id + private String id; + private String name; + private String description; + private boolean enabled; + + public Product() { + } + + public Product(String id, String name, String description, boolean enabled) { + this(); + this.id = id; + this.name = name; + this.description = description; + this.enabled = enabled; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Department.java b/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Department.java new file mode 100644 index 0000000..629f9df --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Department.java @@ -0,0 +1,35 @@ +package xy.SpringBoot2NoSQL.model.Mongo; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class Department { + + @Id + private String id; + + + private String name; + + public Department(String id, String name) { + super(); + this.id = id; + this.name = name; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Location.java b/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Location.java new file mode 100644 index 0000000..b3788de --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Location.java @@ -0,0 +1,38 @@ +package xy.SpringBoot2NoSQL.model.Mongo; + +public class Location { + + private String place; + + private String year; + + + + public Location(String place, String year) { + super(); + this.place = place; + this.year = year; + } + + public String getPlace() { + return place; + } + + public void setPlace(String place) { + this.place = place; + } + + public String getYear() { + return year; + } + + public void setYear(String year) { + this.year = year; + } + + + + + + +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Person.java b/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Person.java new file mode 100644 index 0000000..f1d0b79 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/Mongo/Person.java @@ -0,0 +1,69 @@ +package xy.SpringBoot2NoSQL.model.Mongo; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; +import org.springframework.data.mongodb.core.mapping.DBRef; + +import java.util.Collection; +import java.util.LinkedHashSet; + +@Document +public class Person { + @Id + private String id; + private String name; + private Integer age; + @Field("locs") + private Collection locations = new LinkedHashSet(); + @DBRef + Department department; + + + public Person(String name, Integer age) { + super(); + this.name = name; + this.age = age; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Collection getLocations() { + return locations; + } + + public void setLocations(Collection locations) { + this.locations = locations; + } + + public Department getDepartment() { + return department; + } + + public void setDepartment(Department department) { + this.department = department; + } + +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/Redis/User.java b/src/main/java/xy/SpringBoot2NoSQL/model/Redis/User.java new file mode 100644 index 0000000..2647b91 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/Redis/User.java @@ -0,0 +1,49 @@ +package xy.SpringBoot2NoSQL.model.Redis; + +import java.io.Serializable; +import java.util.Date; + +public class User implements Serializable{ + + private static final long serialVersionUID = 1945136152785232109L; + + private String login; + + private String fullName; + + private Date lastLogin; + + public User() {} + + public User(String login, String fullName) { + this.login = login; + this.fullName = fullName; + this.lastLogin = new Date(); + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public Date getLastLogin() { + return lastLogin; + } + + public void setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + } + +} + diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/Solr/Customer.java b/src/main/java/xy/SpringBoot2NoSQL/model/Solr/Customer.java new file mode 100644 index 0000000..04ac131 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/Solr/Customer.java @@ -0,0 +1,57 @@ +package xy.SpringBoot2NoSQL.model.Solr; + +import org.apache.solr.client.solrj.beans.Field; +import org.springframework.data.annotation.Id; +import org.springframework.data.solr.core.mapping.SolrDocument; + +@SolrDocument(collection = "customer") +public class Customer { + @Id + @Field + private String id; + + @Field + private String name; + + @Field + private Integer age; + + public Customer() { + } + + public Customer(String id, String name, Integer age){ + this.id = id; + this.name = name; + this.age = age; + } + + public void setId(String id){ + this.id = id; + } + + public String getId(){ + return this.id; + } + + public void setName(String name){ + this.name = name; + } + + public String getName(){ + return this.name; + } + + public void setAge(Integer age){ + this.age = age; + } + + public Integer getAge(){ + return this.age; + } + + @Override + public String toString() { + return "Customer [id=" + this.id + ", name=" + this.name + ", age=" + this.age + "]"; + } +} + diff --git a/src/main/java/xy/SpringBoot2NoSQL/model/User.java b/src/main/java/xy/SpringBoot2NoSQL/model/User.java new file mode 100644 index 0000000..e81ae3b --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/model/User.java @@ -0,0 +1,54 @@ +package xy.SpringBoot2NoSQL.model; + +import java.io.Serializable; +import java.util.Date; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class User implements Serializable{ + + private static final long serialVersionUID = -510562806568452731L; + + Logger logger = LogManager.getLogger(getClass()); + + private String login; + + private String fullName; + + private Date lastLogin; + + public User() {} + + public User(String login, String fullName) { + this.login = login; + this.fullName = fullName; + this.lastLogin = new Date(); + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public Date getLastLogin() { + return lastLogin; + } + + public void setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + } + +} + diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Cassandra/CustomerRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Cassandra/CustomerRepository.java new file mode 100644 index 0000000..258d394 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Cassandra/CustomerRepository.java @@ -0,0 +1,25 @@ +package xy.SpringBoot2NoSQL.repository.Cassandra; + +import java.util.List; + +import org.springframework.data.cassandra.repository.AllowFiltering; +import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.cassandra.repository.Query; + + +import xy.SpringBoot2NoSQL.model.Cassandra.Customer; + +public interface CustomerRepository extends CassandraRepository { + + @Query(value="SELECT * FROM customer WHERE firstname=?0") + public List findByFirstname(String firstname); + + @Query("SELECT * FROM customer WHERE age > ?0") + public List findCustomerHasAgeGreaterThan(int age); + + @AllowFiltering + public List findByLastname(String lastname); + + @AllowFiltering + public List findByAgeGreaterThan(int age); +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Couchbase/CouchbaseCustomerRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Couchbase/CouchbaseCustomerRepository.java new file mode 100644 index 0000000..de1f756 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Couchbase/CouchbaseCustomerRepository.java @@ -0,0 +1,17 @@ +//package xy.SpringBoot2NoSQL.repository.Couchbase; +// +//import java.util.List; +// +//import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed; +//import org.springframework.data.couchbase.core.query.ViewIndexed; +//import org.springframework.data.couchbase.repository.CouchbaseRepository; +// +//import xy.SpringBoot2NoSQL.model.Couchbase.Customer; +// +// +//@N1qlPrimaryIndexed +//@ViewIndexed(designDoc = "customer", viewName = "all") +//public interface CouchbaseCustomerRepository extends CouchbaseRepository { +// +// List findByLastName(String name); +//} diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/ElasticSearch/SampleProductRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/ElasticSearch/SampleProductRepository.java new file mode 100644 index 0000000..681bcc7 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/ElasticSearch/SampleProductRepository.java @@ -0,0 +1,15 @@ +package xy.SpringBoot2NoSQL.repository.ElasticSearch; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; + +import xy.SpringBoot2NoSQL.model.ElasticSearch.Product; + +import java.util.List; + +public interface SampleProductRepository extends ElasticsearchRepository { + List findByName(String name); + List findByDescription(String description); + List findByName(String name, Pageable pageable); + List findByNameAndId(String name, String id); +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/DepartmentRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/DepartmentRepository.java new file mode 100644 index 0000000..563d2a1 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/DepartmentRepository.java @@ -0,0 +1,13 @@ +package xy.SpringBoot2NoSQL.repository.Mongo; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import xy.SpringBoot2NoSQL.model.Mongo.Department; + + +public interface DepartmentRepository extends MongoRepository { + + Department findByName(String name); + +} + diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/PersonRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/PersonRepository.java new file mode 100644 index 0000000..6ff6944 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Mongo/PersonRepository.java @@ -0,0 +1,20 @@ +package xy.SpringBoot2NoSQL.repository.Mongo; + + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import xy.SpringBoot2NoSQL.model.Mongo.Person; +import java.util.List; + +public interface PersonRepository extends MongoRepository { + + Person findByName(String name); + + @Query("{'age': { '$lt' : ?0}}") + List withQueryFindByAge(Integer age); + + Page findAll(Pageable pageable); + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/ObjectRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/ObjectRepository.java new file mode 100644 index 0000000..34a5be0 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/ObjectRepository.java @@ -0,0 +1,27 @@ +package xy.SpringBoot2NoSQL.repository.Redis; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Repository; + +import xy.SpringBoot2NoSQL.model.Redis.User; + +@Repository +public class ObjectRepository { + @Autowired + RedisTemplate redisTemplate; + + @Resource(name = "redisTemplate") + ValueOperations valOps; + + public void save(User user) { + valOps.set(user.getLogin(), user); + } + + public User get(String id) { + return (User) valOps.get(id); + } +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/StringStringRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/StringStringRepository.java new file mode 100644 index 0000000..a454afe --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/StringStringRepository.java @@ -0,0 +1,25 @@ +package xy.SpringBoot2NoSQL.repository.Redis; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Repository; + +@Repository +public class StringStringRepository { + + @Autowired + private RedisTemplate template; + + public void add(String key, String value) { + template.opsForValue().set(key, value); + } + + public String getValue(String key) { + return template.opsForValue().get(key); + } + + public void delete(String key) { + template.opsForValue().getOperations().delete(key); + } + +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/UserRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/UserRepository.java new file mode 100644 index 0000000..ccd6fab --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Redis/UserRepository.java @@ -0,0 +1,30 @@ +package xy.SpringBoot2NoSQL.repository.Redis; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.stereotype.Repository; + +import xy.SpringBoot2NoSQL.model.Redis.User; + +@Repository +public class UserRepository { + +// @Autowired +// RedisTemplate redisTemplate; +// +// @Resource(name = "redisTemplate") +// ValueOperations valOps; +// +// public void save(User user) { +// valOps.set(user.getLogin(), user); +// } +// +// public User get(String id) { +// return valOps.get(id); +// } + + +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/repository/Solr/SolrCustomerRepository.java b/src/main/java/xy/SpringBoot2NoSQL/repository/Solr/SolrCustomerRepository.java new file mode 100644 index 0000000..4b78648 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/repository/Solr/SolrCustomerRepository.java @@ -0,0 +1,10 @@ +package xy.SpringBoot2NoSQL.repository.Solr; + +import java.util.List; +import org.springframework.data.solr.repository.SolrCrudRepository; +import xy.SpringBoot2NoSQL.model.Solr.Customer; + + +public interface SolrCustomerRepository extends SolrCrudRepository { + List findByNameEndsWith(String name); +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/service/Ehcache/UserService.java b/src/main/java/xy/SpringBoot2NoSQL/service/Ehcache/UserService.java new file mode 100644 index 0000000..3ca2c39 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/service/Ehcache/UserService.java @@ -0,0 +1,49 @@ +package xy.SpringBoot2NoSQL.service.Ehcache; + +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.stereotype.Service; +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Element; +import xy.SpringBoot2NoSQL.model.User; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +@Service +@CacheConfig(cacheNames="users") +public class UserService { + + Logger logger = LogManager.getLogger(getClass()); + + @CacheEvict(allEntries = true) + public void clearCache(){} + + public User getUser(String login) { + // 获取缓存实例 + Cache userCache = CacheManager.getInstance().getCache("users"); + + if (userCache.get(login)!=null){ + + User user = (User) userCache.get(login).getObjectValue(); + logger.info("从缓存获取user用户: {}", login); + logger.info("从缓存JVM内存中获取获取user用户: {}-{}",login, userCache.isElementInMemory(login)); + logger.info("从缓存OffHeap内存中获取获取user用户: {}-{}",login, userCache.isElementOffHeap(login)); + logger.info("已持久化磁盘,用户: {}-{}",login, userCache.isElementOnDisk(login)); + + return user; + } + else{ + User user = new User(login,login+"的姓名"); + logger.info("新user用户: {}", login); + // 写入缓存,注意我们故意设置maxElementsInMemory内存最大值是5 + Element element = new Element(login, user); + userCache.put(element); + + return user; + } + + } + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/utils/ESSearchUtil.java b/src/main/java/xy/SpringBoot2NoSQL/utils/ESSearchUtil.java new file mode 100644 index 0000000..0e70f5b --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/utils/ESSearchUtil.java @@ -0,0 +1,160 @@ +package xy.SpringBoot2NoSQL.utils; + +import java.io.IOException; + +import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; +import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; +import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; +import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse; +import org.elasticsearch.client.Client; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; + +import xy.SpringBoot2NoSQL.exception.CreateIndexFailedException; +import xy.SpringBoot2NoSQL.exception.IndicesExistsFailedException; +import xy.SpringBoot2NoSQL.exception.PutMappingFailedException; + +public class ESSearchUtil { + + /** + * 索引是否存在 + * @param client + * @param indexName + * @return + */ + public static IndicesExistsResponse indexExist(Client client, String indexName) { + try { + return client.admin().indices().prepareExists(indexName).execute().actionGet(); + } catch (Exception e) { + + throw new IndicesExistsFailedException(indexName, e); + } + } + + /** + * 创建索引 + * @param client + * @param indexName + * @return + */ + public static CreateIndexResponse createIndex(Client client, String indexName) { + try { + return internalCreateIndex(client, indexName); + } catch (Exception e) { + throw new CreateIndexFailedException(indexName, e); + } + } + + public static PutMappingResponse putMapping(Client client, String indexName, IElasticSearchMapping mapping) { + try { + return internalPutMapping(client, indexName, mapping); + } catch (Exception e) { + + throw new PutMappingFailedException(indexName, e); + } + } + + private static CreateIndexResponse internalCreateIndex(Client client, String indexName) throws IOException { + final CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); + + final CreateIndexResponse indexResponse = createIndexRequestBuilder.execute().actionGet(); + + return indexResponse; + } + + private static PutMappingResponse internalPutMapping(Client client, String indexName, IElasticSearchMapping mapping) + throws IOException { + + final PutMappingRequest putMappingRequest = new PutMappingRequest(indexName).type(mapping.getIndexType()) + .source(mapping.getMapping().string()); + + final PutMappingResponse putMappingResponse = client.admin().indices().putMapping(putMappingRequest) + .actionGet(); + + return putMappingResponse; + } + + /** + * 部分匹配查询,包括模糊匹配和短语或邻近查询。 + * + * @param key + * @param value + * @return + */ + public static QueryBuilder matchQuery(String key, String value) { + return QueryBuilders.matchQuery(key, value); + } + + /** + * 完全匹配。 + * + * @param key + * @param value + * @return + */ + public static QueryBuilder matchPhraseQuery(String key, String value) { + return QueryBuilders.matchPhraseQuery(key, value); + } + + /** + * 多字段匹配 + * + * @param text + * @param fieldNames + * @return + */ + public static QueryBuilder multiMatchQuery(Object text, String... fieldNames) { + return QueryBuilders.multiMatchQuery(text, fieldNames); + + } + + /** + * 模糊查询 + * + * @param key + * @param value + * @return + */ + public static QueryBuilder fuzzyQuery(String key, String value) { + return QueryBuilders.fuzzyQuery(key, value); + } + + /** + * 全部查询 + * + * @return + */ + public static QueryBuilder matchAllQuery() { + return QueryBuilders.matchAllQuery(); + } + + /** + * 范围查询 + * + * @param key + * @param from + * @param to + * @return + */ + public static QueryBuilder rangeQuery(String key, Object from, Object to) { + return QueryBuilders.rangeQuery(key).from(from).to(to).includeLower(true) // 包括下界 + .includeUpper(false); // 包括上界 + } + + /** + * 完全匹配查询 + * + * @param key + * @param values + * @return + */ + public static QueryBuilder termsQuery(String key, String... values) { + return QueryBuilders.termsQuery(key, values); + } + + public static QueryBuilder termsQuery(String key, Object values) { + return QueryBuilders.termsQuery(key, values); + } + +} diff --git a/src/main/java/xy/SpringBoot2NoSQL/utils/IElasticSearchMapping.java b/src/main/java/xy/SpringBoot2NoSQL/utils/IElasticSearchMapping.java new file mode 100644 index 0000000..eb6b04e --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/utils/IElasticSearchMapping.java @@ -0,0 +1,14 @@ +package xy.SpringBoot2NoSQL.utils; + +import org.elasticsearch.Version; +import org.elasticsearch.common.xcontent.XContentBuilder; + +public interface IElasticSearchMapping { + + XContentBuilder getMapping(); + + String getIndexType(); + + Version getVersion(); + +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/utils/RandomUtil.java b/src/main/java/xy/SpringBoot2NoSQL/utils/RandomUtil.java new file mode 100644 index 0000000..b88cafb --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/utils/RandomUtil.java @@ -0,0 +1,120 @@ +package xy.SpringBoot2NoSQL.utils; + +import java.util.Random; + +public class RandomUtil { + public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + public static final String LETTERCHAR = "abcdefghijkllmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + public static final String NUMBERCHAR = "0123456789"; + + /** + * 返回一个定长的随机字符串(只包含大小写字母、数字) + * + * @param length + * 随机字符串长度 + * @return 随机字符串 + */ + public static String generateString(int length) { + StringBuffer sb = new StringBuffer(); + Random random = new Random(); + for (int i = 0; i < length; i++) { + sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length()))); + } + return sb.toString(); + } + + /** + * 返回一个定长的随机纯字母字符串(只包含大小写字母) + * + * @param length + * 随机字符串长度 + * @return 随机字符串 + */ + public static String generateMixString(int length) { + StringBuffer sb = new StringBuffer(); + Random random = new Random(); + for (int i = 0; i < length; i++) { + sb.append(ALLCHAR.charAt(random.nextInt(LETTERCHAR.length()))); + } + return sb.toString(); + } + + /** + * 返回一个定长的随机纯大写字母字符串(只包含大小写字母) + * + * @param length + * 随机字符串长度 + * @return 随机字符串 + */ + public static String generateLowerString(int length) { + return generateMixString(length).toLowerCase(); + } + + /** + * 返回一个定长的随机纯小写字母字符串(只包含大小写字母) + * + * @param length + * 随机字符串长度 + * @return 随机字符串 + */ + public static String generateUpperString(int length) { + return generateMixString(length).toUpperCase(); + } + + /** + * 生成一个定长的纯0字符串 + * + * @param length + * 字符串长度 + * @return 纯0字符串 + */ + public static String generateZeroString(int length) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < length; i++) { + sb.append('0'); + } + return sb.toString(); + } + + /** + * 根据数字生成一个定长的字符串,长度不够前面补0 + * + * @param num + * 数字 + * @param fixdlenth + * 字符串长度 + * @return 定长的字符串 + */ + public static String toFixdLengthString(long num, int fixdlenth) { + StringBuffer sb = new StringBuffer(); + String strNum = String.valueOf(num); + if (fixdlenth - strNum.length() >= 0) { + sb.append(generateZeroString(fixdlenth - strNum.length())); + } else { + throw new RuntimeException("将数字" + num + "转化为长度为" + fixdlenth + "的字符串发生异常!"); + } + sb.append(strNum); + return sb.toString(); + } + + /** + * 每次生成的len位数都不相同 + * + * @param param + * @return 定长的数字 + */ + public static int getNotSimple(int[] param, int len) { + Random rand = new Random(); + for (int i = param.length; i > 1; i--) { + int index = rand.nextInt(i); + int tmp = param[index]; + param[index] = param[i - 1]; + param[i - 1] = tmp; + } + int result = 0; + for (int i = 0; i < len; i++) { + result = result * 10 + param[i]; + } + return result; + } +} \ No newline at end of file diff --git a/src/main/java/xy/SpringBoot2NoSQL/utils/RedisCacheUtils.java b/src/main/java/xy/SpringBoot2NoSQL/utils/RedisCacheUtils.java new file mode 100644 index 0000000..b8e3898 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/utils/RedisCacheUtils.java @@ -0,0 +1,649 @@ +//package xy.SpringBoot2NoSQL.utils; +// +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Map; +//import java.util.Set; +//import java.util.concurrent.TimeUnit; +// +//import javax.annotation.PostConstruct; +//import javax.annotation.Resource; +// +//import org.springframework.data.redis.connection.RedisZSetCommands; +//import org.springframework.data.redis.core.ListOperations; +//import org.springframework.data.redis.core.RedisCallback; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.data.redis.core.SetOperations; +//import org.springframework.data.redis.core.ValueOperations; +// +//import com.alibaba.fastjson.JSON; +//import com.alibaba.fastjson.parser.Feature; +// +//public class RedisCacheUtils { +// @Resource +// private RedisTemplate redisTemplate; +// +// private static RedisCacheUtils cacheUtils; +// +// @PostConstruct +// public void init() { +// cacheUtils = this; +// cacheUtils.redisTemplate = this.redisTemplate; +// } +// +// /** +// * 将数据存入缓存 +// * +// * @param key +// * @param val +// * @return +// */ +// public static void saveString(String key, String val) { +// +// ValueOperations vo = cacheUtils.redisTemplate.opsForValue(); +// vo.set(key, val); +// } +// +// /** +// * 将数据存入缓存的集合中 +// * +// * @param key +// * @param val +// * @return +// */ +// public static void saveToSet(String key, String val) { +// +// SetOperations so = cacheUtils.redisTemplate.opsForSet(); +// +// so.add(key, val); +// } +// +// /** +// * key 缓存Key +// * @param key +// * @return +// */ +// public static String getFromSet(String key) { +// return cacheUtils.redisTemplate.opsForSet().pop(key); +// } +// +// /** +// * 将 key的值保存为 value ,当且仅当 key 不存在。 若给定的 key 已经存在,则 SETNX 不做任何动作。 SETNX 是『SET if +// * Not eXists』(如果不存在,则 SET)的简写。
+// * 保存成功,返回 true
+// * 保存失败,返回 false +// */ +// public static boolean saveNX(String key, String val) { +// +// /** 设置成功,返回 1 设置失败,返回 0 **/ +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.setNX(key.getBytes(), val.getBytes()); +// }); +// +// } +// +// /** +// * 将 key的值保存为 value ,当且仅当 key 不存在。 若给定的 key 已经存在,则 SETNX 不做任何动作。 SETNX 是『SET if +// * Not eXists』(如果不存在,则 SET)的简写。
+// * 保存成功,返回 true
+// * 保存失败,返回 false +// * +// * @param key +// * @param val +// * @param expire 超时时间 +// * @return 保存成功,返回 true 否则返回 false +// */ +// public static boolean saveNX(String key, String val, int expire) { +// +// boolean ret = saveNX(key, val); +// if (ret) { +// cacheUtils.redisTemplate.expire(key, expire, TimeUnit.SECONDS); +// } +// return ret; +// } +// +// /** +// * 将数据存入缓存(并设置失效时间) +// * +// * @param key +// * @param val +// * @param seconds +// * @return +// */ +// public static void saveString(String key, String val, int seconds) { +// +// cacheUtils.redisTemplate.opsForValue().set(key, val, seconds, TimeUnit.SECONDS); +// } +// +// /** +// * 将自增变量存入缓存 +// */ +// public static void saveSeq(String key, long seqNo) { +// +// cacheUtils.redisTemplate.delete(key); +// cacheUtils.redisTemplate.opsForValue().increment(key, seqNo); +// } +// +// /** +// * 将递增浮点数存入缓存 +// */ +// public static void saveFloat(String key, float data) { +// +// cacheUtils.redisTemplate.delete(key); +// cacheUtils.redisTemplate.opsForValue().increment(key, data); +// } +// +// /** +// * 保存复杂类型数据到缓存 +// * +// * @param key +// * @param obj +// * @return +// */ +// public static void saveBean(String key, Object obj) { +// +// cacheUtils.redisTemplate.opsForValue().set(key, JSON.toJSONString(obj)); +// } +// +// /** +// * 保存复杂类型数据到缓存(并设置失效时间) +// * +// * @param key +// * @param obj +// * @param seconds +// */ +// public static void saveBean(String key, Object obj, int seconds) { +// +// cacheUtils.redisTemplate.opsForValue().set(key, JSON.toJSONString(obj), seconds, TimeUnit.SECONDS); +// } +// +// /** +// * 存到指定的队列中 +// * @param key +// * @param val +// * @param size +// */ +// public static void saveToQueue(String key, String val, long size) { +// +// ListOperations lo = cacheUtils.redisTemplate.opsForList(); +// +// if (size > 0 && lo.size(key) >= size) { +// lo.rightPop(key); +// } +// lo.leftPush(key, val); +// } +// +// /** +// * 保存到hash集合中 +// * +// * @param hName 集合名 +// * @param key +// * @param value +// */ +// public static void hashSet(String hName, String key, String value) { +// +// cacheUtils.redisTemplate.opsForHash().put(hName, key, value); +// } +// +// /** +// * 根据key获取所以值 +// * +// * @param key +// * @return +// */ +// public static Map hgetAll(String key) { +// +// return cacheUtils.redisTemplate.opsForHash().entries(key); +// } +// +// /** +// * 保存到hash集合中 +// * +// * @param +// * @param hName 集合名 +// * @param key +// * @param t +// */ +// public static void hashSet(String hName, String key, T t) { +// +// hashSet(hName, key, JSON.toJSONString(t)); +// } +// +// /** +// * 取得复杂JSON数据 +// * +// * @param key +// * @param clazz +// * @param clazz +// * @return +// */ +// public static T getBean(String key, Class clazz) { +// +// String value = cacheUtils.redisTemplate.opsForValue().get(key); +// if (value == null) { +// return null; +// } +// return JSON.parseObject(value, clazz); +// } +// +// /** +// * 从缓存中取得字符串数据 +// * +// * @param key +// * @return 数据 +// */ +// public static String getString(String key) { +// cacheUtils.redisTemplate.opsForValue().get(key); +// +// return cacheUtils.redisTemplate.opsForValue().get(key); +// } +// +// /** +// * 从指定队列里取得数据 +// * @param key +// * @param size +// * @return +// */ +// public static List getFromQueue(String key, long size) { +// +// boolean flag = cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.exists(key.getBytes()); +// }); +// +// if (flag) { +// return new ArrayList<>(); +// } +// ListOperations lo = cacheUtils.redisTemplate.opsForList(); +// if (size > 0) { +// return lo.range(key, 0, size - 1); +// } else { +// return lo.range(key, 0, lo.size(key) - 1); +// } +// } +// +// /** +// * 从指定队列里取得数据 +// * @param key +// * @return +// */ +// public static String popQueue(String key) { +// +// return cacheUtils.redisTemplate.opsForList().rightPop(key); +// +// } +// +// /** +// * 取得序列值的下一个 +// * +// * @param key +// * @return +// */ +// public static Long getSeqNext(String key) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// +// return connection.incr(key.getBytes()); +// +// }); +// } +// +// /** +// * 取得序列值的下一个 +// * +// * @param key +// * @return +// */ +// public static Long getSeqNext(String key, long value) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// +// return connection.incrBy(key.getBytes(), value); +// +// }); +// +// } +// +// /** +// * 将序列值回退一个 +// * +// * @param key +// * @return +// */ +// public static void getSeqBack(String key) { +// +// cacheUtils.redisTemplate.execute((RedisCallback) connection -> connection.decr(key.getBytes())); +// +// } +// +// /** +// * 从hash集合里取得 +// * +// * @param hName +// * @param key +// * @return +// */ +// public static Object hashGet(String hName, String key) { +// +// return cacheUtils.redisTemplate.opsForHash().get(hName, key); +// } +// +// public static T hashGet(String hName, String key, Class clazz) { +// +// return JSON.parseObject((String) hashGet(hName, key), clazz); +// } +// +// /** +// * 增加浮点数的值 +// * +// * @param key +// * @return +// */ +// public static Double incrFloat(String key, double incrBy) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// +// return connection.incrBy(key.getBytes(), incrBy); +// +// }); +// } +// +// /** +// * 判断是否缓存了数据 +// * +// * @param key 数据KEY +// * @return 判断是否缓存了 +// */ +// public static boolean isCached(String key) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.exists(key.getBytes()); +// }); +// } +// +// /** +// * 判断hash集合中是否缓存了数据 +// * +// * @param hName +// * @param key 数据KEY +// * @return 判断是否缓存了 +// */ +// public static boolean hashCached(String hName, String key) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.hExists(key.getBytes(), key.getBytes()); +// }); +// } +// +// /** +// * 判断是否缓存在指定的集合中 +// * +// * @param key 数据KEY +// * @param val 数据 +// * @return 判断是否缓存了 +// */ +// public static boolean isMember(String key, String val) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.sIsMember(key.getBytes(), val.getBytes()); +// }); +// } +// +// /** +// * 从缓存中删除数据 +// * +// * @param key +// * @return +// */ +// public static void delKey(String key) { +// +// cacheUtils.redisTemplate.execute((RedisCallback) connection -> connection.del(key.getBytes())); +// } +// +// /** +// * 设置超时时间 +// * +// * @param key +// * @param seconds +// */ +// public static void expire(String key, int seconds) { +// cacheUtils.redisTemplate +// .execute((RedisCallback) connection -> connection.expire(key.getBytes(), seconds)); +// +// } +// +// /** +// * 列出set中所有成员 +// * +// * @param setName set名 +// * @return +// */ +// public static Set listSet(String setName) { +// +// return cacheUtils.redisTemplate.opsForHash().keys(setName); +// +// } +// +// /** +// * 向set中追加一个值 +// * +// * @param setName set名 +// * @param value +// */ +// public static void setSave(String setName, String value) { +// +// cacheUtils.redisTemplate +// .execute((RedisCallback) connection -> connection.sAdd(setName.getBytes(), value.getBytes())); +// +// } +// +// /** +// * 逆序列出sorted set包括分数的set列表 +// * +// * @param key set名 +// * @param start 开始位置 +// * @param end 结束位置 +// * @return 列表 +// */ +// public static Set listSortedsetRev(String key, int start, int end) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback>) connection -> { +// return connection.zRevRangeWithScores(key.getBytes(), start, end); +// }); +// } +// +// /** +// * 逆序取得sorted sort排名 +// * +// * @param key set名 +// * @param member 成员名 +// * @return 排名 +// */ +// public static Long getRankRev(String key, String member) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.zRevRank(key.getBytes(), member.getBytes()); +// }); +// +// } +// +// /** +// * 根据成员名取得sorted sort分数 +// * +// * @param key set名 +// * @param member 成员名 +// * @return 分数 +// */ +// public static Double getMemberScore(String key, String member) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.zScore(key.getBytes(), member.getBytes()); +// }); +// } +// +// /** +// * 向sorted set中追加一个值 +// * +// * @param key set名 +// * @param score 分数 +// * @param member 成员名称 +// */ +// public static void saveToSortedset(String key, Double score, String member) { +// +// cacheUtils.redisTemplate.execute( +// (RedisCallback) connection -> connection.zAdd(key.getBytes(), score, member.getBytes())); +// } +// +// /** +// * 从sorted set删除一个值 +// * +// * @param key set名 +// * @param member 成员名称 +// */ +// public static void delFromSortedset(String key, String member) { +// cacheUtils.redisTemplate +// .execute((RedisCallback) connection -> connection.zRem(key.getBytes(), member.getBytes())); +// +// } +// +// /** +// * 从hash map中取得复杂JSON数据 +// * +// * @param key +// * @param field +// * @param clazz +// */ +// public static T getBeanFromMap(String key, String field, Class clazz) { +// +// byte[] input = cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.hGet(key.getBytes(), field.getBytes()); +// }); +// return JSON.parseObject(input, clazz, Feature.AutoCloseSource); +// } +// +// /** +// * 从hashmap中删除一个值 +// * +// * @param key map名 +// * @param field 成员名称 +// */ +// public static void delFromMap(String key, String field) { +// +// cacheUtils.redisTemplate +// .execute((RedisCallback) connection -> connection.hDel(key.getBytes(), field.getBytes())); +// +// } +// +// /** +// * @param key +// * @return +// * @Description: 根据key增长 ,计数器 +// * @author clg +// * @date 2016年6月30日 下午2:37:52 +// */ +// public static long incr(String key) { +// +// return cacheUtils.redisTemplate.execute((RedisCallback) connection -> { +// return connection.incr(key.getBytes()); +// }); +// } +// +// +// /** +// * 根据key获取当前计数结果 +// * @param key +// * @return +// */ +// public static String getCount(String key) { +// +// return cacheUtils.redisTemplate.opsForValue().get(key); +// } +// +// /** +// * 将所有指定的值插入到存于 key 的列表的头部。如果 key 不存在,那么在进行 push 操作前会创建一个空列表 +// * +// * @param +// * @param key +// * @param value +// * @return +// */ +// public static Long lpush(String key, T value) { +// +// return cacheUtils.redisTemplate.opsForList().leftPush(key, JSON.toJSONString(value)); +// } +// +// /** +// * 只有当 key 已经存在并且存着一个 list 的时候,在这个 key 下面的 list 的头部插入 value。 与 LPUSH 相反,当 key +// * 不存在的时候不会进行任何操作 +// * +// * @param key +// * @param value +// * @return +// */ +// public static Long lpushx(String key, T value) { +// +// return cacheUtils.redisTemplate.opsForList().leftPushIfPresent(key, JSON.toJSONString(value)); +// } +// +// /** +// * 返回存储在 key 里的list的长度。 如果 key 不存在,那么就被看作是空list,并且返回长度为 0 +// * +// * @param key +// * @return +// */ +// public static Long llen(String key) { +// +// return cacheUtils.redisTemplate.opsForList().size(key); +// } +// +// /** +// * 返回存储在 key 的列表里指定范围内的元素。 start 和 end +// * 偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1,以此类推 +// * +// * @param key +// * @return +// */ +// public static List lrange(String key, long start, long end) { +// +// return cacheUtils.redisTemplate.opsForList().range(key, start, end); +// } +// +// /** +// * 移除并且返回 key 对应的 list 的第一个元素 +// * +// * @param key +// * @return +// */ +// public static String lpop(String key) { +// +// return cacheUtils.redisTemplate.opsForList().leftPop(key); +// } +// +// /** +// * 保存到hash集合中 只在 key 指定的哈希集中不存在指定的字段时,设置字段的值。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key +// * 关联。如果字段已存在,该操作无效果。 +// * +// * @param hName 集合名 +// * @param key +// * @param value +// */ +// public static void hsetnx(String hName, String key, String value) { +// +// cacheUtils.redisTemplate.execute((RedisCallback) connection -> connection.hSetNX(key.getBytes(), +// key.getBytes(), value.getBytes())); +// +// } +// +// /** +// * 保存到hash集合中 只在 key 指定的哈希集中不存在指定的字段时,设置字段的值。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key +// * 关联。如果字段已存在,该操作无效果。 +// * +// * @param hName 集合名 +// * @param key +// * @param t +// * @param +// */ +// public static void hsetnx(String hName, String key, T t) { +// hsetnx(hName, key, JSON.toJSONString(t)); +// } +// +//} diff --git a/src/main/java/xy/SpringBoot2NoSQL/utils/RedissonUtil.java b/src/main/java/xy/SpringBoot2NoSQL/utils/RedissonUtil.java new file mode 100644 index 0000000..3d490f7 --- /dev/null +++ b/src/main/java/xy/SpringBoot2NoSQL/utils/RedissonUtil.java @@ -0,0 +1,157 @@ +package xy.SpringBoot2NoSQL.utils; + +import org.redisson.Redisson; +import org.redisson.api.RAtomicLong; +import org.redisson.api.RBucket; +import org.redisson.api.RCountDownLatch; +import org.redisson.api.RDeque; +import org.redisson.api.RList; +import org.redisson.api.RLock; +import org.redisson.api.RMap; +import org.redisson.api.RQueue; +import org.redisson.api.RSet; +import org.redisson.api.RSortedSet; +import org.redisson.api.RTopic; +import org.redisson.api.RedissonClient; + +/** + * Redisson分布式操作类 + * @author 王昕 + * + */ +public class RedissonUtil { + + /** + * 关闭Redisson客户端连接 + * @param redisson + */ + public static void closeRedisson(RedissonClient redisson){ + redisson.shutdown(); + System.out.println("成功关闭Redis Client连接"); + } + + /** + * 获取字符串对象 + * @param redisson + * @param objectName + * @return + */ + public static RBucket getRBucket(RedissonClient redisson,String objectName){ + RBucket bucket=redisson.getBucket(objectName); + return bucket; + } + + /** + * 获取Map对象 + * @param redisson + * @param objectName + * @return + */ + public static RMap getRMap(RedissonClient redisson,String objectName){ + RMap map=redisson.getMap(objectName); + return map; + } + + /** + * 获取有序集合 + * @param redisson + * @param objectName + * @return + */ + public static RSortedSet getRSortedSet(RedissonClient redisson,String objectName){ + RSortedSet sortedSet=redisson.getSortedSet(objectName); + return sortedSet; + } + + /** + * 获取集合 + * @param redisson + * @param objectName + * @return + */ + public static RSet getRSet(RedissonClient redisson,String objectName){ + RSet rSet=redisson.getSet(objectName); + return rSet; + } + + /** + * 获取列表 + * @param redisson + * @param objectName + * @return + */ + public static RList getRList(RedissonClient redisson,String objectName){ + RList rList=redisson.getList(objectName); + return rList; + } + + /** + * 获取队列 + * @param redisson + * @param objectName + * @return + */ + public static RQueue getRQueue(RedissonClient redisson,String objectName){ + RQueue rQueue=redisson.getQueue(objectName); + return rQueue; + } + + /** + * 获取双端队列 + * @param redisson + * @param objectName + * @return + */ + public static RDeque getRDeque(RedissonClient redisson,String objectName){ + RDeque rDeque=redisson.getDeque(objectName); + return rDeque; + } + + + + /** + * 获取锁 + * @param redisson + * @param objectName + * @return + */ + public static RLock getRLock(RedissonClient redisson,String objectName){ + RLock rLock=redisson.getLock(objectName); + return rLock; + } + + /** + * 获取原子数 + * @param redisson + * @param objectName + * @return + */ + public static RAtomicLong getRAtomicLong(RedissonClient redisson,String objectName){ + RAtomicLong rAtomicLong=redisson.getAtomicLong(objectName); + return rAtomicLong; + } + + /** + * 获取记数锁 + * @param redisson + * @param objectName + * @return + */ + public static RCountDownLatch getRCountDownLatch(RedissonClient redisson,String objectName){ + RCountDownLatch rCountDownLatch=redisson.getCountDownLatch(objectName); + return rCountDownLatch; + } + + /** + * 获取消息的Topic + * @param redisson + * @param objectName + * @return + */ + public static RTopic getRTopic(RedissonClient redisson,String objectName){ + RTopic rTopic=redisson.getTopic(objectName); + return rTopic; + + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..79c7f91 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,101 @@ +server.port=9092 +debug=true +spring.devtools.restart.exclude=static/** + +#spring.datasource.url=jdbc:mysql://localhost:3306/boot?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true +#spring.datasource.username=root +#spring.datasource.password=mysql +#spring.datasource.driver-class-name=com.mysql.jdbc.Driver + +# MONGODB +spring.data.mongodb.host=127.0.0.1 +spring.data.mongodb.port=27017 +spring.data.mongodb.database=test + +#Cassandra +#spring.data.cassandra.keyspace-name=mydb +#spring.data.cassandra.contact-points=localhost +#spring.data.cassandra.port=9042 + +#Solr +spring.data.solr.host=http://localhost:8983/solr + +#Couchbase +#spring.couchbase.bootstrap-hosts=127.0.0.1 +#spring.couchbase.bucket.name=mydb +#spring.couchbase.bucket.password=123456 +#spring.data.couchbase.auto-index=true + +# Redis +# Redis\u6570\u636e\u5e93\u7d22\u5f15\uff08\u9ed8\u8ba4\u4e3a0\uff09 +spring.redis.database=0 +spring.redis.host=127.0.0.1 +spring.redis.port=6379 +#spring.redis.password=123 +# \u8fde\u63a5\u6c60\u6700\u5927\u8fde\u63a5\u6570\uff08\u4f7f\u7528\u8d1f\u503c\u8868\u793a\u6ca1\u6709\u9650\u5236\uff09 +spring.redis.pool.max-active=60 +# \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5927\u7a7a\u95f2\u8fde\u63a5 +spring.redis.pool.max-idle=30 +# \u8fde\u63a5\u6c60\u6700\u5927\u963b\u585e\u7b49\u5f85\u65f6\u95f4\uff08\u4f7f\u7528\u8d1f\u503c\u8868\u793a\u6ca1\u6709\u9650\u5236\uff09 +spring.redis.pool.max-wait=-1 +# \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5 +spring.redis.pool.min-idle=0 + +#redisson\u914d\u7f6e +#redis\u94fe\u63a5\u5730\u5740 +spring.redisson.address=redis://127.0.0.1:6379 +#\u5f53\u524d\u5904\u7406\u6838\u6570\u91cf * 2 +spring.redisson.thread=4 +#\u6307\u5b9a\u7f16\u89e3\u7801 +spring.redisson.codec=org.redisson.codec.JsonJacksonCodec +#\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5\u6570,\u9ed8\u8ba4\u503c:10,\u6700\u5c0f\u4fdd\u6301\u8fde\u63a5\u6570\uff08\u957f\u8fde\u63a5\uff09 +spring.redisson.connectionMinimumIdleSize=12 +#\u8fde\u63a5\u7a7a\u95f2\u8d85\u65f6\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2 \u9ed8\u8ba410000;\u5f53\u524d\u8fde\u63a5\u6c60\u91cc\u7684\u8fde\u63a5\u6570\u91cf\u8d85\u8fc7\u4e86\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5\u6570\uff0c +#\u800c\u8fde\u63a5\u7a7a\u95f2\u65f6\u95f4\u8d85\u8fc7\u4e86\u8be5\u6570\u503c\uff0c\u8fd9\u4e9b\u8fde\u63a5\u5c06\u4f1a\u81ea\u52a8\u88ab\u5173\u95ed\uff0c\u5e76\u4ece\u8fde\u63a5\u6c60\u91cc\u53bb\u6389 +spring.redisson.idleConnectionTimeout=10000 +#ping\u8282\u70b9\u8d85\u65f6,\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba41000 +spring.redisson.pingTimeout=1000 +#\u8fde\u63a5\u7b49\u5f85\u8d85\u65f6,\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba410000 +spring.redisson.connectTimeout=10000 +#\u547d\u4ee4\u7b49\u5f85\u8d85\u65f6,\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba43000\uff1b\u7b49\u5f85\u8282\u70b9\u56de\u590d\u547d\u4ee4\u7684\u65f6\u95f4\u3002\u8be5\u65f6\u95f4\u4ece\u547d\u4ee4\u53d1\u9001\u6210\u529f\u65f6\u5f00\u59cb\u8ba1\u65f6 +spring.redisson.timeout=3000 +#\u547d\u4ee4\u5931\u8d25\u91cd\u8bd5\u6b21\u6570\uff0c\u9ed8\u8ba4\u503c:3 +spring.redisson.retryAttempts=2 +#\u547d\u4ee4\u91cd\u8bd5\u53d1\u9001\u65f6\u95f4\u95f4\u9694\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba4\u503c:1500 +spring.redisson.retryInterval=1500 +#\u91cd\u65b0\u8fde\u63a5\u65f6\u95f4\u95f4\u9694\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2,\u9ed8\u8ba4\u503c\uff1a3000;\u8fde\u63a5\u65ad\u5f00\u65f6\uff0c\u7b49\u5f85\u4e0e\u5176\u91cd\u65b0\u5efa\u7acb\u8fde\u63a5\u7684\u65f6\u95f4\u95f4\u9694 +spring.redisson.reconnectionTimeout=3000 +#\u6267\u884c\u5931\u8d25\u6700\u5927\u6b21\u6570, \u9ed8\u8ba4\u503c\uff1a3\uff1b\u5931\u8d25\u540e\u76f4\u5230 reconnectionTimeout\u8d85\u65f6\u4ee5\u540e\u518d\u6b21\u5c1d\u8bd5\u3002 +spring.redisson.failedAttempts=2 +#\u8eab\u4efd\u9a8c\u8bc1\u5bc6\u7801 +#spring.redisson.password= +#\u5355\u4e2a\u8fde\u63a5\u6700\u5927\u8ba2\u9605\u6570\u91cf\uff0c\u9ed8\u8ba4\u503c\uff1a5 +spring.redisson.subscriptionsPerConnection=5 +#\u5ba2\u6237\u7aef\u540d\u79f0 +#spring.redisson.clientName= +#\u53d1\u5e03\u548c\u8ba2\u9605\u8fde\u63a5\u7684\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5\u6570\uff0c\u9ed8\u8ba4\u503c\uff1a1\uff1bRedisson\u5185\u90e8\u7ecf\u5e38\u901a\u8fc7\u53d1\u5e03\u548c\u8ba2\u9605\u6765\u5b9e\u73b0\u8bb8\u591a\u529f\u80fd\u3002 +#\u957f\u671f\u4fdd\u6301\u4e00\u5b9a\u6570\u91cf\u7684\u53d1\u5e03\u8ba2\u9605\u8fde\u63a5\u662f\u5fc5\u987b\u7684 +spring.redisson.subscriptionConnectionMinimumIdleSize=1 +#\u53d1\u5e03\u548c\u8ba2\u9605\u8fde\u63a5\u6c60\u5927\u5c0f\uff0c\u9ed8\u8ba4\u503c\uff1a50 +spring.redisson.subscriptionConnectionPoolSize=50 +#\u8fde\u63a5\u6c60\u6700\u5927\u5bb9\u91cf\u3002\u9ed8\u8ba4\u503c\uff1a64\uff1b\u8fde\u63a5\u6c60\u7684\u8fde\u63a5\u6570\u91cf\u81ea\u52a8\u5f39\u6027\u4f38\u7f29 +spring.redisson.connectionPoolSize=64 +#\u6570\u636e\u5e93\u7f16\u53f7\uff0c\u9ed8\u8ba4\u503c\uff1a0 +spring.redisson.database=0 +#\u662f\u5426\u542f\u7528DNS\u76d1\u6d4b\uff0c\u9ed8\u8ba4\u503c\uff1afalse +spring.redisson.dnsMonitoring=false +#DNS\u76d1\u6d4b\u65f6\u95f4\u95f4\u9694\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2\uff0c\u9ed8\u8ba4\u503c\uff1a5000 +spring.redisson.dnsMonitoringInterval=5000 + + +# elasticsearch +#\u8282\u70b9\u540d\u5b57\uff0c\u9ed8\u8ba4elasticsearch +spring.data.elasticsearch.cluster-name=elasticsearch +# \u8282\u70b9\u5730\u5740\uff0c\u591a\u4e2a\u8282\u70b9\u7528\u9017\u53f7\u9694\u5f00 +spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300 +#spring.data.elasticsearch.local=false +spring.data.elasticsearch.repositories.enable=true + +# ehcache +spring.cache.type=ehcache +spring.cache.ehcache.config=classpath:ehcache.xml \ No newline at end of file diff --git a/src/main/resources/cassandra.properties b/src/main/resources/cassandra.properties new file mode 100644 index 0000000..6b39d8e --- /dev/null +++ b/src/main/resources/cassandra.properties @@ -0,0 +1,3 @@ +cassandra.contactpoints=127.0.0.1 +cassandra.port=9042 +cassandra.keyspace=mydb \ No newline at end of file diff --git a/src/main/resources/couchdb.xml b/src/main/resources/couchdb.xml new file mode 100644 index 0000000..e7d752b --- /dev/null +++ b/src/main/resources/couchdb.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml new file mode 100644 index 0000000..c645ed7 --- /dev/null +++ b/src/main/resources/ehcache.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..00314e0 --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,61 @@ + + + + + /tmp/logs + /tmp/logs/7z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplicationTests.java b/src/test/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplicationTests.java new file mode 100644 index 0000000..9e7aa1c --- /dev/null +++ b/src/test/java/xy/SpringBoot2NoSQL/SpringBoot2NoSqlApplicationTests.java @@ -0,0 +1,16 @@ +package xy.SpringBoot2NoSQL; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringBoot2NoSqlApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git "a/\350\204\232\346\234\254/Cassandra/\345\273\272\345\272\223\350\204\232\346\234\254.txt" "b/\350\204\232\346\234\254/Cassandra/\345\273\272\345\272\223\350\204\232\346\234\254.txt" new file mode 100644 index 0000000..b44c2d4 --- /dev/null +++ "b/\350\204\232\346\234\254/Cassandra/\345\273\272\345\272\223\350\204\232\346\234\254.txt" @@ -0,0 +1,15 @@ +创建keyspace : +create keyspace myDb with replication={'class':'SimpleStrategy', 'replication_factor':1}; + +建表: +use myDb; + +CREATE TABLE customer( + id text PRIMARY KEY, + firstname text, + lastname text, + age int +); + +建索引: +CREATE INDEX ON myDb.customer (firstname); \ No newline at end of file