diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..991728ccc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+target/
+*.iml
+
diff --git a/1.x/README.md b/1.x/README.md
new file mode 100644
index 000000000..03c818122
--- /dev/null
+++ b/1.x/README.md
@@ -0,0 +1,73 @@
+# Spring Boot Examples
+
+Demo website:http://www.ityouknow.com/
+
+[Spring Cloud学习示例代码](https://github.com/ityouknow/spring-cloud-examples)
+
+[Spring Boot 中文索引](https://github.com/ityouknow/awesome-spring-boot)
+
+[参与贡献](https://github.com/ityouknow/spring-boot-examples/issues) | [English](README_EN.md)
+
+**[github地址](https://github.com/ityouknow/spring-boot-examples)**
+
+**[码云地址](https://gitee.com/ityouknow/spring-boot-examples)**
+
+Spring boot使用的各种示例,以最简单、最实用为标准
+
+
+- [spring-boot-helloWorld](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-helloWorld):spring-boot的helloWorld版本
+- [spring-boot-mybaits-annotation](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-annotation):注解版本
+- [spring-boot-mybaits-xml](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-xml):xml配置版本
+- [spring-boot-mybatis-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-mulidatasource):springboot+mybatis多数据源最简解决方案
+- [spring-boot-mybatis-annotation-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-annotation-mulidatasource):springboot+mybatis(注解版)多数据源最简解决方案
+- [spring-boot-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-thymeleaf):simple spring boot thymeleaf demo
+- [spring-boot-jpa-thymeleaf-curd](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-jpa-thymeleaf-curd):spring boot + jpa + thymeleaf 增删改查示例
+- [spring-boot-rabbitmq](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-rabbitmq):spring boot和rabbitmq各种消息应用案例
+- [spring-boot-scheduler](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-scheduler):spring boot和定时任务案例
+- [spring-boot-web](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-web):web开发综合使用案例
+- [spring-boot-mail](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mail):spring boot和邮件服务
+- [spring-boot-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mongodb):spring boot和mongodb的使用
+- [spring-boot-multi-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-multi-mongodb):spring boot和mongodb多数据源的使用
+- [spring-boot-package-war](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-package-war):spring-boot打包成war包示例
+- [spring-boot-shiro](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-shiro):springboot 整合shiro rbac示例
+- [spring-boot-file-upload](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-file-upload):使用Spring Boot 上传文件示例
+- [spring-boot-fastDFS](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-fastDFS):Spring Boot 整合FastDFS示例
+- [spring-boot-actuator](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-actuator):Spring Boot Actuator 使用示例
+- [spring-boot-admin-simple](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-admin-simple):Spring Boot Admin 的使用示例
+
+**[Favorites-web](https://github.com/cloudfavorites/favorites-web):云收藏(springboot实战开源项目)**
+
+
+
+参考文章:
+
+- [springboot(一):入门篇](http://www.ityouknow.com/springboot/2016/01/06/springboot(%E4%B8%80)-%E5%85%A5%E9%97%A8%E7%AF%87.html)
+- [springboot(二):web综合开发](http://www.ityouknow.com/springboot/2016/02/03/springboot(%E4%BA%8C)-web%E7%BB%BC%E5%90%88%E5%BC%80%E5%8F%91.html)
+- [springboot(三):Spring boot中Redis的使用](http://www.ityouknow.com/springboot/2016/03/06/springboot(%E4%B8%89)-Spring-Boot%E4%B8%ADRedis%E7%9A%84%E4%BD%BF%E7%94%A8.html)
+- [springboot(四):thymeleaf使用详解](http://www.ityouknow.com/springboot/2016/05/01/springboot(%E5%9B%9B)-thymeleaf%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3.html)
+- [springboot(五):spring data jpa的使用](http://www.ityouknow.com/springboot/2016/08/20/springboot(%E4%BA%94)-spring-data-jpa%E7%9A%84%E4%BD%BF%E7%94%A8.html)
+- [springboot(六):如何优雅的使用mybatis](http://www.ityouknow.com/springboot/2016/11/06/springboot(%E5%85%AD)-%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E7%9A%84%E4%BD%BF%E7%94%A8mybatis.html)
+- [springboot(七):springboot+mybatis多数据源最简解决方案](http://www.ityouknow.com/springboot/2016/11/25/springboot(%E4%B8%83)-springboot+mybatis%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E6%9C%80%E7%AE%80%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88.html)
+- [springboot(八):RabbitMQ详解](http://www.ityouknow.com/springboot/2016/11/30/springboot(%E5%85%AB)-RabbitMQ%E8%AF%A6%E8%A7%A3.html)
+- [springboot(九):定时任务](http://www.ityouknow.com/springboot/2016/12/02/springboot(%E4%B9%9D)-%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1.html)
+- [springboot(十):邮件服务](http://www.ityouknow.com/springboot/2017/05/06/springboot-mail.html)
+- [springboot(十一):Spring boot中mongodb的使用](http://www.ityouknow.com/springboot/2017/05/08/springboot-mongodb.html)
+- [springboot(十二):springboot如何测试打包部署](http://www.ityouknow.com/springboot/2017/05/09/springboot-deploy.html)
+- [springboot(十三):springboot小技巧](http://www.ityouknow.com/springboot/2017/06/22/springboot-tips.html)
+- [springboot(十四):springboot整合shiro-登录认证和权限管理](http://www.ityouknow.com/springboot/2017/06/26/springboot-shiro.html)
+- [springboot(十五):springboot+jpa+thymeleaf增删改查示例](http://www.ityouknow.com/springboot/2017/09/23/spring-boot-jpa-thymeleaf-curd.html)
+- [springboot(十六):使用Jenkins部署Spring Boot](http://www.ityouknow.com/springboot/2017/11/11/springboot-jenkins.html)
+- [springboot(十七):使用Spring Boot上传文件](http://www.ityouknow.com/springboot/2018/01/12/spring-boot-upload-file.html)
+- [springboot(十八):使用Spring Boot集成FastDFS](http://www.ityouknow.com/springboot/2018/01/16/spring-boot-fastdfs.html)
+- [springboot(十九):使用Spring Boot Actuator监控应用](http://www.ityouknow.com/springboot/2018/02/06/spring-boot-actuator.html)
+- [springboot(二十):使用spring-boot-admin对spring-boot服务进行监控](http://www.ityouknow.com/springboot/2018/02/11/spring-boot-admin.html)
+
+**[springboot实战:我们的第一款开源项目](http://www.ityouknow.com/springboot/2016/09/26/springboot%E5%AE%9E%E6%88%98-%E6%88%91%E4%BB%AC%E7%9A%84%E7%AC%AC%E4%B8%80%E6%AC%BE%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6.html)**
+
+> 如果大家想了解关于springboot的其它方面应用,也可以以[issues](https://github.com/ityouknow/spring-boot-examples/issues)的形式反馈给我,我后续来完善。
+
+
+关注公众号:纯洁的微笑,回复"666"进群交流
+
+
+
diff --git a/1.x/README_EN.md b/1.x/README_EN.md
new file mode 100644
index 000000000..93f67e576
--- /dev/null
+++ b/1.x/README_EN.md
@@ -0,0 +1,33 @@
+# Spring Boot Examples
+
+this is ablout learn Spring Boot Examples
+
+Demo website:http://www.ityouknow.com/
+
+[Spring Cloud example code](https://github.com/ityouknow/spring-cloud-examples)
+
+[Contribution](https://github.com/ityouknow/spring-boot-examples/issues) | [中文](README.md)
+
+Spring Boot Examples, Use the simplest and most useful scene demo.
+
+- [spring-boot-helloWorld](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-helloWorld):Spring Boot helloWorld
+- [spring-boot-mybaits-annotation](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-annotation):Spring Boot use mybatis annotation
+- [spring-boot-mybaits-xml](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-xml):Spring Boot use mybatis xml
+- [spring-boot-mybatis-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-mulidatasource):Spring Boot+mybatis+mulidatasource
+- [spring-boot-mybatis-annotation-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mybatis-annotation-mulidatasource):Spring Boot+ mybatis annotation + mulidatasource
+- [spring-boot-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-thymeleaf):simple spring boot thymeleaf demo
+- [spring-boot-jpa-thymeleaf-curd](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-jpa-thymeleaf-curd):spring boot + jpa + thymeleaf curd demo
+- [spring-boot-rabbitmq](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-rabbitmq): using AMQP and RabbitMQ
+- [spring-boot-scheduler](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-scheduler):Timed tasks developed using Spring Boot
+- [spring-boot-web](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-web):Web projects developed using Spring Boot
+- [spring-boot-mail](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mail):Mail system developed using Spring Boot
+- [spring-boot-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-mongodb):Spring Boot + Mongodb
+- [spring-boot-multi-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-multi-mongodb):Spring Boot + multiMongodb
+- [spring-boot-package-war](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-package-war):Spring Boot package war
+- [spring-boot-shiro](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-shiro):spring boot shiro rbac demo
+- [spring-boot-file-upload](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-file-upload):Spring Boot upload file demo
+- [spring-boot-fastDFS](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-fastDFS):Spring Boot Integrate FastDFS upload delete and so on
+- [spring-boot-actuator](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-actuator):Spring Boot Actuator demo
+- [spring-boot-admin-simple](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x/spring-boot-admin-simple):Spring Boot Admin demo
+
+**[Favorites-web](https://github.com/cloudfavorites/favorites-web):Open source projects developed using Spring Boot**
diff --git a/spring-boot-actuator/pom.xml b/1.x/spring-boot-actuator/pom.xml
similarity index 100%
rename from spring-boot-actuator/pom.xml
rename to 1.x/spring-boot-actuator/pom.xml
diff --git a/spring-boot-actuator/src/main/java/com/neo/ActuatorApplication.java b/1.x/spring-boot-actuator/src/main/java/com/neo/ActuatorApplication.java
similarity index 100%
rename from spring-boot-actuator/src/main/java/com/neo/ActuatorApplication.java
rename to 1.x/spring-boot-actuator/src/main/java/com/neo/ActuatorApplication.java
diff --git a/spring-boot-actuator/src/main/java/com/neo/controller/HelloController.java b/1.x/spring-boot-actuator/src/main/java/com/neo/controller/HelloController.java
similarity index 100%
rename from spring-boot-actuator/src/main/java/com/neo/controller/HelloController.java
rename to 1.x/spring-boot-actuator/src/main/java/com/neo/controller/HelloController.java
diff --git a/spring-boot-actuator/src/main/resources/application.yml b/1.x/spring-boot-actuator/src/main/resources/application.yml
similarity index 100%
rename from spring-boot-actuator/src/main/resources/application.yml
rename to 1.x/spring-boot-actuator/src/main/resources/application.yml
diff --git a/spring-boot-actuator/src/test/java/com/neo/ActuatorApplicationTests.java b/1.x/spring-boot-actuator/src/test/java/com/neo/ActuatorApplicationTests.java
similarity index 100%
rename from spring-boot-actuator/src/test/java/com/neo/ActuatorApplicationTests.java
rename to 1.x/spring-boot-actuator/src/test/java/com/neo/ActuatorApplicationTests.java
diff --git a/spring-boot-actuator/src/test/java/com/neo/controller/HelloTests.java b/1.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloTests.java
similarity index 100%
rename from spring-boot-actuator/src/test/java/com/neo/controller/HelloTests.java
rename to 1.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloTests.java
diff --git a/spring-boot-actuator/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/1.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloWorldControlerTests.java
similarity index 100%
rename from spring-boot-actuator/src/test/java/com/neo/controller/HelloWorldControlerTests.java
rename to 1.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloWorldControlerTests.java
diff --git a/spring-boot-admin-simple/pom.xml b/1.x/spring-boot-admin-simple/pom.xml
similarity index 100%
rename from spring-boot-admin-simple/pom.xml
rename to 1.x/spring-boot-admin-simple/pom.xml
diff --git a/spring-boot-admin-simple/spring-boot-admin-client/pom.xml b/1.x/spring-boot-admin-simple/spring-boot-admin-client/pom.xml
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-client/pom.xml
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-client/pom.xml
diff --git a/spring-boot-admin-simple/spring-boot-admin-client/src/main/java/com/neo/AdminClientApplication.java b/1.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/java/com/neo/AdminClientApplication.java
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-client/src/main/java/com/neo/AdminClientApplication.java
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/java/com/neo/AdminClientApplication.java
diff --git a/spring-boot-admin-simple/spring-boot-admin-client/src/main/resources/application.properties b/1.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-client/src/main/resources/application.properties
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/resources/application.properties
diff --git a/spring-boot-admin-simple/spring-boot-admin-client/src/test/java/com/neo/AdminClientApplicationTests.java b/1.x/spring-boot-admin-simple/spring-boot-admin-client/src/test/java/com/neo/AdminClientApplicationTests.java
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-client/src/test/java/com/neo/AdminClientApplicationTests.java
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-client/src/test/java/com/neo/AdminClientApplicationTests.java
diff --git a/spring-boot-admin-simple/spring-boot-admin-server/pom.xml b/1.x/spring-boot-admin-simple/spring-boot-admin-server/pom.xml
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-server/pom.xml
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-server/pom.xml
diff --git a/spring-boot-admin-simple/spring-boot-admin-server/src/main/java/com/neo/AdminServerApplication.java b/1.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/java/com/neo/AdminServerApplication.java
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-server/src/main/java/com/neo/AdminServerApplication.java
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/java/com/neo/AdminServerApplication.java
diff --git a/spring-boot-admin-simple/spring-boot-admin-server/src/main/resources/application.properties b/1.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-server/src/main/resources/application.properties
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/resources/application.properties
diff --git a/spring-boot-admin-simple/spring-boot-admin-server/src/test/java/com/neo/AdminServerApplicationTests.java b/1.x/spring-boot-admin-simple/spring-boot-admin-server/src/test/java/com/neo/AdminServerApplicationTests.java
similarity index 100%
rename from spring-boot-admin-simple/spring-boot-admin-server/src/test/java/com/neo/AdminServerApplicationTests.java
rename to 1.x/spring-boot-admin-simple/spring-boot-admin-server/src/test/java/com/neo/AdminServerApplicationTests.java
diff --git a/spring-boot-fastDFS/pom.xml b/1.x/spring-boot-fastDFS/pom.xml
similarity index 100%
rename from spring-boot-fastDFS/pom.xml
rename to 1.x/spring-boot-fastDFS/pom.xml
diff --git a/spring-boot-fastDFS/src/main/java/com/neo/FastDFSApplication.java b/1.x/spring-boot-fastDFS/src/main/java/com/neo/FastDFSApplication.java
similarity index 100%
rename from spring-boot-fastDFS/src/main/java/com/neo/FastDFSApplication.java
rename to 1.x/spring-boot-fastDFS/src/main/java/com/neo/FastDFSApplication.java
diff --git a/spring-boot-fastDFS/src/main/java/com/neo/controller/GlobalExceptionHandler.java b/1.x/spring-boot-fastDFS/src/main/java/com/neo/controller/GlobalExceptionHandler.java
similarity index 100%
rename from spring-boot-fastDFS/src/main/java/com/neo/controller/GlobalExceptionHandler.java
rename to 1.x/spring-boot-fastDFS/src/main/java/com/neo/controller/GlobalExceptionHandler.java
diff --git a/spring-boot-fastDFS/src/main/java/com/neo/controller/UploadController.java b/1.x/spring-boot-fastDFS/src/main/java/com/neo/controller/UploadController.java
similarity index 100%
rename from spring-boot-fastDFS/src/main/java/com/neo/controller/UploadController.java
rename to 1.x/spring-boot-fastDFS/src/main/java/com/neo/controller/UploadController.java
diff --git a/1.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSClient.java b/1.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSClient.java
new file mode 100644
index 000000000..ce9555029
--- /dev/null
+++ b/1.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSClient.java
@@ -0,0 +1,104 @@
+package com.neo.fastdfs;
+
+import org.csource.common.NameValuePair;
+import org.csource.fastdfs.*;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import java.io.*;
+
+public class FastDFSClient {
+ private static org.slf4j.Logger logger = LoggerFactory.getLogger(FastDFSClient.class);
+ private static TrackerClient trackerClient;
+ private static TrackerServer trackerServer;
+ private static StorageClient storageClient;
+ private static StorageServer storageServer;
+
+ static {
+ try {
+ String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();;
+ ClientGlobal.init(filePath);
+ trackerClient = new TrackerClient();
+ trackerServer = trackerClient.getConnection();
+ storageServer = trackerClient.getStoreStorage(trackerServer);
+ } catch (Exception e) {
+ logger.error("FastDFS Client Init Fail!",e);
+ }
+ }
+
+ public static String[] upload(FastDFSFile file) {
+ logger.info("File Name: " + file.getName() + "File Length:" + file.getContent().length);
+
+ NameValuePair[] meta_list = new NameValuePair[1];
+ meta_list[0] = new NameValuePair("author", file.getAuthor());
+
+ long startTime = System.currentTimeMillis();
+ String[] uploadResults = null;
+ try {
+ storageClient = new StorageClient(trackerServer, storageServer);
+ uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
+ } catch (IOException e) {
+ logger.error("IO Exception when uploadind the file:" + file.getName(), e);
+ } catch (Exception e) {
+ logger.error("Non IO Exception when uploadind the file:" + file.getName(), e);
+ }
+ logger.info("upload_file time used:" + (System.currentTimeMillis() - startTime) + " ms");
+
+ if (uploadResults == null) {
+ logger.error("upload file fail, error code:" + storageClient.getErrorCode());
+ }
+ String groupName = uploadResults[0];
+ String remoteFileName = uploadResults[1];
+
+ logger.info("upload file successfully!!!" + "group_name:" + groupName + ", remoteFileName:" + " " + remoteFileName);
+ return uploadResults;
+ }
+
+ public static FileInfo getFile(String groupName, String remoteFileName) {
+ try {
+ storageClient = new StorageClient(trackerServer, storageServer);
+ return storageClient.get_file_info(groupName, remoteFileName);
+ } catch (IOException e) {
+ logger.error("IO Exception: Get File from Fast DFS failed", e);
+ } catch (Exception e) {
+ logger.error("Non IO Exception: Get File from Fast DFS failed", e);
+ }
+ return null;
+ }
+
+ public static InputStream downFile(String groupName, String remoteFileName) {
+ try {
+ storageClient = new StorageClient(trackerServer, storageServer);
+ byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
+ InputStream ins = new ByteArrayInputStream(fileByte);
+ return ins;
+ } catch (IOException e) {
+ logger.error("IO Exception: Get File from Fast DFS failed", e);
+ } catch (Exception e) {
+ logger.error("Non IO Exception: Get File from Fast DFS failed", e);
+ }
+ return null;
+ }
+
+ public static void deleteFile(String groupName, String remoteFileName)
+ throws Exception {
+ storageClient = new StorageClient(trackerServer, storageServer);
+ int i = storageClient.delete_file(groupName, remoteFileName);
+ logger.info("delete file successfully!!!" + i);
+ }
+
+ public static StorageServer[] getStoreStorages(String groupName)
+ throws IOException {
+ return trackerClient.getStoreStorages(trackerServer, groupName);
+ }
+
+ public static ServerInfo[] getFetchStorages(String groupName,
+ String remoteFileName) throws IOException {
+ return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
+ }
+
+ public static String getTrackerUrl() {
+ return "http://"+trackerServer.getInetSocketAddress().getHostString()+":"+ClientGlobal.getG_tracker_http_port()+"/";
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSFile.java b/1.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSFile.java
similarity index 100%
rename from spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSFile.java
rename to 1.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSFile.java
diff --git a/spring-boot-fastDFS/src/main/resources/application.properties b/1.x/spring-boot-fastDFS/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-fastDFS/src/main/resources/application.properties
rename to 1.x/spring-boot-fastDFS/src/main/resources/application.properties
diff --git a/spring-boot-fastDFS/src/main/resources/fdfs_client.conf b/1.x/spring-boot-fastDFS/src/main/resources/fdfs_client.conf
similarity index 100%
rename from spring-boot-fastDFS/src/main/resources/fdfs_client.conf
rename to 1.x/spring-boot-fastDFS/src/main/resources/fdfs_client.conf
diff --git a/spring-boot-fastDFS/src/main/resources/logback.xml b/1.x/spring-boot-fastDFS/src/main/resources/logback.xml
similarity index 100%
rename from spring-boot-fastDFS/src/main/resources/logback.xml
rename to 1.x/spring-boot-fastDFS/src/main/resources/logback.xml
diff --git a/spring-boot-fastDFS/src/main/resources/templates/upload.html b/1.x/spring-boot-fastDFS/src/main/resources/templates/upload.html
similarity index 100%
rename from spring-boot-fastDFS/src/main/resources/templates/upload.html
rename to 1.x/spring-boot-fastDFS/src/main/resources/templates/upload.html
diff --git a/spring-boot-fastDFS/src/main/resources/templates/uploadStatus.html b/1.x/spring-boot-fastDFS/src/main/resources/templates/uploadStatus.html
similarity index 100%
rename from spring-boot-fastDFS/src/main/resources/templates/uploadStatus.html
rename to 1.x/spring-boot-fastDFS/src/main/resources/templates/uploadStatus.html
diff --git a/1.x/spring-boot-file-upload/pom.xml b/1.x/spring-boot-file-upload/pom.xml
new file mode 100644
index 000000000..731cfa08c
--- /dev/null
+++ b/1.x/spring-boot-file-upload/pom.xml
@@ -0,0 +1,48 @@
+
+ 4.0.0
+
+ com.neo
+ spring-boot-file-upload
+ jar
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.9.RELEASE
+
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/1.x/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java b/1.x/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java
new file mode 100644
index 000000000..6e355e38d
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java
@@ -0,0 +1,30 @@
+package com.neo;
+
+import org.apache.coyote.http11.AbstractHttp11Protocol;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
+import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication
+public class FileUploadWebApplication {
+
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(FileUploadWebApplication.class, args);
+ }
+
+ //Tomcat large file upload connection reset
+ @Bean
+ public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {
+ TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
+ tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
+ if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol>)) {
+ //-1 means unlimited
+ ((AbstractHttp11Protocol>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
+ }
+ });
+ return tomcat;
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java b/1.x/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java
new file mode 100644
index 000000000..8f5caf6cc
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java
@@ -0,0 +1,18 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.multipart.MultipartException;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+ //https://jira.spring.io/browse/SPR-14651
+ //4.3.5 supports RedirectAttributes redirectAttributes
+ @ExceptionHandler(MultipartException.class)
+ public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {
+ redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
+ return "redirect:/uploadStatus";
+ }
+}
diff --git a/1.x/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java b/1.x/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java
new file mode 100644
index 000000000..13d3ab467
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java
@@ -0,0 +1,54 @@
+package com.neo.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Controller
+public class UploadController {
+ //Save the uploaded file to this folder
+ private static String UPLOADED_FOLDER = "E://temp//";
+
+ @GetMapping("/")
+ public String index() {
+ return "upload";
+ }
+
+ @PostMapping("/upload") // //new annotation since 4.3
+ public String singleFileUpload(@RequestParam("file") MultipartFile file,
+ RedirectAttributes redirectAttributes) {
+ if (file.isEmpty()) {
+ redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
+ return "redirect:uploadStatus";
+ }
+
+ try {
+ // Get the file and save it somewhere
+ byte[] bytes = file.getBytes();
+ Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
+ Files.write(path, bytes);
+
+ redirectAttributes.addFlashAttribute("message",
+ "You successfully uploaded '" + file.getOriginalFilename() + "'");
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return "redirect:/uploadStatus";
+ }
+
+ @GetMapping("/uploadStatus")
+ public String uploadStatus() {
+ return "uploadStatus";
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-file-upload/src/main/resources/application.properties b/1.x/spring-boot-file-upload/src/main/resources/application.properties
new file mode 100644
index 000000000..8ec671da4
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/resources/application.properties
@@ -0,0 +1,11 @@
+#http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
+#search multipart
+spring.http.multipart.max-file-size=10MB
+spring.http.multipart.max-request-size=10MB
+
+#spring.http.multipart.enabled=true #\u9ED8\u8BA4\u652F\u6301\u6587\u4EF6\u4E0A\u4F20.
+#spring.http.multipart.file-size-threshold=0 #\u652F\u6301\u6587\u4EF6\u5199\u5165\u78C1\u76D8.
+#spring.http.multipart.location= # \u4E0A\u4F20\u6587\u4EF6\u7684\u4E34\u65F6\u76EE\u5F55
+#spring.http.multipart.max-file-size=1Mb # \u6700\u5927\u652F\u6301\u6587\u4EF6\u5927\u5C0F
+#spring.http.multipart.max-request-size=10Mb # \u6700\u5927\u652F\u6301\u8BF7\u6C42\u5927\u5C0F
+
diff --git a/1.x/spring-boot-file-upload/src/main/resources/logback.xml b/1.x/spring-boot-file-upload/src/main/resources/logback.xml
new file mode 100644
index 000000000..0c0f833bc
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/resources/logback.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.x/spring-boot-file-upload/src/main/resources/templates/from_file.html b/1.x/spring-boot-file-upload/src/main/resources/templates/from_file.html
new file mode 100644
index 000000000..3f95f35e1
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/resources/templates/from_file.html
@@ -0,0 +1,51 @@
+
+
+
+
\ No newline at end of file
diff --git a/1.x/spring-boot-file-upload/src/main/resources/templates/upload.html b/1.x/spring-boot-file-upload/src/main/resources/templates/upload.html
new file mode 100644
index 000000000..2e93a58dd
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/resources/templates/upload.html
@@ -0,0 +1,13 @@
+
+
+
+
+Spring Boot file upload example
+
+
+
+
+
diff --git a/1.x/spring-boot-file-upload/src/main/resources/templates/uploadStatus.html b/1.x/spring-boot-file-upload/src/main/resources/templates/uploadStatus.html
new file mode 100644
index 000000000..71fb76d3c
--- /dev/null
+++ b/1.x/spring-boot-file-upload/src/main/resources/templates/uploadStatus.html
@@ -0,0 +1,12 @@
+
+
+
+
+Spring Boot - Upload Status
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.x/spring-boot-helloWorld/pom.xml b/1.x/spring-boot-helloWorld/pom.xml
new file mode 100644
index 000000000..c8280ef2e
--- /dev/null
+++ b/1.x/spring-boot-helloWorld/pom.xml
@@ -0,0 +1,62 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-helloworld
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-helloworld
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.6.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/spring-boot-package-war/src/main/java/com/neo/Application.java b/1.x/spring-boot-helloWorld/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-package-war/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-helloWorld/src/main/java/com/neo/Application.java
diff --git a/1.x/spring-boot-helloWorld/src/main/java/com/neo/controller/HelloWorldController.java b/1.x/spring-boot-helloWorld/src/main/java/com/neo/controller/HelloWorldController.java
new file mode 100644
index 000000000..7d0256b4a
--- /dev/null
+++ b/1.x/spring-boot-helloWorld/src/main/java/com/neo/controller/HelloWorldController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloWorldController {
+
+ @RequestMapping("/hello")
+ public String index() {
+ return "Hello World";
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-package-war/src/main/resources/application.properties b/1.x/spring-boot-helloWorld/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-package-war/src/main/resources/application.properties
rename to 1.x/spring-boot-helloWorld/src/main/resources/application.properties
diff --git a/1.x/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java
new file mode 100644
index 000000000..1faf3f2e7
--- /dev/null
+++ b/1.x/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello word");
+ }
+
+}
diff --git a/1.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java b/1.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java
new file mode 100644
index 000000000..d42211135
--- /dev/null
+++ b/1.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java
@@ -0,0 +1,39 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloTests {
+
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/1.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloWorldControlerTests.java
similarity index 100%
rename from spring-boot-helloWorld/src/test/java/com/neo/controller/HelloWorldControlerTests.java
rename to 1.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloWorldControlerTests.java
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/pom.xml b/1.x/spring-boot-jpa-thymeleaf-curd/pom.xml
new file mode 100644
index 000000000..caa8ecc56
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+ spring-boot-jpa-thymeleaf-curd
+ spring-boot-jpa-thymeleaf-curd
+ spring-boot-jpa-thymeleaf-curd
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.6.RELEASE
+
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java
new file mode 100644
index 000000000..92f4c0aec
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java
@@ -0,0 +1,20 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+
+@SpringBootApplication
+public class JpaThymeleafApplication extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(JpaThymeleafApplication.class);
+ }
+
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(JpaThymeleafApplication.class, args);
+ }
+}
+
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/entity/User.java b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/entity/User.java
similarity index 100%
rename from spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/entity/User.java
rename to 1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/entity/User.java
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..14821f515
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,11 @@
+package com.neo.repository;
+
+import com.neo.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserRepository extends JpaRepository {
+
+ User findById(long id);
+
+ Long deleteById(Long id);
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java
new file mode 100644
index 000000000..be9becb4e
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java
@@ -0,0 +1,20 @@
+package com.neo.service;
+
+import com.neo.entity.User;
+
+import java.util.List;
+
+public interface UserService {
+
+ public List getUserList();
+
+ public User findUserById(long id);
+
+ public void save(User user);
+
+ public void edit(User user);
+
+ public void delete(long id);
+
+
+}
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java
new file mode 100644
index 000000000..8e66fad24
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java
@@ -0,0 +1,44 @@
+package com.neo.service.impl;
+
+import com.neo.entity.User;
+import com.neo.repository.UserRepository;
+import com.neo.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class UserServiceImpl implements UserService{
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Override
+ public List getUserList() {
+ return userRepository.findAll();
+ }
+
+ @Override
+ public User findUserById(long id) {
+ return userRepository.findById(id);
+ }
+
+ @Override
+ public void save(User user) {
+ userRepository.save(user);
+ }
+
+ @Override
+ public void edit(User user) {
+ userRepository.save(user);
+ }
+
+ @Override
+ public void delete(long id) {
+ userRepository.delete(id);
+ }
+}
+
+
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/HelloController.java b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..82136eb19
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,16 @@
+package com.neo.web;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Controller
+public class HelloController {
+
+ @RequestMapping("/hello")
+ public String hello(Model model, @RequestParam(value="name", required=false, defaultValue="World") String name) {
+ model.addAttribute("name", name);
+ return "hello";
+ }
+}
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..02eef58ae
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,63 @@
+package com.neo.web;
+
+import com.neo.entity.User;
+import com.neo.service.UserService;
+import org.springframework.stereotype.Controller;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Controller
+public class UserController {
+
+ @Resource
+ UserService userService;
+
+
+ @RequestMapping("/")
+ public String index() {
+ return "redirect:/list";
+ }
+
+ @RequestMapping("/list")
+ public String list(Model model) {
+ List users=userService.getUserList();
+ model.addAttribute("users", users);
+ return "user/list";
+ }
+
+ @RequestMapping("/toAdd")
+ public String toAdd() {
+ return "user/userAdd";
+ }
+
+ @RequestMapping("/add")
+ public String add(User user) {
+ userService.save(user);
+ return "redirect:/list";
+ }
+
+ @RequestMapping("/toEdit")
+ public String toEdit(Model model,Long id) {
+ User user=userService.findUserById(id);
+ model.addAttribute("user", user);
+ return "user/userEdit";
+ }
+
+ @RequestMapping("/edit")
+ public String edit(User user) {
+ userService.edit(user);
+ return "redirect:/list";
+ }
+
+
+ @RequestMapping("/delete")
+ public String delete(Long id) {
+ userService.delete(id);
+ return "redirect:/list";
+ }
+}
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties
new file mode 100644
index 000000000..65ff9c384
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties
@@ -0,0 +1,10 @@
+spring.datasource.url=jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+
+spring.jpa.properties.hibernate.hbm2ddl.auto=update
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.show-sql= true
+
+spring.thymeleaf.cache=false
\ No newline at end of file
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/static/css/bootstrap.css b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/static/css/bootstrap.css
new file mode 100644
index 000000000..42c79d6e4
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/static/css/bootstrap.css
@@ -0,0 +1,6760 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+[hidden],
+template {
+ display: none;
+}
+a {
+ background-color: transparent;
+}
+a:active,
+a:hover {
+ outline: 0;
+}
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+b,
+strong {
+ font-weight: bold;
+}
+dfn {
+ font-style: italic;
+}
+h1 {
+ margin: .67em 0;
+ font-size: 2em;
+}
+mark {
+ color: #000;
+ background: #ff0;
+}
+small {
+ font-size: 80%;
+}
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+sup {
+ top: -.5em;
+}
+sub {
+ bottom: -.25em;
+}
+img {
+ border: 0;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 1em 40px;
+}
+hr {
+ height: 0;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+pre {
+ overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0;
+ font: inherit;
+ color: inherit;
+}
+button {
+ overflow: visible;
+}
+button,
+select {
+ text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+input {
+ line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+fieldset {
+ padding: .35em .625em .75em;
+ margin: 0 2px;
+ border: 1px solid #c0c0c0;
+}
+legend {
+ padding: 0;
+ border: 0;
+}
+textarea {
+ overflow: auto;
+}
+optgroup {
+ font-weight: bold;
+}
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+td,
+th {
+ padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ }
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+ pre,
+ blockquote {
+ border: 1px solid #999;
+
+ page-break-inside: avoid;
+ }
+ thead {
+ display: table-header-group;
+ }
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+ img {
+ max-width: 100% !important;
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+ .navbar {
+ display: none;
+ }
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+ .label {
+ border: 1px solid #000;
+ }
+ .table {
+ border-collapse: collapse !important;
+ }
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+@font-face {
+ font-family: 'Glyphicons Halflings';
+
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.glyphicon-asterisk:before {
+ content: "\002a";
+}
+.glyphicon-plus:before {
+ content: "\002b";
+}
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+.glyphicon-minus:before {
+ content: "\2212";
+}
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+.glyphicon-glass:before {
+ content: "\e001";
+}
+.glyphicon-music:before {
+ content: "\e002";
+}
+.glyphicon-search:before {
+ content: "\e003";
+}
+.glyphicon-heart:before {
+ content: "\e005";
+}
+.glyphicon-star:before {
+ content: "\e006";
+}
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+.glyphicon-user:before {
+ content: "\e008";
+}
+.glyphicon-film:before {
+ content: "\e009";
+}
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+.glyphicon-th:before {
+ content: "\e011";
+}
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+.glyphicon-ok:before {
+ content: "\e013";
+}
+.glyphicon-remove:before {
+ content: "\e014";
+}
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+.glyphicon-off:before {
+ content: "\e017";
+}
+.glyphicon-signal:before {
+ content: "\e018";
+}
+.glyphicon-cog:before {
+ content: "\e019";
+}
+.glyphicon-trash:before {
+ content: "\e020";
+}
+.glyphicon-home:before {
+ content: "\e021";
+}
+.glyphicon-file:before {
+ content: "\e022";
+}
+.glyphicon-time:before {
+ content: "\e023";
+}
+.glyphicon-road:before {
+ content: "\e024";
+}
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+.glyphicon-download:before {
+ content: "\e026";
+}
+.glyphicon-upload:before {
+ content: "\e027";
+}
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+.glyphicon-lock:before {
+ content: "\e033";
+}
+.glyphicon-flag:before {
+ content: "\e034";
+}
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+.glyphicon-tag:before {
+ content: "\e041";
+}
+.glyphicon-tags:before {
+ content: "\e042";
+}
+.glyphicon-book:before {
+ content: "\e043";
+}
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+.glyphicon-print:before {
+ content: "\e045";
+}
+.glyphicon-camera:before {
+ content: "\e046";
+}
+.glyphicon-font:before {
+ content: "\e047";
+}
+.glyphicon-bold:before {
+ content: "\e048";
+}
+.glyphicon-italic:before {
+ content: "\e049";
+}
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+.glyphicon-list:before {
+ content: "\e056";
+}
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+.glyphicon-picture:before {
+ content: "\e060";
+}
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+.glyphicon-tint:before {
+ content: "\e064";
+}
+.glyphicon-edit:before {
+ content: "\e065";
+}
+.glyphicon-share:before {
+ content: "\e066";
+}
+.glyphicon-check:before {
+ content: "\e067";
+}
+.glyphicon-move:before {
+ content: "\e068";
+}
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+.glyphicon-backward:before {
+ content: "\e071";
+}
+.glyphicon-play:before {
+ content: "\e072";
+}
+.glyphicon-pause:before {
+ content: "\e073";
+}
+.glyphicon-stop:before {
+ content: "\e074";
+}
+.glyphicon-forward:before {
+ content: "\e075";
+}
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+.glyphicon-eject:before {
+ content: "\e078";
+}
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+.glyphicon-gift:before {
+ content: "\e102";
+}
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+.glyphicon-fire:before {
+ content: "\e104";
+}
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+.glyphicon-plane:before {
+ content: "\e108";
+}
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+.glyphicon-random:before {
+ content: "\e110";
+}
+.glyphicon-comment:before {
+ content: "\e111";
+}
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+.glyphicon-bell:before {
+ content: "\e123";
+}
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+.glyphicon-globe:before {
+ content: "\e135";
+}
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+.glyphicon-filter:before {
+ content: "\e138";
+}
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+.glyphicon-link:before {
+ content: "\e144";
+}
+.glyphicon-phone:before {
+ content: "\e145";
+}
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+.glyphicon-usd:before {
+ content: "\e148";
+}
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+.glyphicon-sort:before {
+ content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+.glyphicon-expand:before {
+ content: "\e158";
+}
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+.glyphicon-flash:before {
+ content: "\e162";
+}
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+.glyphicon-record:before {
+ content: "\e165";
+}
+.glyphicon-save:before {
+ content: "\e166";
+}
+.glyphicon-open:before {
+ content: "\e167";
+}
+.glyphicon-saved:before {
+ content: "\e168";
+}
+.glyphicon-import:before {
+ content: "\e169";
+}
+.glyphicon-export:before {
+ content: "\e170";
+}
+.glyphicon-send:before {
+ content: "\e171";
+}
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+.glyphicon-header:before {
+ content: "\e180";
+}
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+.glyphicon-tower:before {
+ content: "\e184";
+}
+.glyphicon-stats:before {
+ content: "\e185";
+}
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+.glyphicon-cd:before {
+ content: "\e201";
+}
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+.glyphicon-copy:before {
+ content: "\e205";
+}
+.glyphicon-paste:before {
+ content: "\e206";
+}
+.glyphicon-alert:before {
+ content: "\e209";
+}
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+.glyphicon-king:before {
+ content: "\e211";
+}
+.glyphicon-queen:before {
+ content: "\e212";
+}
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+.glyphicon-knight:before {
+ content: "\e215";
+}
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+.glyphicon-bed:before {
+ content: "\e219";
+}
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+.glyphicon-erase:before {
+ content: "\e221";
+}
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+.glyphicon-btc:before {
+ content: "\e227";
+}
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+.glyphicon-scale:before {
+ content: "\e230";
+}
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+.glyphicon-education:before {
+ content: "\e233";
+}
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+.glyphicon-oil:before {
+ content: "\e238";
+}
+.glyphicon-grain:before {
+ content: "\e239";
+}
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+.glyphicon-console:before {
+ content: "\e254";
+}
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html {
+ font-size: 10px;
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+a {
+ color: #337ab7;
+ text-decoration: none;
+}
+a:hover,
+a:focus {
+ color: #23527c;
+ text-decoration: underline;
+}
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+figure {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+.img-rounded {
+ border-radius: 6px;
+}
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
+}
+.img-circle {
+ border-radius: 50%;
+}
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eee;
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+[role="button"] {
+ cursor: pointer;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+h1,
+.h1 {
+ font-size: 36px;
+}
+h2,
+.h2 {
+ font-size: 30px;
+}
+h3,
+.h3 {
+ font-size: 24px;
+}
+h4,
+.h4 {
+ font-size: 18px;
+}
+h5,
+.h5 {
+ font-size: 14px;
+}
+h6,
+.h6 {
+ font-size: 12px;
+}
+p {
+ margin: 0 0 10px;
+}
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+small,
+.small {
+ font-size: 85%;
+}
+mark,
+.mark {
+ padding: .2em;
+ background-color: #fcf8e3;
+}
+.text-left {
+ text-align: left;
+}
+.text-right {
+ text-align: right;
+}
+.text-center {
+ text-align: center;
+}
+.text-justify {
+ text-align: justify;
+}
+.text-nowrap {
+ white-space: nowrap;
+}
+.text-lowercase {
+ text-transform: lowercase;
+}
+.text-uppercase {
+ text-transform: uppercase;
+}
+.text-capitalize {
+ text-transform: capitalize;
+}
+.text-muted {
+ color: #777;
+}
+.text-primary {
+ color: #337ab7;
+}
+a.text-primary:hover,
+a.text-primary:focus {
+ color: #286090;
+}
+.text-success {
+ color: #3c763d;
+}
+a.text-success:hover,
+a.text-success:focus {
+ color: #2b542c;
+}
+.text-info {
+ color: #31708f;
+}
+a.text-info:hover,
+a.text-info:focus {
+ color: #245269;
+}
+.text-warning {
+ color: #8a6d3b;
+}
+a.text-warning:hover,
+a.text-warning:focus {
+ color: #66512c;
+}
+.text-danger {
+ color: #a94442;
+}
+a.text-danger:hover,
+a.text-danger:focus {
+ color: #843534;
+}
+.bg-primary {
+ color: #fff;
+ background-color: #337ab7;
+}
+a.bg-primary:hover,
+a.bg-primary:focus {
+ background-color: #286090;
+}
+.bg-success {
+ background-color: #dff0d8;
+}
+a.bg-success:hover,
+a.bg-success:focus {
+ background-color: #c1e2b3;
+}
+.bg-info {
+ background-color: #d9edf7;
+}
+a.bg-info:hover,
+a.bg-info:focus {
+ background-color: #afd9ee;
+}
+.bg-warning {
+ background-color: #fcf8e3;
+}
+a.bg-warning:hover,
+a.bg-warning:focus {
+ background-color: #f7ecb5;
+}
+.bg-danger {
+ background-color: #f2dede;
+}
+a.bg-danger:hover,
+a.bg-danger:focus {
+ background-color: #e4b9b9;
+}
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eee;
+}
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none;
+}
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
+}
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+dt,
+dd {
+ line-height: 1.42857143;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777;
+}
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eee;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #333;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+}
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+.row {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+.col-xs-12 {
+ width: 100%;
+}
+.col-xs-11 {
+ width: 91.66666667%;
+}
+.col-xs-10 {
+ width: 83.33333333%;
+}
+.col-xs-9 {
+ width: 75%;
+}
+.col-xs-8 {
+ width: 66.66666667%;
+}
+.col-xs-7 {
+ width: 58.33333333%;
+}
+.col-xs-6 {
+ width: 50%;
+}
+.col-xs-5 {
+ width: 41.66666667%;
+}
+.col-xs-4 {
+ width: 33.33333333%;
+}
+.col-xs-3 {
+ width: 25%;
+}
+.col-xs-2 {
+ width: 16.66666667%;
+}
+.col-xs-1 {
+ width: 8.33333333%;
+}
+.col-xs-pull-12 {
+ right: 100%;
+}
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+.col-xs-pull-9 {
+ right: 75%;
+}
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+.col-xs-pull-6 {
+ right: 50%;
+}
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+.col-xs-pull-3 {
+ right: 25%;
+}
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+.col-xs-pull-0 {
+ right: auto;
+}
+.col-xs-push-12 {
+ left: 100%;
+}
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+.col-xs-push-9 {
+ left: 75%;
+}
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+.col-xs-push-6 {
+ left: 50%;
+}
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+.col-xs-push-3 {
+ left: 25%;
+}
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+.col-xs-push-0 {
+ left: auto;
+}
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+ .col-sm-3 {
+ width: 25%;
+ }
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-sm-pull-0 {
+ right: auto;
+ }
+ .col-sm-push-12 {
+ left: 100%;
+ }
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+ .col-sm-push-9 {
+ left: 75%;
+ }
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+ .col-sm-push-6 {
+ left: 50%;
+ }
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+ .col-sm-push-3 {
+ left: 25%;
+ }
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+ .col-sm-push-0 {
+ left: auto;
+ }
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-sm-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+ .col-md-pull-12 {
+ right: 100%;
+ }
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-md-pull-9 {
+ right: 75%;
+ }
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-md-pull-6 {
+ right: 50%;
+ }
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-md-pull-3 {
+ right: 25%;
+ }
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-md-pull-0 {
+ right: auto;
+ }
+ .col-md-push-12 {
+ left: 100%;
+ }
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+ .col-md-push-9 {
+ left: 75%;
+ }
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+ .col-md-push-6 {
+ left: 50%;
+ }
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+ .col-md-push-3 {
+ left: 25%;
+ }
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+ .col-md-push-0 {
+ left: auto;
+ }
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-md-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+ .col-lg-9 {
+ width: 75%;
+ }
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-lg-pull-0 {
+ right: auto;
+ }
+ .col-lg-push-12 {
+ left: 100%;
+ }
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+ .col-lg-push-9 {
+ left: 75%;
+ }
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+ .col-lg-push-6 {
+ left: 50%;
+ }
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+ .col-lg-push-3 {
+ left: 25%;
+ }
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+ .col-lg-push-0 {
+ left: auto;
+ }
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-lg-offset-0 {
+ margin-left: 0;
+ }
+}
+table {
+ background-color: transparent;
+}
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777;
+ text-align: left;
+}
+th {
+ text-align: left;
+}
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd;
+}
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+.table > tbody + tbody {
+ border-top: 2px solid #ddd;
+}
+.table .table {
+ background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+.table-bordered {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+ position: static;
+ display: table-column;
+ float: none;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ display: table-cell;
+ float: none;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
+}
+.table-responsive {
+ min-height: .01%;
+ overflow-x: auto;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd;
+ }
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+input[type="file"] {
+ display: block;
+}
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+select[multiple],
+select[size] {
+ height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+}
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+ color: #999;
+}
+.form-control::-webkit-input-placeholder {
+ color: #999;
+}
+.form-control::-ms-expand {
+ background-color: transparent;
+ border: 0;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #eee;
+ opacity: 1;
+}
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+textarea.form-control {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: none;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"].form-control,
+ input[type="time"].form-control,
+ input[type="datetime-local"].form-control,
+ input[type="month"].form-control {
+ line-height: 34px;
+ }
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 46px;
+ }
+}
+.form-group {
+ margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ vertical-align: middle;
+ cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+.form-control-static {
+ min-height: 34px;
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.form-group-sm select.form-control {
+ height: 30px;
+ line-height: 30px;
+}
+.form-group-sm textarea.form-control,
+.form-group-sm select[multiple].form-control {
+ height: auto;
+}
+.form-group-sm .form-control-static {
+ height: 30px;
+ min-height: 32px;
+ padding: 6px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+.form-group-lg select.form-control {
+ height: 46px;
+ line-height: 46px;
+}
+.form-group-lg textarea.form-control,
+.form-group-lg select[multiple].form-control {
+ height: auto;
+}
+.form-group-lg .form-control-static {
+ height: 46px;
+ min-height: 38px;
+ padding: 11px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.has-feedback {
+ position: relative;
+}
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #3c763d;
+}
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d;
+}
+.has-success .form-control-feedback {
+ color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #8a6d3b;
+}
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #8a6d3b;
+}
+.has-warning .form-control-feedback {
+ color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #a94442;
+}
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+.has-error .form-control-feedback {
+ color: #a94442;
+}
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373;
+}
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
+ }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 11px;
+ font-size: 18px;
+ }
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ font-size: 12px;
+ }
+}
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #333;
+ text-decoration: none;
+}
+.btn:active,
+.btn.active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+.btn-default:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default .badge {
+ color: #fff;
+ background-color: #333;
+}
+.btn-primary {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+ color: #fff;
+ background-color: #286090;
+ border-color: #122b40;
+}
+.btn-primary:hover {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+ color: #fff;
+ background-color: #204d74;
+ border-color: #122b40;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+.btn-success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+.btn-info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+.btn-warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+.btn-danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+.btn-link {
+ font-weight: normal;
+ color: #337ab7;
+ border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+ color: #23527c;
+ text-decoration: underline;
+ background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777;
+ text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-block {
+ display: block;
+ width: 100%;
+}
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
+}
+.fade.in {
+ opacity: 1;
+}
+.collapse {
+ display: none;
+}
+.collapse.in {
+ display: block;
+}
+tr.collapse.in {
+ display: table-row;
+}
+tbody.collapse.in {
+ display: table-row-group;
+}
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility;
+}
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-top: 4px solid \9;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+.dropup,
+.dropdown {
+ position: relative;
+}
+.dropdown-toggle:focus {
+ outline: 0;
+}
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ font-size: 14px;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ color: #262626;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #fff;
+ text-decoration: none;
+ background-color: #337ab7;
+ outline: 0;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
+.open > .dropdown-menu {
+ display: block;
+}
+.open > a {
+ outline: 0;
+}
+.dropdown-menu-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777;
+ white-space: nowrap;
+}
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990;
+}
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: 4px dashed;
+ border-bottom: 4px solid \9;
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto;
+ }
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0;
+ }
+}
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+.btn-toolbar {
+ margin-left: -5px;
+}
+.btn-toolbar .btn,
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px;
+}
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn .caret {
+ margin-left: 0;
+}
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+.input-group[class*="col-"] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+.input-group .form-control:focus {
+ z-index: 3;
+}
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555;
+ text-align: center;
+ background-color: #eee;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 3px;
+}
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 6px;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group-addon:first-child {
+ border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.input-group-addon:last-child {
+ border-left: 0;
+}
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+.input-group-btn > .btn {
+ position: relative;
+}
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ z-index: 2;
+ margin-left: -1px;
+}
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+.nav > li {
+ position: relative;
+ display: block;
+}
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.nav > li.disabled > a {
+ color: #777;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777;
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eee;
+ border-color: #337ab7;
+}
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.nav > li > a > img {
+ max-width: none;
+}
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+}
+.nav-tabs > li > a:hover {
+ border-color: #eee #eee #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555;
+ cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+.nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.nav-pills > li {
+ float: left;
+}
+.nav-pills > li > a {
+ border-radius: 4px;
+}
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #fff;
+ background-color: #337ab7;
+}
+.nav-stacked > li {
+ float: none;
+}
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+.nav-justified {
+ width: 100%;
+}
+.nav-justified > li {
+ float: none;
+}
+.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.tab-content > .tab-pane {
+ display: none;
+}
+.tab-content > .active {
+ display: block;
+}
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+}
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+.navbar-collapse {
+ padding-right: 15px;
+ padding-left: 15px;
+ overflow-x: visible;
+ -webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+}
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+.navbar-brand {
+ float: left;
+ height: 50px;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+.navbar-brand > img {
+ display: block;
+}
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-right: 15px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.navbar-toggle:focus {
+ outline: 0;
+}
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+.navbar-nav {
+ margin: 7.5px -15px;
+}
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+ .navbar-nav > li {
+ float: left;
+ }
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+}
+.navbar-form {
+ padding: 10px 15px;
+ margin-top: 8px;
+ margin-right: -15px;
+ margin-bottom: 8px;
+ margin-left: -15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+}
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px;
+}
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+ color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #5e5e5e;
+ background-color: transparent;
+}
+.navbar-default .navbar-text {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #333;
+ background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+ border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #777;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #333;
+ background-color: transparent;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+}
+.navbar-default .navbar-link {
+ color: #777;
+}
+.navbar-default .navbar-link:hover {
+ color: #333;
+}
+.navbar-default .btn-link {
+ color: #777;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+ border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+ }
+}
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-link:hover {
+ color: #fff;
+}
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+}
+.breadcrumb > li {
+ display: inline-block;
+}
+.breadcrumb > li + li:before {
+ padding: 0 5px;
+ color: #ccc;
+ content: "/\00a0";
+}
+.breadcrumb > .active {
+ color: #777;
+}
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px;
+}
+.pagination > li {
+ display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ margin-left: -1px;
+ line-height: 1.42857143;
+ color: #337ab7;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ z-index: 2;
+ color: #23527c;
+ background-color: #eee;
+ border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 3;
+ color: #fff;
+ cursor: default;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+}
+.pager li {
+ display: inline;
+}
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+}
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.label:empty {
+ display: none;
+}
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+.label-default {
+ background-color: #777;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+.label-primary {
+ background-color: #337ab7;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #286090;
+}
+.label-success {
+ background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+.label-info {
+ background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+.label-warning {
+ background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+.label-danger {
+ background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #777;
+ border-radius: 10px;
+}
+.badge:empty {
+ display: none;
+}
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.list-group-item > .badge {
+ float: right;
+}
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+.jumbotron {
+ padding-top: 30px;
+ padding-bottom: 30px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eee;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+.container .jumbotron,
+.container-fluid .jumbotron {
+ padding-right: 15px;
+ padding-left: 15px;
+ border-radius: 6px;
+}
+.jumbotron .container {
+ max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding-top: 48px;
+ padding-bottom: 48px;
+ }
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-right: 60px;
+ padding-left: 60px;
+ }
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+ margin-right: auto;
+ margin-left: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #337ab7;
+}
+.thumbnail .caption {
+ padding: 9px;
+ color: #333;
+}
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+.alert .alert-link {
+ font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+.alert > p + p {
+ margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+.alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.alert-success hr {
+ border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+ color: #2b542c;
+}
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.alert-info hr {
+ border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+ color: #245269;
+}
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.alert-warning hr {
+ border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+ color: #66512c;
+}
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.alert-danger hr {
+ border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+ color: #843534;
+}
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+.progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #337ab7;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.media {
+ margin-top: 15px;
+}
+.media:first-child {
+ margin-top: 0;
+}
+.media,
+.media-body {
+ overflow: hidden;
+ zoom: 1;
+}
+.media-body {
+ width: 10000px;
+}
+.media-object {
+ display: block;
+}
+.media-object.img-thumbnail {
+ max-width: none;
+}
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+.media-middle {
+ vertical-align: middle;
+}
+.media-bottom {
+ vertical-align: bottom;
+}
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+.list-group {
+ padding-left: 0;
+ margin-bottom: 20px;
+}
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.list-group-item:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+a.list-group-item,
+button.list-group-item {
+ color: #555;
+}
+a.list-group-item .list-group-item-heading,
+button.list-group-item .list-group-item-heading {
+ color: #333;
+}
+a.list-group-item:hover,
+button.list-group-item:hover,
+a.list-group-item:focus,
+button.list-group-item:focus {
+ color: #555;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+button.list-group-item {
+ width: 100%;
+ text-align: left;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #eee;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #c7ddef;
+}
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+}
+a.list-group-item-success,
+button.list-group-item-success {
+ color: #3c763d;
+}
+a.list-group-item-success .list-group-item-heading,
+button.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-success:hover,
+button.list-group-item-success:hover,
+a.list-group-item-success:focus,
+button.list-group-item-success:focus {
+ color: #3c763d;
+ background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+button.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+button.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus,
+button.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d;
+}
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7;
+}
+a.list-group-item-info,
+button.list-group-item-info {
+ color: #31708f;
+}
+a.list-group-item-info .list-group-item-heading,
+button.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-info:hover,
+button.list-group-item-info:hover,
+a.list-group-item-info:focus,
+button.list-group-item-info:focus {
+ color: #31708f;
+ background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+button.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+button.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus,
+button.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f;
+}
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+a.list-group-item-warning,
+button.list-group-item-warning {
+ color: #8a6d3b;
+}
+a.list-group-item-warning .list-group-item-heading,
+button.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-warning:hover,
+button.list-group-item-warning:hover,
+a.list-group-item-warning:focus,
+button.list-group-item-warning:focus {
+ color: #8a6d3b;
+ background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+button.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+button.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus,
+button.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b;
+}
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede;
+}
+a.list-group-item-danger,
+button.list-group-item-danger {
+ color: #a94442;
+}
+a.list-group-item-danger .list-group-item-heading,
+button.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-danger:hover,
+button.list-group-item-danger:hover,
+a.list-group-item-danger:focus,
+button.list-group-item-danger:focus {
+ color: #a94442;
+ background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+button.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+button.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus,
+button.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442;
+}
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+.panel-body {
+ padding: 15px;
+}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px;
+}
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #ddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+.panel > .table-responsive {
+ margin-bottom: 0;
+ border: 0;
+}
+.panel-group {
+ margin-bottom: 20px;
+}
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px;
+}
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #ddd;
+}
+.panel-group .panel-footer {
+ border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd;
+}
+.panel-default {
+ border-color: #ddd;
+}
+.panel-default > .panel-heading {
+ color: #333;
+ background-color: #f5f5f5;
+ border-color: #ddd;
+}
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd;
+}
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333;
+}
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd;
+}
+.panel-primary {
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337ab7;
+}
+.panel-primary > .panel-heading .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337ab7;
+}
+.panel-success {
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6;
+}
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d;
+}
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6;
+}
+.panel-info {
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1;
+}
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f;
+}
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1;
+}
+.panel-warning {
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc;
+}
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b;
+}
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc;
+}
+.panel-danger {
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1;
+}
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442;
+}
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1;
+}
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+}
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+}
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15);
+}
+.well-lg {
+ padding: 24px;
+ border-radius: 6px;
+}
+.well-sm {
+ padding: 9px;
+ border-radius: 3px;
+}
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ filter: alpha(opacity=20);
+ opacity: .2;
+}
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+button.close {
+ -webkit-appearance: none;
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+}
+.modal-open {
+ overflow: hidden;
+}
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+}
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+}
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000;
+}
+.modal-backdrop.fade {
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+.modal-backdrop.in {
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+ margin-top: -2px;
+}
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ }
+ .modal-sm {
+ width: 300px;
+ }
+}
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ filter: alpha(opacity=0);
+ opacity: 0;
+
+ line-break: auto;
+}
+.tooltip.in {
+ filter: alpha(opacity=90);
+ opacity: .9;
+}
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px;
+}
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px;
+}
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px;
+}
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px;
+}
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 4px;
+}
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-left .tooltip-arrow {
+ right: 5px;
+ bottom: 0;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000;
+}
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000;
+}
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+
+ line-break: auto;
+}
+.popover.top {
+ margin-top: -10px;
+}
+.popover.right {
+ margin-left: 10px;
+}
+.popover.bottom {
+ margin-top: 10px;
+}
+.popover.left {
+ margin-left: -10px;
+}
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 5px 5px 0 0;
+}
+.popover-content {
+ padding: 9px 14px;
+}
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.popover > .arrow {
+ border-width: 11px;
+}
+.popover > .arrow:after {
+ content: "";
+ border-width: 10px;
+}
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
+ border-bottom-width: 0;
+}
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
+ border-bottom-width: 0;
+}
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
+ border-left-width: 0;
+}
+.popover.right > .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
+ border-left-width: 0;
+}
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25);
+}
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: #fff;
+}
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, .25);
+}
+.popover.left > .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff;
+}
+.carousel {
+ position: relative;
+}
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000px;
+ perspective: 1000px;
+ }
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+.carousel-inner > .active {
+ left: 0;
+}
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+.carousel-inner > .next {
+ left: 100%;
+}
+.carousel-inner > .prev {
+ left: -100%;
+}
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+.carousel-inner > .active.left {
+ left: -100%;
+}
+.carousel-inner > .active.right {
+ left: 100%;
+}
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 15%;
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+ background-color: rgba(0, 0, 0, 0);
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control.right {
+ right: 0;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control:hover,
+.carousel-control:focus {
+ color: #fff;
+ text-decoration: none;
+ filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+ margin-top: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ font-family: serif;
+ line-height: 1;
+}
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none;
+}
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px;
+}
+.carousel-indicators .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: #fff;
+}
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+}
+.carousel-caption .btn {
+ text-shadow: none;
+}
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -10px;
+ font-size: 30px;
+ }
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -10px;
+ }
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -10px;
+ }
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px;
+ }
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-header:before,
+.modal-header:after,
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ content: " ";
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-header:after,
+.modal-footer:after {
+ clear: both;
+}
+.center-block {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.hidden {
+ display: none !important;
+}
+.affix {
+ position: fixed;
+}
+@-ms-viewport {
+ width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+ table.visible-xs {
+ display: table !important;
+ }
+ tr.visible-xs {
+ display: table-row !important;
+ }
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+ table.visible-sm {
+ display: table !important;
+ }
+ tr.visible-sm {
+ display: table-row !important;
+ }
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+ table.visible-md {
+ display: table !important;
+ }
+ tr.visible-md {
+ display: table-row !important;
+ }
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+ table.visible-lg {
+ display: table !important;
+ }
+ tr.visible-lg {
+ display: table-row !important;
+ }
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+.visible-print {
+ display: none !important;
+}
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+ table.visible-print {
+ display: table !important;
+ }
+ tr.visible-print {
+ display: table-row !important;
+ }
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+.visible-print-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/spring-boot-thymeleaf/src/main/resources/templates/hello.html b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/hello.html
similarity index 100%
rename from spring-boot-thymeleaf/src/main/resources/templates/hello.html
rename to 1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/hello.html
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/list.html b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/list.html
new file mode 100644
index 000000000..4126a3de1
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/list.html
@@ -0,0 +1,43 @@
+
+
+
+
+ userList
+
+
+
+
+用户列表
+
+
+
+
+
+ | # |
+ User Name |
+ Password |
+ Age |
+ Edit |
+ Delete |
+
+
+
+
+ | 1 |
+ neo |
+ Otto |
+ 6 |
+ edit |
+ delete |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userAdd.html b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userAdd.html
new file mode 100644
index 000000000..0fa93c38a
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userAdd.html
@@ -0,0 +1,43 @@
+
+
+
+
+ user
+
+
+
+
+添加用户
+
+
+
+
diff --git a/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userEdit.html b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userEdit.html
new file mode 100644
index 000000000..b312daa37
--- /dev/null
+++ b/1.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userEdit.html
@@ -0,0 +1,44 @@
+
+
+
+
+ user
+
+
+
+
+修改用户
+
+
+
+
diff --git a/1.x/spring-boot-mail/pom.xml b/1.x/spring-boot-mail/pom.xml
new file mode 100644
index 000000000..d22376fce
--- /dev/null
+++ b/1.x/spring-boot-mail/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mail
+ 1.0.0
+ jar
+
+ spring-boot-mail
+ Demo project for Spring Boot and mail
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.3.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework
+ spring-context-support
+ RELEASE
+
+
+ com.sun.mail
+ javax.mail
+ RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/spring-boot-mail/src/main/java/com/neo/Application.java b/1.x/spring-boot-mail/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-mail/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-mail/src/main/java/com/neo/Application.java
diff --git a/1.x/spring-boot-mail/src/main/java/com/neo/service/MailService.java b/1.x/spring-boot-mail/src/main/java/com/neo/service/MailService.java
new file mode 100644
index 000000000..a2948541c
--- /dev/null
+++ b/1.x/spring-boot-mail/src/main/java/com/neo/service/MailService.java
@@ -0,0 +1,16 @@
+package com.neo.service;
+
+/**
+ * Created by summer on 2017/5/4.
+ */
+public interface MailService {
+
+ public void sendSimpleMail(String to, String subject, String content);
+
+ public void sendHtmlMail(String to, String subject, String content);
+
+ public void sendAttachmentsMail(String to, String subject, String content, String filePath);
+
+ public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);
+
+}
diff --git a/1.x/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java b/1.x/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java
new file mode 100644
index 000000000..9053e6fb7
--- /dev/null
+++ b/1.x/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java
@@ -0,0 +1,138 @@
+package com.neo.service.impl;
+
+import com.neo.service.MailService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Component;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.io.File;
+
+/**
+ * Created by summer on 2017/5/4.
+ */
+@Component
+public class MailServiceImpl implements MailService{
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Autowired
+ private JavaMailSender mailSender;
+
+ @Value("${mail.fromMail.addr}")
+ private String from;
+
+ /**
+ * 发送文本邮件
+ * @param to
+ * @param subject
+ * @param content
+ */
+ @Override
+ public void sendSimpleMail(String to, String subject, String content) {
+ SimpleMailMessage message = new SimpleMailMessage();
+ message.setFrom(from);
+ message.setTo(to);
+ message.setSubject(subject);
+ message.setText(content);
+
+ try {
+ mailSender.send(message);
+ logger.info("简单邮件已经发送。");
+ } catch (Exception e) {
+ logger.error("发送简单邮件时发生异常!", e);
+ }
+
+ }
+
+ /**
+ * 发送html邮件
+ * @param to
+ * @param subject
+ * @param content
+ */
+ @Override
+ public void sendHtmlMail(String to, String subject, String content) {
+ MimeMessage message = mailSender.createMimeMessage();
+
+ try {
+ //true表示需要创建一个multipart message
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setFrom(from);
+ helper.setTo(to);
+ helper.setSubject(subject);
+ helper.setText(content, true);
+
+ mailSender.send(message);
+ logger.info("html邮件发送成功");
+ } catch (MessagingException e) {
+ logger.error("发送html邮件时发生异常!", e);
+ }
+ }
+
+
+ /**
+ * 发送带附件的邮件
+ * @param to
+ * @param subject
+ * @param content
+ * @param filePath
+ */
+ public void sendAttachmentsMail(String to, String subject, String content, String filePath){
+ MimeMessage message = mailSender.createMimeMessage();
+
+ try {
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setFrom(from);
+ helper.setTo(to);
+ helper.setSubject(subject);
+ helper.setText(content, true);
+
+ FileSystemResource file = new FileSystemResource(new File(filePath));
+ String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
+ helper.addAttachment(fileName, file);
+ //helper.addAttachment("test"+fileName, file);
+
+ mailSender.send(message);
+ logger.info("带附件的邮件已经发送。");
+ } catch (MessagingException e) {
+ logger.error("发送带附件的邮件时发生异常!", e);
+ }
+ }
+
+
+ /**
+ * 发送正文中有静态资源(图片)的邮件
+ * @param to
+ * @param subject
+ * @param content
+ * @param rscPath
+ * @param rscId
+ */
+ public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
+ MimeMessage message = mailSender.createMimeMessage();
+
+ try {
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setFrom(from);
+ helper.setTo(to);
+ helper.setSubject(subject);
+ helper.setText(content, true);
+
+ FileSystemResource res = new FileSystemResource(new File(rscPath));
+ helper.addInline(rscId, res);
+
+ mailSender.send(message);
+ logger.info("嵌入静态资源的邮件已经发送。");
+ } catch (MessagingException e) {
+ logger.error("发送嵌入静态资源的邮件时发生异常!", e);
+ }
+ }
+}
diff --git a/1.x/spring-boot-mail/src/main/resources/application.properties b/1.x/spring-boot-mail/src/main/resources/application.properties
new file mode 100644
index 000000000..dcbb52168
--- /dev/null
+++ b/1.x/spring-boot-mail/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+spring.application.name=spirng-boot-mail
+
+spring.mail.host=smtp.163.com
+spring.mail.username=xxoo@xxoo.com
+spring.mail.password=xxoo
+spring.mail.default-encoding=UTF-8
+
+mail.fromMail.addr=xxoo@xxoo.com
+
diff --git a/1.x/spring-boot-mail/src/main/resources/templates/emailTemplate.html b/1.x/spring-boot-mail/src/main/resources/templates/emailTemplate.html
new file mode 100644
index 000000000..387a4fbcd
--- /dev/null
+++ b/1.x/spring-boot-mail/src/main/resources/templates/emailTemplate.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Title
+
+
+ 您好,这是验证邮件,请点击下面的链接完成验证,
+ 激活账号
+
+
\ No newline at end of file
diff --git a/spring-boot-mail/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-mail/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-mail/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-mail/src/test/java/com/neo/ApplicationTests.java
diff --git a/1.x/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java b/1.x/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java
new file mode 100644
index 000000000..91c4bbfd2
--- /dev/null
+++ b/1.x/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java
@@ -0,0 +1,65 @@
+package com.neo.service;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.Context;
+
+/**
+ * Created by summer on 2017/5/4.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MailServiceTest {
+
+ @Autowired
+ private MailService mailService;
+
+ @Autowired
+ private TemplateEngine templateEngine;
+
+ @Test
+ public void testSimpleMail() throws Exception {
+ mailService.sendSimpleMail("ityouknow@126.com","test simple mail"," hello this is simple mail");
+ }
+
+ @Test
+ public void testHtmlMail() throws Exception {
+ String content="\n" +
+ "\n" +
+ " hello world ! 这是一封html邮件!
\n" +
+ "\n" +
+ "";
+ mailService.sendHtmlMail("ityouknow@126.com","test simple mail",content);
+ }
+
+ @Test
+ public void sendAttachmentsMail() {
+ String filePath="e:\\tmp\\application.log";
+ mailService.sendAttachmentsMail("ityouknow@126.com", "主题:带附件的邮件", "有附件,请查收!", filePath);
+ }
+
+
+ @Test
+ public void sendInlineResourceMail() {
+ String rscId = "neo006";
+ String content="这是有图片的邮件:
";
+ String imgPath = "C:\\Users\\summer\\Pictures\\favicon.png";
+
+ mailService.sendInlineResourceMail("ityouknow@126.com", "主题:这是有图片的邮件", content, imgPath, rscId);
+ }
+
+
+ @Test
+ public void sendTemplateMail() {
+ //创建邮件正文
+ Context context = new Context();
+ context.setVariable("id", "006");
+ String emailContent = templateEngine.process("emailTemplate", context);
+
+ mailService.sendHtmlMail("ityouknow@126.com","主题:这是模板邮件",emailContent);
+ }
+}
diff --git a/spring-boot-mongodb/pom.xml b/1.x/spring-boot-mongodb/pom.xml
similarity index 100%
rename from spring-boot-mongodb/pom.xml
rename to 1.x/spring-boot-mongodb/pom.xml
diff --git a/spring-boot-mongodb/src/main/java/com/neo/Application.java b/1.x/spring-boot-mongodb/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-mongodb/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-mongodb/src/main/java/com/neo/Application.java
diff --git a/spring-boot-mongodb/src/main/java/com/neo/dao/UserDao.java b/1.x/spring-boot-mongodb/src/main/java/com/neo/dao/UserDao.java
similarity index 100%
rename from spring-boot-mongodb/src/main/java/com/neo/dao/UserDao.java
rename to 1.x/spring-boot-mongodb/src/main/java/com/neo/dao/UserDao.java
diff --git a/spring-boot-mongodb/src/main/java/com/neo/dao/impl/UserDaoImpl.java b/1.x/spring-boot-mongodb/src/main/java/com/neo/dao/impl/UserDaoImpl.java
similarity index 100%
rename from spring-boot-mongodb/src/main/java/com/neo/dao/impl/UserDaoImpl.java
rename to 1.x/spring-boot-mongodb/src/main/java/com/neo/dao/impl/UserDaoImpl.java
diff --git a/spring-boot-mongodb/src/main/java/com/neo/entity/UserEntity.java b/1.x/spring-boot-mongodb/src/main/java/com/neo/entity/UserEntity.java
similarity index 100%
rename from spring-boot-mongodb/src/main/java/com/neo/entity/UserEntity.java
rename to 1.x/spring-boot-mongodb/src/main/java/com/neo/entity/UserEntity.java
diff --git a/spring-boot-mongodb/src/main/resources/application.properties b/1.x/spring-boot-mongodb/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-mongodb/src/main/resources/application.properties
rename to 1.x/spring-boot-mongodb/src/main/resources/application.properties
diff --git a/spring-boot-mongodb/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-mongodb/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-mongodb/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-mongodb/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-mongodb/src/test/java/com/neo/dao/UserDaoTest.java b/1.x/spring-boot-mongodb/src/test/java/com/neo/dao/UserDaoTest.java
similarity index 100%
rename from spring-boot-mongodb/src/test/java/com/neo/dao/UserDaoTest.java
rename to 1.x/spring-boot-mongodb/src/test/java/com/neo/dao/UserDaoTest.java
diff --git a/spring-boot-multi-mongodb/pom.xml b/1.x/spring-boot-multi-mongodb/pom.xml
similarity index 100%
rename from spring-boot-multi-mongodb/pom.xml
rename to 1.x/spring-boot-multi-mongodb/pom.xml
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/Application.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/Application.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryMongoObject.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryMongoObject.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryMongoObject.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryMongoObject.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryRepository.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryRepository.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryRepository.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/primary/PrimaryRepository.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryMongoObject.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryMongoObject.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryMongoObject.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryMongoObject.java
diff --git a/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryRepository.java b/1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryRepository.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryRepository.java
rename to 1.x/spring-boot-multi-mongodb/src/main/java/com/neo/model/repository/secondary/SecondaryRepository.java
diff --git a/spring-boot-multi-mongodb/src/main/resources/application.yml b/1.x/spring-boot-multi-mongodb/src/main/resources/application.yml
similarity index 100%
rename from spring-boot-multi-mongodb/src/main/resources/application.yml
rename to 1.x/spring-boot-multi-mongodb/src/main/resources/application.yml
diff --git a/spring-boot-multi-mongodb/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-multi-mongodb/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-multi-mongodb/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-multi-mongodb/src/test/java/com/neo/model/repository/MuliDatabaseTest.java b/1.x/spring-boot-multi-mongodb/src/test/java/com/neo/model/repository/MuliDatabaseTest.java
similarity index 100%
rename from spring-boot-multi-mongodb/src/test/java/com/neo/model/repository/MuliDatabaseTest.java
rename to 1.x/spring-boot-multi-mongodb/src/test/java/com/neo/model/repository/MuliDatabaseTest.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/pom.xml b/1.x/spring-boot-mybatis-annotation-mulidatasource/pom.xml
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/pom.xml
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/pom.xml
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/Application.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/Application.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/entity/UserEntity.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/entity/UserEntity.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/entity/UserEntity.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/entity/UserEntity.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
diff --git a/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java b/1.x/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
similarity index 100%
rename from spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
rename to 1.x/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
diff --git a/spring-boot-mybatis-annotation/pom.xml b/1.x/spring-boot-mybatis-annotation/pom.xml
similarity index 100%
rename from spring-boot-mybatis-annotation/pom.xml
rename to 1.x/spring-boot-mybatis-annotation/pom.xml
diff --git a/spring-boot-mybatis-annotation/src/main/java/com/neo/Application.java b/1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-mybatis-annotation/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/Application.java
diff --git a/spring-boot-mybatis-annotation/src/main/java/com/neo/entity/UserEntity.java b/1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/entity/UserEntity.java
similarity index 100%
rename from spring-boot-mybatis-annotation/src/main/java/com/neo/entity/UserEntity.java
rename to 1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/entity/UserEntity.java
diff --git a/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java b/1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java
similarity index 100%
rename from spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java
rename to 1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java
diff --git a/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java b/1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java
similarity index 100%
rename from spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java
rename to 1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java
diff --git a/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java b/1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java
similarity index 100%
rename from spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java
rename to 1.x/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java
diff --git a/spring-boot-mybatis-annotation/src/main/resources/application.properties b/1.x/spring-boot-mybatis-annotation/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-mybatis-annotation/src/main/resources/application.properties
rename to 1.x/spring-boot-mybatis-annotation/src/main/resources/application.properties
diff --git a/spring-boot-mybatis-annotation/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-mybatis-annotation/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-mybatis-annotation/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-mybatis-annotation/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java b/1.x/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java
similarity index 100%
rename from spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java
rename to 1.x/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java
diff --git a/spring-boot-mybatis-annotation/users.sql b/1.x/spring-boot-mybatis-annotation/users.sql
similarity index 100%
rename from spring-boot-mybatis-annotation/users.sql
rename to 1.x/spring-boot-mybatis-annotation/users.sql
diff --git a/spring-boot-mybatis-mulidatasource/pom.xml b/1.x/spring-boot-mybatis-mulidatasource/pom.xml
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/pom.xml
rename to 1.x/spring-boot-mybatis-mulidatasource/pom.xml
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/Application.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/Application.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/entity/UserEntity.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/entity/UserEntity.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/entity/UserEntity.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/entity/UserEntity.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/web/UserController.java b/1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/web/UserController.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/java/com/neo/web/UserController.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/java/com/neo/web/UserController.java
diff --git a/spring-boot-mybatis-mulidatasource/src/main/resources/application.properties b/1.x/spring-boot-mybatis-mulidatasource/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/resources/application.properties
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/resources/application.properties
diff --git a/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml b/1.x/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml
diff --git a/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml b/1.x/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml
diff --git a/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mybatis-config.xml b/1.x/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mybatis-config.xml
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mybatis-config.xml
rename to 1.x/spring-boot-mybatis-mulidatasource/src/main/resources/mybatis/mybatis-config.xml
diff --git a/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java b/1.x/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
diff --git a/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java b/1.x/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
rename to 1.x/spring-boot-mybatis-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
diff --git a/spring-boot-mybatis-mulidatasource/users.sql b/1.x/spring-boot-mybatis-mulidatasource/users.sql
similarity index 100%
rename from spring-boot-mybatis-mulidatasource/users.sql
rename to 1.x/spring-boot-mybatis-mulidatasource/users.sql
diff --git a/spring-boot-mybatis-xml/pom.xml b/1.x/spring-boot-mybatis-xml/pom.xml
similarity index 100%
rename from spring-boot-mybatis-xml/pom.xml
rename to 1.x/spring-boot-mybatis-xml/pom.xml
diff --git a/spring-boot-mybatis-xml/src/main/java/com/neo/Application.java b/1.x/spring-boot-mybatis-xml/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-mybatis-xml/src/main/java/com/neo/Application.java
diff --git a/spring-boot-mybatis-xml/src/main/java/com/neo/entity/UserEntity.java b/1.x/spring-boot-mybatis-xml/src/main/java/com/neo/entity/UserEntity.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/java/com/neo/entity/UserEntity.java
rename to 1.x/spring-boot-mybatis-xml/src/main/java/com/neo/entity/UserEntity.java
diff --git a/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java b/1.x/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java
rename to 1.x/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java
diff --git a/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java b/1.x/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java
rename to 1.x/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java
diff --git a/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java b/1.x/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java
rename to 1.x/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java
diff --git a/spring-boot-mybatis-xml/src/main/resources/application.properties b/1.x/spring-boot-mybatis-xml/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/resources/application.properties
rename to 1.x/spring-boot-mybatis-xml/src/main/resources/application.properties
diff --git a/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml b/1.x/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
rename to 1.x/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
diff --git a/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml b/1.x/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml
similarity index 100%
rename from spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml
rename to 1.x/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml
diff --git a/spring-boot-mybatis-xml/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-mybatis-xml/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-mybatis-xml/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java b/1.x/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java
rename to 1.x/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java
diff --git a/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java b/1.x/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java
similarity index 100%
rename from spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java
rename to 1.x/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java
diff --git a/spring-boot-mybatis-xml/users.sql b/1.x/spring-boot-mybatis-xml/users.sql
similarity index 100%
rename from spring-boot-mybatis-xml/users.sql
rename to 1.x/spring-boot-mybatis-xml/users.sql
diff --git a/spring-boot-package-war/pom.xml b/1.x/spring-boot-package-war/pom.xml
similarity index 100%
rename from spring-boot-package-war/pom.xml
rename to 1.x/spring-boot-package-war/pom.xml
diff --git a/spring-boot-rabbitmq/src/main/java/com/neo/Application.java b/1.x/spring-boot-package-war/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-rabbitmq/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-package-war/src/main/java/com/neo/Application.java
diff --git a/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java b/1.x/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java
similarity index 100%
rename from spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java
rename to 1.x/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java
diff --git a/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java b/1.x/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java
similarity index 100%
rename from spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java
rename to 1.x/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java
diff --git a/1.x/spring-boot-package-war/src/main/resources/application.properties b/1.x/spring-boot-package-war/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java b/1.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java
similarity index 100%
rename from spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java
rename to 1.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java
diff --git a/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/1.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java
similarity index 100%
rename from spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java
rename to 1.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java
diff --git a/1.x/spring-boot-rabbitmq/pom.xml b/1.x/spring-boot-rabbitmq/pom.xml
new file mode 100644
index 000000000..b4de1e355
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-rabbitmq
+ 1.0.0
+ jar
+
+ spring-boot-rabbitmq
+ Demo project for Spring Boot and rabbitmq
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.4.2.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/spring-boot-web/src/main/java/com/neo/Application.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-web/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-rabbitmq/src/main/java/com/neo/Application.java
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/model/User.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..f4eec95e4
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/model/User.java
@@ -0,0 +1,37 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by summer on 2016/11/29.
+ */
+public class User implements Serializable{
+
+ private String name;
+
+ private String pass;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPass() {
+ return pass;
+ }
+
+ public void setPass(String pass) {
+ this.pass = pass;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "name='" + name + '\'' +
+ ", pass='" + pass + '\'' +
+ '}';
+ }
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/FanoutRabbitConfig.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/FanoutRabbitConfig.java
new file mode 100644
index 000000000..4fe21fa9f
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/FanoutRabbitConfig.java
@@ -0,0 +1,49 @@
+package com.neo.rabbit;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class FanoutRabbitConfig {
+
+ @Bean
+ public Queue AMessage() {
+ return new Queue("fanout.A");
+ }
+
+ @Bean
+ public Queue BMessage() {
+ return new Queue("fanout.B");
+ }
+
+ @Bean
+ public Queue CMessage() {
+ return new Queue("fanout.C");
+ }
+
+ @Bean
+ FanoutExchange fanoutExchange() {
+ return new FanoutExchange("fanoutExchange");
+ }
+
+ @Bean
+ Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange) {
+ return BindingBuilder.bind(AMessage).to(fanoutExchange);
+ }
+
+ @Bean
+ Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
+ return BindingBuilder.bind(BMessage).to(fanoutExchange);
+ }
+
+ @Bean
+ Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
+ return BindingBuilder.bind(CMessage).to(fanoutExchange);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/RabbitConfig.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/RabbitConfig.java
new file mode 100644
index 000000000..d5d649b5c
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/RabbitConfig.java
@@ -0,0 +1,27 @@
+package com.neo.rabbit;
+
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class RabbitConfig {
+
+ @Bean
+ public Queue helloQueue() {
+ return new Queue("hello");
+ }
+
+ @Bean
+ public Queue neoQueue() {
+ return new Queue("neo");
+ }
+
+ @Bean
+ public Queue objectQueue() {
+ return new Queue("object");
+ }
+
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/TopicRabbitConfig.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/TopicRabbitConfig.java
new file mode 100644
index 000000000..7bd2a096c
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/TopicRabbitConfig.java
@@ -0,0 +1,41 @@
+package com.neo.rabbit;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class TopicRabbitConfig {
+
+ final static String message = "topic.message";
+ final static String messages = "topic.messages";
+
+ @Bean
+ public Queue queueMessage() {
+ return new Queue(TopicRabbitConfig.message);
+ }
+
+ @Bean
+ public Queue queueMessages() {
+ return new Queue(TopicRabbitConfig.messages);
+ }
+
+ @Bean
+ TopicExchange exchange() {
+ return new TopicExchange("topicExchange");
+ }
+
+ @Bean
+ Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
+ return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
+ }
+
+ @Bean
+ Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
+ return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
+ }
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverA.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverA.java
new file mode 100644
index 000000000..256de2eee
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverA.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "fanout.A")
+public class FanoutReceiverA {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("fanout Receiver A : " + message);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverB.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverB.java
new file mode 100644
index 000000000..a721da684
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverB.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "fanout.B")
+public class FanoutReceiverB {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("fanout Receiver B: " + message);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverC.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverC.java
new file mode 100644
index 000000000..aceef8b08
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverC.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "fanout.C")
+public class FanoutReceiverC {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("fanout Receiver C: " + message);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutSender.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutSender.java
new file mode 100644
index 000000000..2fa62d39c
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutSender.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class FanoutSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send() {
+ String context = "hi, fanout msg ";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("fanoutExchange","", context);
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloReceiver.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloReceiver.java
new file mode 100644
index 000000000..2d59b1740
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloReceiver.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.hello;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+@RabbitListener(queues = "hello")
+public class HelloReceiver {
+
+ @RabbitHandler
+ public void process(String hello) {
+ System.out.println("Receiver : " + hello);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloSender.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloSender.java
new file mode 100644
index 000000000..05fc740ac
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloSender.java
@@ -0,0 +1,22 @@
+package com.neo.rabbit.hello;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class HelloSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send() {
+ String context = "hello " + new Date();
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("hello", context);
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver1.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver1.java
new file mode 100644
index 000000000..c352fbeb5
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver1.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "neo")
+public class NeoReceiver1 {
+
+ @RabbitHandler
+ public void process(String neo) {
+ System.out.println("Receiver 1: " + neo);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver2.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver2.java
new file mode 100644
index 000000000..d7cbdd758
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver2.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "neo")
+public class NeoReceiver2 {
+
+ @RabbitHandler
+ public void process(String neo) {
+ System.out.println("Receiver 2: " + neo);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender.java
new file mode 100644
index 000000000..755918fb6
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NeoSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(int i) {
+ String context = "spirng boot neo queue"+" ****** "+i;
+ System.out.println("Sender1 : " + context);
+ this.rabbitTemplate.convertAndSend("neo", context);
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender2.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender2.java
new file mode 100644
index 000000000..e34cce647
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender2.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NeoSender2 {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(int i) {
+ String context = "spirng boot neo queue"+" ****** "+i;
+ System.out.println("Sender2 : " + context);
+ this.rabbitTemplate.convertAndSend("neo", context);
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectReceiver.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectReceiver.java
new file mode 100644
index 000000000..b97f8a026
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectReceiver.java
@@ -0,0 +1,17 @@
+package com.neo.rabbit.object;
+
+import com.neo.model.User;
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "object")
+public class ObjectReceiver {
+
+ @RabbitHandler
+ public void process(User user) {
+ System.out.println("Receiver object : " + user);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectSender.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectSender.java
new file mode 100644
index 000000000..9c7aba927
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectSender.java
@@ -0,0 +1,21 @@
+package com.neo.rabbit.object;
+
+import com.neo.model.User;
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class ObjectSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(User user) {
+ System.out.println("Sender object: " + user.toString());
+ this.rabbitTemplate.convertAndSend("object", user);
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver.java
new file mode 100644
index 000000000..14523941a
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.topic;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "topic.message")
+public class TopicReceiver {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("Topic Receiver1 : " + message);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver2.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver2.java
new file mode 100644
index 000000000..9ea81d7fe
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver2.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.topic;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "topic.messages")
+public class TopicReceiver2 {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("Topic Receiver2 : " + message);
+ }
+
+}
diff --git a/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicSender.java b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicSender.java
new file mode 100644
index 000000000..8f17c34e3
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicSender.java
@@ -0,0 +1,33 @@
+package com.neo.rabbit.topic;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class TopicSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send() {
+ String context = "hi, i am message all";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("topicExchange", "topic.1", context);
+ }
+
+ public void send1() {
+ String context = "hi, i am message 1";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("topicExchange", "topic.message", context);
+ }
+
+ public void send2() {
+ String context = "hi, i am messages 2";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("topicExchange", "topic.messages", context);
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/main/resources/application.properties b/1.x/spring-boot-rabbitmq/src/main/resources/application.properties
new file mode 100644
index 000000000..da5cc5ed0
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+spring.application.name=spirng-boot-rabbitmq-example
+
+spring.rabbitmq.host=192.168.0.86
+spring.rabbitmq.port=5672
+spring.rabbitmq.username=admin
+spring.rabbitmq.password=123456
diff --git a/spring-boot-rabbitmq/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-rabbitmq/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-rabbitmq/src/test/java/com/neo/ApplicationTests.java
diff --git a/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/FanoutTest.java b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/FanoutTest.java
new file mode 100644
index 000000000..d9ee0afd9
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/FanoutTest.java
@@ -0,0 +1,24 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.fanout.FanoutSender;
+import com.neo.rabbit.topic.TopicSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class FanoutTest {
+
+ @Autowired
+ private FanoutSender sender;
+
+ @Test
+ public void fanoutSender() throws Exception {
+ sender.send();
+ }
+
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/HelloTest.java b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/HelloTest.java
new file mode 100644
index 000000000..f790b0452
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/HelloTest.java
@@ -0,0 +1,23 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.hello.HelloSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloTest {
+
+ @Autowired
+ private HelloSender helloSender;
+
+ @Test
+ public void hello() throws Exception {
+ helloSender.send();
+ }
+
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ManyTest.java b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ManyTest.java
new file mode 100644
index 000000000..08c701cfd
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ManyTest.java
@@ -0,0 +1,35 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.many.NeoSender;
+import com.neo.rabbit.many.NeoSender2;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ManyTest {
+ @Autowired
+ private NeoSender neoSender;
+
+ @Autowired
+ private NeoSender2 neoSender2;
+
+ @Test
+ public void oneToMany() throws Exception {
+ for (int i=0;i<100;i++){
+ neoSender.send(i);
+ }
+ }
+
+ @Test
+ public void manyToMany() throws Exception {
+ for (int i=0;i<100;i++){
+ neoSender.send(i);
+ neoSender2.send(i);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ObjectTest.java b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ObjectTest.java
new file mode 100644
index 000000000..e36daf7ed
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ObjectTest.java
@@ -0,0 +1,26 @@
+package com.neo.rabbitmq;
+
+import com.neo.model.User;
+import com.neo.rabbit.object.ObjectSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ObjectTest {
+
+ @Autowired
+ private ObjectSender sender;
+
+ @Test
+ public void sendOject() throws Exception {
+ User user=new User();
+ user.setName("neo");
+ user.setPass("123456");
+ sender.send(user);
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/TopicTest.java b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/TopicTest.java
new file mode 100644
index 000000000..d69a5b85e
--- /dev/null
+++ b/1.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/TopicTest.java
@@ -0,0 +1,32 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.topic.TopicSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class TopicTest {
+
+ @Autowired
+ private TopicSender sender;
+
+ @Test
+ public void topic() throws Exception {
+ sender.send();
+ }
+
+ @Test
+ public void topic1() throws Exception {
+ sender.send1();
+ }
+
+ @Test
+ public void topic2() throws Exception {
+ sender.send2();
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-scheduler/pom.xml b/1.x/spring-boot-scheduler/pom.xml
new file mode 100644
index 000000000..b3d18365d
--- /dev/null
+++ b/1.x/spring-boot-scheduler/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-scheduler
+ 1.0.0
+ jar
+
+ spring-boot-scheduler
+ Demo project for Spring Boot and scheduler
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.4.2.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/spring-boot-scheduler/src/main/java/com/neo/Application.java b/1.x/spring-boot-scheduler/src/main/java/com/neo/Application.java
similarity index 100%
rename from spring-boot-scheduler/src/main/java/com/neo/Application.java
rename to 1.x/spring-boot-scheduler/src/main/java/com/neo/Application.java
diff --git a/1.x/spring-boot-scheduler/src/main/java/com/neo/task/Scheduler2Task.java b/1.x/spring-boot-scheduler/src/main/java/com/neo/task/Scheduler2Task.java
new file mode 100644
index 000000000..7b59c9f2b
--- /dev/null
+++ b/1.x/spring-boot-scheduler/src/main/java/com/neo/task/Scheduler2Task.java
@@ -0,0 +1,23 @@
+package com.neo.task;
+
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by summer on 2016/12/1.
+ */
+
+@Component
+public class Scheduler2Task {
+
+ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
+
+ @Scheduled(fixedRate = 6000)
+ public void reportCurrentTime() {
+ System.out.println("现在时间:" + dateFormat.format(new Date()));
+ }
+
+}
diff --git a/1.x/spring-boot-scheduler/src/main/java/com/neo/task/SchedulerTask.java b/1.x/spring-boot-scheduler/src/main/java/com/neo/task/SchedulerTask.java
new file mode 100644
index 000000000..69885e3cc
--- /dev/null
+++ b/1.x/spring-boot-scheduler/src/main/java/com/neo/task/SchedulerTask.java
@@ -0,0 +1,22 @@
+package com.neo.task;
+
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * Created by summer on 2016/12/1.
+ */
+
+@Component
+public class SchedulerTask {
+
+ private int count=0;
+
+ @Scheduled(cron="*/6 * * * * ?")
+ private void process(){
+ System.out.println("this is scheduler task runing "+(count++));
+ }
+
+}
diff --git a/1.x/spring-boot-scheduler/src/main/resources/application.properties b/1.x/spring-boot-scheduler/src/main/resources/application.properties
new file mode 100644
index 000000000..8978a46f1
--- /dev/null
+++ b/1.x/spring-boot-scheduler/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.application.name=spirng-boot-scheduler
+
diff --git a/spring-boot-scheduler/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-scheduler/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-scheduler/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-scheduler/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-shiro/pom.xml b/1.x/spring-boot-shiro/pom.xml
similarity index 98%
rename from spring-boot-shiro/pom.xml
rename to 1.x/spring-boot-shiro/pom.xml
index 3d357ea56..0307f6d44 100644
--- a/spring-boot-shiro/pom.xml
+++ b/1.x/spring-boot-shiro/pom.xml
@@ -45,7 +45,7 @@
org.apache.shiro
shiro-spring
- 1.4.0
+ 1.7.2
mysql
diff --git a/spring-boot-shiro/src/main/java/com/neo/SpringBootShiroApplication.java b/1.x/spring-boot-shiro/src/main/java/com/neo/SpringBootShiroApplication.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/SpringBootShiroApplication.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/SpringBootShiroApplication.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/config/MyShiroRealm.java b/1.x/spring-boot-shiro/src/main/java/com/neo/config/MyShiroRealm.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/config/MyShiroRealm.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/config/MyShiroRealm.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/config/ShiroConfig.java b/1.x/spring-boot-shiro/src/main/java/com/neo/config/ShiroConfig.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/config/ShiroConfig.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/config/ShiroConfig.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/dao/UserInfoDao.java b/1.x/spring-boot-shiro/src/main/java/com/neo/dao/UserInfoDao.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/dao/UserInfoDao.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/dao/UserInfoDao.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/entity/SysPermission.java b/1.x/spring-boot-shiro/src/main/java/com/neo/entity/SysPermission.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/entity/SysPermission.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/entity/SysPermission.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/entity/SysRole.java b/1.x/spring-boot-shiro/src/main/java/com/neo/entity/SysRole.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/entity/SysRole.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/entity/SysRole.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/entity/UserInfo.java b/1.x/spring-boot-shiro/src/main/java/com/neo/entity/UserInfo.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/entity/UserInfo.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/entity/UserInfo.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/sevice/UserInfoService.java b/1.x/spring-boot-shiro/src/main/java/com/neo/sevice/UserInfoService.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/sevice/UserInfoService.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/sevice/UserInfoService.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/sevice/impl/UserInfoServiceImpl.java b/1.x/spring-boot-shiro/src/main/java/com/neo/sevice/impl/UserInfoServiceImpl.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/sevice/impl/UserInfoServiceImpl.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/sevice/impl/UserInfoServiceImpl.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/web/HomeController.java b/1.x/spring-boot-shiro/src/main/java/com/neo/web/HomeController.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/web/HomeController.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/web/HomeController.java
diff --git a/spring-boot-shiro/src/main/java/com/neo/web/UserInfoController.java b/1.x/spring-boot-shiro/src/main/java/com/neo/web/UserInfoController.java
similarity index 100%
rename from spring-boot-shiro/src/main/java/com/neo/web/UserInfoController.java
rename to 1.x/spring-boot-shiro/src/main/java/com/neo/web/UserInfoController.java
diff --git a/spring-boot-shiro/src/main/resources/application.yml b/1.x/spring-boot-shiro/src/main/resources/application.yml
similarity index 100%
rename from spring-boot-shiro/src/main/resources/application.yml
rename to 1.x/spring-boot-shiro/src/main/resources/application.yml
diff --git a/spring-boot-shiro/src/main/resources/database/import.sql b/1.x/spring-boot-shiro/src/main/resources/database/import.sql
similarity index 100%
rename from spring-boot-shiro/src/main/resources/database/import.sql
rename to 1.x/spring-boot-shiro/src/main/resources/database/import.sql
diff --git a/spring-boot-shiro/src/main/resources/templates/403.html b/1.x/spring-boot-shiro/src/main/resources/templates/403.html
similarity index 100%
rename from spring-boot-shiro/src/main/resources/templates/403.html
rename to 1.x/spring-boot-shiro/src/main/resources/templates/403.html
diff --git a/spring-boot-shiro/src/main/resources/templates/index.html b/1.x/spring-boot-shiro/src/main/resources/templates/index.html
similarity index 100%
rename from spring-boot-shiro/src/main/resources/templates/index.html
rename to 1.x/spring-boot-shiro/src/main/resources/templates/index.html
diff --git a/spring-boot-shiro/src/main/resources/templates/login.html b/1.x/spring-boot-shiro/src/main/resources/templates/login.html
similarity index 100%
rename from spring-boot-shiro/src/main/resources/templates/login.html
rename to 1.x/spring-boot-shiro/src/main/resources/templates/login.html
diff --git a/spring-boot-shiro/src/main/resources/templates/userInfo.html b/1.x/spring-boot-shiro/src/main/resources/templates/userInfo.html
similarity index 100%
rename from spring-boot-shiro/src/main/resources/templates/userInfo.html
rename to 1.x/spring-boot-shiro/src/main/resources/templates/userInfo.html
diff --git a/spring-boot-shiro/src/main/resources/templates/userInfoAdd.html b/1.x/spring-boot-shiro/src/main/resources/templates/userInfoAdd.html
similarity index 100%
rename from spring-boot-shiro/src/main/resources/templates/userInfoAdd.html
rename to 1.x/spring-boot-shiro/src/main/resources/templates/userInfoAdd.html
diff --git a/spring-boot-shiro/src/main/resources/templates/userInfoDel.html b/1.x/spring-boot-shiro/src/main/resources/templates/userInfoDel.html
similarity index 100%
rename from spring-boot-shiro/src/main/resources/templates/userInfoDel.html
rename to 1.x/spring-boot-shiro/src/main/resources/templates/userInfoDel.html
diff --git a/spring-boot-shiro/src/test/java/com/neo/SpringBootShiroApplicationTests.java b/1.x/spring-boot-shiro/src/test/java/com/neo/SpringBootShiroApplicationTests.java
similarity index 100%
rename from spring-boot-shiro/src/test/java/com/neo/SpringBootShiroApplicationTests.java
rename to 1.x/spring-boot-shiro/src/test/java/com/neo/SpringBootShiroApplicationTests.java
diff --git a/spring-boot-thymeleaf/pom.xml b/1.x/spring-boot-thymeleaf/pom.xml
similarity index 100%
rename from spring-boot-thymeleaf/pom.xml
rename to 1.x/spring-boot-thymeleaf/pom.xml
diff --git a/spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/HelloController.java b/1.x/spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/HelloController.java
similarity index 100%
rename from spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/HelloController.java
rename to 1.x/spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/HelloController.java
diff --git a/spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/ThymeleafApplication.java b/1.x/spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/ThymeleafApplication.java
similarity index 100%
rename from spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/ThymeleafApplication.java
rename to 1.x/spring-boot-thymeleaf/src/main/java/com/neo/thymeleaf/ThymeleafApplication.java
diff --git a/spring-boot-thymeleaf/src/main/resources/application.properties b/1.x/spring-boot-thymeleaf/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-thymeleaf/src/main/resources/application.properties
rename to 1.x/spring-boot-thymeleaf/src/main/resources/application.properties
diff --git a/1.x/spring-boot-thymeleaf/src/main/resources/templates/hello.html b/1.x/spring-boot-thymeleaf/src/main/resources/templates/hello.html
new file mode 100644
index 000000000..bd1f7817e
--- /dev/null
+++ b/1.x/spring-boot-thymeleaf/src/main/resources/templates/hello.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Hello Thymeleaf!
+
+
+
+
+
\ No newline at end of file
diff --git a/1.x/spring-boot-web/pom.xml b/1.x/spring-boot-web/pom.xml
new file mode 100644
index 000000000..ebeec70a0
--- /dev/null
+++ b/1.x/spring-boot-web/pom.xml
@@ -0,0 +1,90 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-web
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-web
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.6.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.webjars.bower
+ jquery
+ 2.0.3
+
+
+ org.webjars.bower
+ bootstrap
+ 3.0.3
+
+
+ org.springframework.boot
+ spring-boot-starter-redis
+
+
+ org.springframework.session
+ spring-session-data-redis
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/1.x/spring-boot-web/src/main/java/com/neo/Application.java b/1.x/spring-boot-web/src/main/java/com/neo/Application.java
new file mode 100644
index 000000000..6cda50c81
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/java/com/neo/Application.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/1.x/spring-boot-web/src/main/java/com/neo/WebConfiguration.java b/1.x/spring-boot-web/src/main/java/com/neo/WebConfiguration.java
new file mode 100644
index 000000000..cbf7177fd
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/java/com/neo/WebConfiguration.java
@@ -0,0 +1,60 @@
+package com.neo;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.catalina.filters.RemoteIpFilter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class WebConfiguration {
+ @Bean
+ public RemoteIpFilter remoteIpFilter() {
+ return new RemoteIpFilter();
+ }
+
+ @Bean
+ public FilterRegistrationBean testFilterRegistration() {
+
+ FilterRegistrationBean registration = new FilterRegistrationBean();
+ registration.setFilter(new MyFilter());
+ registration.addUrlPatterns("/*");
+ registration.addInitParameter("paramName", "paramValue");
+ registration.setName("MyFilter");
+ registration.setOrder(1);
+ return registration;
+ }
+
+ public class MyFilter implements Filter {
+ @Override
+ public void destroy() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ // TODO Auto-generated method stub
+ HttpServletRequest request = (HttpServletRequest) srequest;
+ System.out.println("this is MyFilter,url :"+request.getRequestURI());
+ filterChain.doFilter(srequest, sresponse);
+ }
+
+ @Override
+ public void init(FilterConfig arg0) throws ServletException {
+ // TODO Auto-generated method stub
+ }
+ }
+}
+
+
+
diff --git a/spring-boot-web/src/main/java/com/neo/config/RedisConfig.java b/1.x/spring-boot-web/src/main/java/com/neo/config/RedisConfig.java
similarity index 100%
rename from spring-boot-web/src/main/java/com/neo/config/RedisConfig.java
rename to 1.x/spring-boot-web/src/main/java/com/neo/config/RedisConfig.java
diff --git a/spring-boot-web/src/main/java/com/neo/config/SessionConfig.java b/1.x/spring-boot-web/src/main/java/com/neo/config/SessionConfig.java
similarity index 100%
rename from spring-boot-web/src/main/java/com/neo/config/SessionConfig.java
rename to 1.x/spring-boot-web/src/main/java/com/neo/config/SessionConfig.java
diff --git a/spring-boot-web/src/main/java/com/neo/domain/User.java b/1.x/spring-boot-web/src/main/java/com/neo/domain/User.java
similarity index 100%
rename from spring-boot-web/src/main/java/com/neo/domain/User.java
rename to 1.x/spring-boot-web/src/main/java/com/neo/domain/User.java
diff --git a/spring-boot-web/src/main/java/com/neo/domain/UserRepository.java b/1.x/spring-boot-web/src/main/java/com/neo/domain/UserRepository.java
similarity index 100%
rename from spring-boot-web/src/main/java/com/neo/domain/UserRepository.java
rename to 1.x/spring-boot-web/src/main/java/com/neo/domain/UserRepository.java
diff --git a/1.x/spring-boot-web/src/main/java/com/neo/util/NeoProperties.java b/1.x/spring-boot-web/src/main/java/com/neo/util/NeoProperties.java
new file mode 100644
index 000000000..ab337bfbd
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/java/com/neo/util/NeoProperties.java
@@ -0,0 +1,26 @@
+package com.neo.util;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NeoProperties {
+
+ @Value("${com.neo.title}")
+ private String title;
+ @Value("${com.neo.description}")
+ private String description;
+ public String getTitle() {
+ return title;
+ }
+ public void setTitle(String title) {
+ this.title = title;
+ }
+ public String getDescription() {
+ return description;
+ }
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+}
diff --git a/1.x/spring-boot-web/src/main/java/com/neo/web/HelloController.java b/1.x/spring-boot-web/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..5fd95a062
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,30 @@
+package com.neo.web;
+
+import java.util.Locale;
+import java.util.UUID;
+
+import javax.servlet.http.HttpSession;
+
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+
+ @RequestMapping("/hello")
+ public String hello(Locale locale, Model model) {
+ return "hello world";
+ }
+
+ @RequestMapping("/uid")
+ String uid(HttpSession session) {
+ UUID uid = (UUID) session.getAttribute("uid");
+ if (uid == null) {
+ uid = UUID.randomUUID();
+ }
+ session.setAttribute("uid", uid);
+ return session.getId();
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-web/src/main/java/com/neo/web/ThymeleafController.java b/1.x/spring-boot-web/src/main/java/com/neo/web/ThymeleafController.java
new file mode 100644
index 000000000..c384bd1d8
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/java/com/neo/web/ThymeleafController.java
@@ -0,0 +1,26 @@
+package com.neo.web;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class ThymeleafController {
+
+ @RequestMapping("/hi")
+ public String hello(Locale locale, Model model) {
+ model.addAttribute("greeting", "Hello!");
+
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
+ String formattedDate = dateFormat.format(date);
+ model.addAttribute("currentTime", formattedDate);
+
+ return "hello";
+ }
+
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-web/src/main/java/com/neo/web/UserController.java b/1.x/spring-boot-web/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..983617cce
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,34 @@
+package com.neo.web;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.neo.domain.User;
+import com.neo.domain.UserRepository;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @RequestMapping("/getUser")
+ @Cacheable(value="user-key")
+ public User getUser() {
+ User user=userRepository.findByUserName("aa");
+ System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
+ return user;
+ }
+
+ @RequestMapping("/getUsers")
+ @Cacheable(value="key-Users")
+ public List getUsers() {
+ List users=userRepository.findAll();
+ System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
+ return users;
+ }
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-web/src/main/resources/application.properties b/1.x/spring-boot-web/src/main/resources/application.properties
new file mode 100644
index 000000000..16fed3698
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/resources/application.properties
@@ -0,0 +1,32 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/test
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+
+spring.jpa.properties.hibernate.hbm2ddl.auto=update
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.show-sql= true
+
+com.neo.title=\u7eaf\u6d01\u7684\u5fae\u7b11
+com.neo.description=\u5206\u4eab\u751f\u6d3b\u548c\u6280\u672f
+
+# REDIS (RedisProperties)
+# Redis\u6570\u636e\u5e93\u7d22\u5f15\uff08\u9ed8\u8ba4\u4e3a0\uff09
+spring.redis.database=0
+# Redis\u670d\u52a1\u5668\u5730\u5740
+spring.redis.host=192.168.0.71
+# Redis\u670d\u52a1\u5668\u8fde\u63a5\u7aef\u53e3
+spring.redis.port=6379
+# Redis\u670d\u52a1\u5668\u8fde\u63a5\u5bc6\u7801\uff08\u9ed8\u8ba4\u4e3a\u7a7a\uff09
+spring.redis.password=
+# \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=8
+# \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\u5927\u7a7a\u95f2\u8fde\u63a5
+spring.redis.pool.max-idle=8
+# \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5
+spring.redis.pool.min-idle=0
+# \u8fde\u63a5\u8d85\u65f6\u65f6\u95f4\uff08\u6beb\u79d2\uff09
+spring.redis.timeout=0
+
diff --git a/1.x/spring-boot-web/src/main/resources/static/css/starter.css b/1.x/spring-boot-web/src/main/resources/static/css/starter.css
new file mode 100644
index 000000000..e2fc60cd4
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/resources/static/css/starter.css
@@ -0,0 +1,8 @@
+body {
+ padding-top: 50px;
+}
+
+.starter-template {
+ padding: 40px 15px;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/1.x/spring-boot-web/src/main/resources/static/images/favicon.png b/1.x/spring-boot-web/src/main/resources/static/images/favicon.png
new file mode 100644
index 000000000..890ef0630
Binary files /dev/null and b/1.x/spring-boot-web/src/main/resources/static/images/favicon.png differ
diff --git a/1.x/spring-boot-web/src/main/resources/templates/hello.html b/1.x/spring-boot-web/src/main/resources/templates/hello.html
new file mode 100644
index 000000000..c417054af
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/resources/templates/hello.html
@@ -0,0 +1,18 @@
+
+
+
+
+ (navbar)
+
+
+
+
Spring MVC / Thymeleaf / Bootstrap
+
(greeting)
+
The current time is (time)
+
+
+
+
+
+
+
diff --git a/1.x/spring-boot-web/src/main/resources/templates/layout.html b/1.x/spring-boot-web/src/main/resources/templates/layout.html
new file mode 100644
index 000000000..422fbb71e
--- /dev/null
+++ b/1.x/spring-boot-web/src/main/resources/templates/layout.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+ (title)
+
+
+
+
+
+
+
+
+
+
+
Spring MVC/Thymeleaf/Bootstrap
+
(greeting)
+
+
+
+
+
+
+
diff --git a/spring-boot-web/src/test/java/com/neo/ApplicationTests.java b/1.x/spring-boot-web/src/test/java/com/neo/ApplicationTests.java
similarity index 100%
rename from spring-boot-web/src/test/java/com/neo/ApplicationTests.java
rename to 1.x/spring-boot-web/src/test/java/com/neo/ApplicationTests.java
diff --git a/spring-boot-web/src/test/java/com/neo/domain/UserRepositoryTests.java b/1.x/spring-boot-web/src/test/java/com/neo/domain/UserRepositoryTests.java
similarity index 100%
rename from spring-boot-web/src/test/java/com/neo/domain/UserRepositoryTests.java
rename to 1.x/spring-boot-web/src/test/java/com/neo/domain/UserRepositoryTests.java
diff --git a/spring-boot-web/src/test/java/com/neo/util/TestRedis.java b/1.x/spring-boot-web/src/test/java/com/neo/util/TestRedis.java
similarity index 100%
rename from spring-boot-web/src/test/java/com/neo/util/TestRedis.java
rename to 1.x/spring-boot-web/src/test/java/com/neo/util/TestRedis.java
diff --git a/spring-boot-web/src/test/java/com/neo/web/HelloControlerTests.java b/1.x/spring-boot-web/src/test/java/com/neo/web/HelloControlerTests.java
similarity index 100%
rename from spring-boot-web/src/test/java/com/neo/web/HelloControlerTests.java
rename to 1.x/spring-boot-web/src/test/java/com/neo/web/HelloControlerTests.java
diff --git a/1.x/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java b/1.x/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java
new file mode 100644
index 000000000..ae0b39960
--- /dev/null
+++ b/1.x/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java
@@ -0,0 +1,40 @@
+package com.neo.web;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.neo.Application;
+import com.neo.util.NeoProperties;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ProPertiesTest {
+
+
+ @Autowired
+ private NeoProperties neoProperties;
+
+
+ @Test
+ public void getHello() throws Exception {
+ System.out.println(neoProperties.getTitle());
+ Assert.assertEquals(neoProperties.getTitle(), "纯洁的微笑");
+ Assert.assertEquals(neoProperties.getDescription(), "分享生活和技术");
+ }
+
+
+ @Test
+ public void testMap() throws Exception {
+ Map orderMinTime=new HashMap();
+ long xx=orderMinTime.get("123");
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/README.md b/2.x/README.md
new file mode 100644
index 000000000..5d86202fd
--- /dev/null
+++ b/2.x/README.md
@@ -0,0 +1,118 @@
+Spring Boot 学习示例
+=========================
+
+
+
+
+
+
+
+Spring Boot 使用的各种示例,以最简单、最实用为标准,此开源项目中的每个示例都以最小依赖,最简单为标准,帮助初学者快速掌握 Spring Boot 各组件的使用。
+
+[Spring Boot 中文索引](https://github.com/ityouknow/awesome-spring-boot) | [Spring Cloud学习示例代码](https://github.com/ityouknow/spring-cloud-examples) | [Spring Boot 精品课程](https://github.com/ityouknow/spring-boot-leaning)
+
+[English](README_EN.md) | [Github地址](https://github.com/ityouknow/spring-boot-examples) | [码云地址](https://gitee.com/ityouknow/spring-boot-examples) | [Spring Boot 1.0](https://github.com/ityouknow/spring-boot-examples/tree/Spring-Boot-1.0)
+
+---
+
+推荐程序员都关注的一个漫画公众号
+
+
+
+关注后,回复:**java** 获取超过 10万 人领取的 Java 知识体系/面试必看资料。
+
+
+
+## Spring Boot 2.0
+
+**[Spring Boot 2.0 最全使用教程](https://github.com/ityouknow/spring-boot-leaning)**
+
+**[Favorites-web](https://github.com/cloudfavorites/favorites-web):云收藏(Spring Boot 2.0 实战开源项目)**
+
+**示例代码**
+
+- [spring-boot-hello](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-hello):Spring Boot 2.0 Hello World 示例
+- [spring-boot-banner](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-banner):Spring Boot 定制 Banner 示例
+- [spring-boot-docker](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-docker):使用 Docker 部署 Spring Boot 示例
+- [dockercompose-springboot-mysql-nginx](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/dockercompose-springboot-mysql-nginx) :Docker Compose + Spring Boot + Nginx + Mysql 示例
+- [spring-boot-commandLineRunner](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-commandLineRunner) :Spring Boot 使用 commandLineRunner 实现项目启动时资源初始化示例
+- [spring-boot-web-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-web-thymeleaf) :Spring Boot 使用 thymeleaf 实现布局、验参、增删改查示例
+- [spring-boot-memcache-spymemcached](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-memcache-spymemcached) :Spring Boot 使用 spymemcached 集成 memcache 示例
+- [spring-boot-webflux](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-webflux) :Spring Boot webflux 示例
+- [spring-boot-elasticsearch](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-elasticsearch) :Spring Boot elasticsearch 示例
+- [spring-boot-swagger](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-swagger) :Spring Boot swagger2 示例
+- [spring-boot-mybatis-plus](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis-plus) :Spring Boot 集成 MyBatis Plus 示例
+
+**参考文章**
+
+- [Spring Boot 2(一):【重磅】Spring Boot 2.0权威发布](http://www.ityouknow.com/springboot/2018/03/01/spring-boot-2.0.html)
+- [Spring Boot 2(二):Spring Boot 2.0尝鲜-动态 Banner](http://www.ityouknow.com/springboot/2018/03/03/spring-boot-banner.html)
+- [Spring Boot 2(三):Spring Boot 开源软件都有哪些?](http://www.ityouknow.com/springboot/2018/03/05/spring-boot-open-source.html)
+- [Spring Boot 2(四):使用 Docker 部署 Spring Boot](http://www.ityouknow.com/springboot/2018/03/19/spring-boot-docker.html)
+- [Spring Boot 2(五):Docker Compose + Spring Boot + Nginx + Mysql 实践](http://www.ityouknow.com/springboot/2018/03/28/dockercompose-springboot-mysql-nginx.html)
+- [Spring Boot 2(六):使用 Docker 部署 Spring Boot 开源软件云收藏](http://www.ityouknow.com/springboot/2018/04/02/docker-favorites.html)
+- [Spring Boot 2(七):Spring Boot 如何解决项目启动时初始化资源](http://www.ityouknow.com/springboot/2018/05/03/spring-boot-commandLineRunner.html)
+- [Spring Boot 2(八):Spring Boot 集成 Memcached](http://www.ityouknow.com/springboot/2018/09/01/spring-boot-memcached.html)
+- [Spring Boot 2 (九):【重磅】Spring Boot 2.1.0 权威发布](http://www.ityouknow.com/springboot/2018/11/03/spring-boot-2.1.html)
+- [Spring Boot/Cloud 研发团队介绍](http://www.ityouknow.com/springboot/2019/01/03/spring-pivotal.html)
+- [Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门](http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html)
+
+
+## 下方示例已经全部升级到 2.X
+
+**示例代码**
+
+- [spring-boot-helloWorld](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-helloWorld):Spring Boot 的 hello World 版本
+- [spring-boot-web](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-web):Spring Boot Web 开发综合示例
+- [spring-boot-redis](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-redis):Spring Boot 集成 Redis 示例
+- [spring-boot-jpa](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-jpa):Spring Boot 使用 Jpa 各种示例
+- [spring-boot-mybaits-annotation](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation):注解版本
+- [spring-boot-mybaits-xml](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-xml):Xml 配置版本
+- [spring-boot-mybatis-xml-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource):Spring Boot + Mybatis (Xml 版) 多数据源最简解决方案
+- [spring-boot-mybatis-annotation-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource):Spring Boot + Mybatis(注解版)多数据源最简解决方案
+- [spring-boot-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-thymeleaf):Spring Boot 使用 Thymeleaf 详细示例
+- [spring-boot-jpa-thymeleaf-curd](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-jpa-thymeleaf-curd):Spring Boot + Jpa + Thymeleaf 增删改查示例
+- [spring-boot-rabbitmq](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-rabbitmq):Spring Boot 和 Rabbitmq 各种消息应用案例
+- [spring-boot-scheduler](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-scheduler):Spring Boot 和定时任务案例
+- [spring-boot-mail](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mail):Spring Boot 和邮件服务
+- [spring-boot-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mongodb/spring-boot-mongodb):Spring Boot 和 Mongodb 的使用
+- [spring-boot-multi-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mongodb/spring-boot-multi-mongodb):Spring Boot 和 Mongodb 多数据源的使用
+- [spring-boot-package-war](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-package-war): Spring Boot 打包成 War 包示例
+- [spring-boot-shiro](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-shiro):Spring Boot 整合 Shiro Rbac 示例
+- [spring-boot-file-upload](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-file-upload):使用 Spring Boot 上传文件示例
+- [spring-boot-fastDFS](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-fastDFS):Spring Boot 整合 FastDFS 示例
+- [spring-boot-actuator](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-actuator):Spring Boot Actuator 使用示例
+- [spring-boot-admin-simple](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-admin-simple):Spring Boot Admin 的使用示例
+
+**参考文章**
+
+- [Spring Boot(一):入门篇](http://www.ityouknow.com/springboot/2016/01/06/spring-boot-quick-start.html)
+- [Spring Boot(二):Web 综合开发](http://www.ityouknow.com/springboot/2016/02/03/spring-boot-web.html)
+- [Spring Boot(三):Spring Boot 中 Redis 的使用](http://www.ityouknow.com/springboot/2016/03/06/spring-boot-redis.html)
+- [Spring Boot(四):Thymeleaf 使用详解](http://www.ityouknow.com/springboot/2016/05/01/spring-boot-thymeleaf.html)
+- [Spring Boot(五):Spring Data Jpa 的使用](http://www.ityouknow.com/springboot/2016/08/20/spring-boot-jpa.html)
+- [Spring Boot(六):如何优雅的使用 Mybatis](http://www.ityouknow.com/springboot/2016/11/06/spring-boot-mybatis.html)
+- [Spring Boot(七):Spring Boot + Mybatis 多数据源最简解决方案](http://www.ityouknow.com/springboot/2016/11/25/spring-boot-multi-mybatis.html)
+- [Spring Boot(八):RabbitMQ 详解](http://www.ityouknow.com/springboot/2016/11/30/spring-boot-rabbitMQ.html)
+- [Spring Boot(九):定时任务](http://www.ityouknow.com/springboot/2016/12/02/spring-boot-scheduler.html)
+- [Spring Boot(十):邮件服务](http://www.ityouknow.com/springboot/2017/05/06/spring-boot-mail.html)
+- [Spring Boot(十一):Spring Boot 中 Mongodb 的使用](http://www.ityouknow.com/springboot/2017/05/08/spring-boot-mongodb.html)
+- [Spring Boot(十二):Spring Boot 如何测试打包部署](http://www.ityouknow.com/springboot/2017/05/09/spring-boot-deploy.html)
+- [Spring Boot(十三):Spring Boot 小技巧](http://www.ityouknow.com/springboot/2017/06/22/spring-boot-tips.html)
+- [Spring Boot(十四):Spring Boot 整合 Shiro-登录认证和权限管理](http://www.ityouknow.com/springboot/2017/06/26/spring-boot-shiro.html)
+- [Spring Boot(十五):Spring Boot + Jpa + Thymeleaf 增删改查示例](http://www.ityouknow.com/springboot/2017/09/23/spring-boot-jpa-thymeleaf-curd.html)
+- [Spring Boot(十六):使用 Jenkins 部署 Spring Boot](http://www.ityouknow.com/springboot/2017/11/11/spring-boot-jenkins.html)
+- [Spring Boot(十七):使用 Spring Boot 上传文件](http://www.ityouknow.com/springboot/2018/01/12/spring-boot-upload-file.html)
+- [Spring Boot(十八):使用 Spring Boot 集成 FastDFS](http://www.ityouknow.com/springboot/2018/01/16/spring-boot-fastdfs.html)
+- [Spring Boot(十九):使用 Spring Boot Actuator 监控应用](http://www.ityouknow.com/springboot/2018/02/06/spring-boot-actuator.html)
+- [Spring Boot(二十):使用 spring-boot-admin 对 Spring Boot 服务进行监控](http://www.ityouknow.com/springboot/2018/02/11/spring-boot-admin.html)
+
+**[Spring Boot 实战:我们的第一款开源项目](http://www.ityouknow.com/springboot/2016/09/26/spring-boot-opensource-favorites.html)**
+
+---
+
+> 如果大家想了解关于 Spring Boot 的其它方面应用,也可以以[issues](https://github.com/ityouknow/spring-boot-examples/issues)的形式反馈给我,我后续来完善。
+
+关注公众号:纯洁的微笑,回复"666"进群交流
+
+
\ No newline at end of file
diff --git a/2.x/README_EN.md b/2.x/README_EN.md
new file mode 100644
index 000000000..2868c31f5
--- /dev/null
+++ b/2.x/README_EN.md
@@ -0,0 +1,54 @@
+# Spring Boot Examples
+
+This tutorial is about learning Spring Boot via examples.
+
+[Spring Cloud Example Code](https://github.com/ityouknow/spring-cloud-examples) | [中文](README.md)
+
+Spring Boot examples, using the simplest and the most useful scene demos.
+
+---
+
+## Spring Boot 2.X
+
+
+**[Favorites-web](https://github.com/cloudfavorites/favorites-web):Open source projects developed using Spring Boot 2.X**
+
+- [spring-boot-hello](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-hello):Spring Boot 2.0 Hello World Demo
+- [spring-boot-banner](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-banner):Spring Boot Customized Banner
+- [spring-boot-docker](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-docker):Spring Boot with Docker
+- [dockercompose-springboot-mysql-nginx](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/dockercompose-springboot-mysql-nginx) :Docker Compose + Spring Boot + Nginx + Mysql example
+- [spring-boot-commandLineRunner](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-commandLineRunner) :Example of resource initialization at project startup using Spring Boot and commandLineRunner
+- [spring-boot-web-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-web-thymeleaf) :Spring Boot uses thymeleaf to implement layout, check parameters and CURD
+- [spring-boot-memcache-spymemcached](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-memcache-spymemcached) :Spring Boot uses spymemcached to memcache
+- [spring-boot-webflux](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-webflux) :Spring Boot webflux demo
+- [spring-boot-elasticsearch](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-elasticsearch) :Spring Boot elasticsearch demo
+- [spring-boot-swagger](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-swagger) :Spring Boot swagger2 demo
+- [spring-boot-mybatis-plus](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis-plus) :Spring Boot MyBatis Plus demo
+
+
+---
+
+## Spring Boot (Already upgraded to 2.x)
+
+- [spring-boot-helloWorld](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-helloWorld):Spring Boot helloWorld
+- [spring-boot-redis](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-redis):Spring Boot Redis Demo
+- [spring-boot-jpa](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-jpa):Spring Boot Jpa Demo
+- [spring-boot-mybaits-annotation](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation):Spring Boot use mybatis annotation
+- [spring-boot-mybaits-xml](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-xml):Spring Boot use mybatis xml
+- [spring-boot-mybatis-xml-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource):Spring Boot+mybatis+mulidatasource
+- [spring-boot-mybatis-annotation-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource):Spring Boot+ mybatis annotation + mulidatasource
+- [spring-boot-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-thymeleaf):Spring Boot Thymeleaf Demo
+- [spring-boot-jpa-thymeleaf-curd](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-jpa-thymeleaf-curd):spring boot + jpa + thymeleaf curd demo
+- [spring-boot-rabbitmq](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-rabbitmq): using AMQP and RabbitMQ
+- [spring-boot-scheduler](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-scheduler):Timed tasks developed using Spring Boot
+- [spring-boot-web](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-web):Web projects developed using Spring Boot
+- [spring-boot-mail](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mail):Mail system developed using Spring Boot
+- [spring-boot-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mongodb/spring-boot-mongodb):Spring Boot + Mongodb
+- [spring-boot-multi-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-mongodb/spring-boot-multi-mongodb):Spring Boot + multiMongodb
+- [spring-boot-package-war](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-package-war):Spring Boot package war
+- [spring-boot-shiro](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-shiro):spring boot shiro rbac demo
+- [spring-boot-file-upload](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-file-upload):Spring Boot upload file demo
+- [spring-boot-fastDFS](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-fastDFS):Spring Boot Integrate FastDFS upload delete and so on
+- [spring-boot-actuator](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-actuator):Spring Boot Actuator demo
+- [spring-boot-admin-simple](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-admin-simple):Spring Boot Admin demo
+- [spring-boot-banner](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x/spring-boot-banner):Spring Boot Cumtom Banner
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/Dockerfile b/2.x/dockercompose-springboot-mysql-nginx/app/Dockerfile
new file mode 100644
index 000000000..6ae65e4e7
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/Dockerfile
@@ -0,0 +1 @@
+FROM maven:3.5-jdk-8
\ No newline at end of file
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/pom.xml b/2.x/dockercompose-springboot-mysql-nginx/app/pom.xml
new file mode 100644
index 000000000..1dc59f64b
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+
+ com.neo
+ dockercompose-springboot-mysql-nginx
+ 1.0
+ jar
+
+ dockercompose-springboot-mysql-nginx
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.RELEASE
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ compile
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/ComposeApplication.java b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/ComposeApplication.java
new file mode 100644
index 000000000..9c2646d0a
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/ComposeApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ComposeApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ComposeApplication.class, args);
+ }
+}
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/controller/VisitorController.java b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/controller/VisitorController.java
new file mode 100644
index 000000000..583be103f
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/controller/VisitorController.java
@@ -0,0 +1,31 @@
+package com.neo.controller;
+
+import com.neo.entity.Visitor;
+import com.neo.repository.VisitorRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+public class VisitorController {
+
+ @Autowired
+ private VisitorRepository repository;
+
+ @RequestMapping("/")
+ public String index(HttpServletRequest request) {
+ String ip=request.getRemoteAddr();
+ Visitor visitor=repository.findByIp(ip);
+ if(visitor==null){
+ visitor=new Visitor();
+ visitor.setIp(ip);
+ visitor.setTimes(1);
+ }else {
+ visitor.setTimes(visitor.getTimes()+1);
+ }
+ repository.save(visitor);
+ return "I have been seen ip "+visitor.getIp()+" "+visitor.getTimes()+" times.";
+ }
+}
\ No newline at end of file
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/entity/Visitor.java b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/entity/Visitor.java
new file mode 100644
index 000000000..43cfa34b0
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/entity/Visitor.java
@@ -0,0 +1,41 @@
+package com.neo.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class Visitor {
+ @Id
+ @GeneratedValue
+ private long id;
+ @Column(nullable = false)
+ private long times;
+ @Column(nullable = false)
+ private String ip;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getTimes() {
+ return times;
+ }
+
+ public void setTimes(long times) {
+ this.times = times;
+ }
+
+ public String getIp() {
+ return ip;
+ }
+
+ public void setIp(String ip) {
+ this.ip = ip;
+ }
+}
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/repository/VisitorRepository.java b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/repository/VisitorRepository.java
new file mode 100644
index 000000000..7395c3962
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/repository/VisitorRepository.java
@@ -0,0 +1,8 @@
+package com.neo.repository;
+
+import com.neo.entity.Visitor;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface VisitorRepository extends JpaRepository {
+ Visitor findByIp(String ip);
+}
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-dev.properties b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-dev.properties
new file mode 100644
index 000000000..25126f01f
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-dev.properties
@@ -0,0 +1,4 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/test
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
\ No newline at end of file
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-docker.properties b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-docker.properties
new file mode 100644
index 000000000..eacae6203
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-docker.properties
@@ -0,0 +1,4 @@
+spring.datasource.url=jdbc:mysql://mysql:3306/test
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
\ No newline at end of file
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application.properties b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application.properties
new file mode 100644
index 000000000..242edfd64
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+spring.jpa.properties.hibernate.hbm2ddl.auto=update
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.show-sql=true
+
+spring.profiles.active=dev
\ No newline at end of file
diff --git a/2.x/dockercompose-springboot-mysql-nginx/app/src/test/java/com/neo/ComposeApplicationTests.java b/2.x/dockercompose-springboot-mysql-nginx/app/src/test/java/com/neo/ComposeApplicationTests.java
new file mode 100644
index 000000000..b0f9edf6a
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/app/src/test/java/com/neo/ComposeApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ComposeApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("Hello Spring Boot Docker Compose!");
+ }
+
+}
diff --git a/2.x/dockercompose-springboot-mysql-nginx/docker-compose.yaml b/2.x/dockercompose-springboot-mysql-nginx/docker-compose.yaml
new file mode 100644
index 000000000..028978f5b
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/docker-compose.yaml
@@ -0,0 +1,36 @@
+version: '3'
+services:
+ nginx:
+ container_name: v-nginx
+ image: nginx:1.13
+ restart: always
+ ports:
+ - 80:80
+ - 443:443
+ volumes:
+ - ./nginx/conf.d:/etc/nginx/conf.d
+
+ mysql:
+ container_name: v-mysql
+ image: mysql/mysql-server:5.7
+ environment:
+ MYSQL_DATABASE: test
+ MYSQL_ROOT_PASSWORD: root
+ MYSQL_ROOT_HOST: '%'
+ ports:
+ - "3306:3306"
+ restart: always
+
+ app:
+ restart: always
+ build: ./app
+ working_dir: /app
+ volumes:
+ - ./app:/app
+ - ~/.m2:/root/.m2
+ expose:
+ - "8080"
+ depends_on:
+ - nginx
+ - mysql
+ command: mvn clean spring-boot:run -Dspring-boot.run.profiles=docker
\ No newline at end of file
diff --git a/2.x/dockercompose-springboot-mysql-nginx/nginx/conf.d/app.conf b/2.x/dockercompose-springboot-mysql-nginx/nginx/conf.d/app.conf
new file mode 100644
index 000000000..486051450
--- /dev/null
+++ b/2.x/dockercompose-springboot-mysql-nginx/nginx/conf.d/app.conf
@@ -0,0 +1,20 @@
+server {
+ listen 80;
+ charset utf-8;
+ access_log off;
+
+ location / {
+ proxy_pass http://app:8080;
+ proxy_set_header Host $host:$server_port;
+ proxy_set_header X-Forwarded-Host $server_name;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ }
+
+ location /static {
+ access_log off;
+ expires 30d;
+
+ alias /app/static;
+ }
+}
diff --git a/2.x/pom.xml b/2.x/pom.xml
new file mode 100644
index 000000000..dd4658e00
--- /dev/null
+++ b/2.x/pom.xml
@@ -0,0 +1,62 @@
+
+
+ 4.0.0
+
+ com.example
+ spring-boot-examples
+ pom
+ 2.0.0
+
+
+ dockercompose-springboot-mysql-nginx/app
+ spring-boot-actuator
+ spring-boot-admin-simple
+ spring-boot-banner
+ spring-boot-commandLineRunner
+ spring-boot-docker
+ spring-boot-elasticsearch
+ spring-boot-file-upload
+ spring-boot-hello
+ spring-boot-helloWorld
+ spring-boot-jpa/spring-boot-jpa
+ spring-boot-jpa/spring-boot-multi-Jpa
+ spring-boot-jpa-thymeleaf-curd
+ spring-boot-mail
+ spring-boot-memcache-spymemcached
+ spring-boot-mongodb/spring-boot-mongodb
+ spring-boot-mongodb/spring-boot-multi-mongodb
+ spring-boot-mybatis/spring-boot-mybatis-annotation
+ spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource
+ spring-boot-mybatis/spring-boot-mybatis-xml
+ spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource
+ spring-boot-mybatis-plus
+ spring-boot-package
+ spring-boot-package-war
+ spring-boot-rabbitmq
+ spring-boot-redis
+ spring-boot-scheduler
+ spring-boot-shiro
+ spring-boot-swagger
+ spring-boot-thymeleaf/spring-boot-thymeleaf
+ spring-boot-thymeleaf/spring-boot-thymeleaf-layout
+ spring-boot-web
+ spring-boot-web-thymeleaf
+ spring-boot-webflux
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ 1.8
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-actuator/pom.xml b/2.x/spring-boot-actuator/pom.xml
new file mode 100644
index 000000000..770a97118
--- /dev/null
+++ b/2.x/spring-boot-actuator/pom.xml
@@ -0,0 +1,59 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-actuator
+ 1.0.0-SNAPSHOT
+ jar
+
+ spring-boot-actuator
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
diff --git a/2.x/spring-boot-actuator/src/main/java/com/neo/ActuatorApplication.java b/2.x/spring-boot-actuator/src/main/java/com/neo/ActuatorApplication.java
new file mode 100644
index 000000000..66b22076b
--- /dev/null
+++ b/2.x/spring-boot-actuator/src/main/java/com/neo/ActuatorApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ActuatorApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ActuatorApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-actuator/src/main/java/com/neo/controller/HelloController.java b/2.x/spring-boot-actuator/src/main/java/com/neo/controller/HelloController.java
new file mode 100644
index 000000000..5e93f0dda
--- /dev/null
+++ b/2.x/spring-boot-actuator/src/main/java/com/neo/controller/HelloController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+
+ @RequestMapping("/hello")
+ public String index() {
+ return "Hello World";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-actuator/src/main/resources/application.properties b/2.x/spring-boot-actuator/src/main/resources/application.properties
new file mode 100644
index 000000000..4157eba14
--- /dev/null
+++ b/2.x/spring-boot-actuator/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+info.app.name=spring-boot-actuator
+info.app.version= 1.0.0
+info.app.test=test
+
+management.endpoints.web.exposure.include=*
+management.endpoint.health.show-details=always
+#management.endpoints.web.base-path=/manage
+
+management.endpoint.shutdown.enabled=true
diff --git a/2.x/spring-boot-actuator/src/test/java/com/neo/ActuatorApplicationTests.java b/2.x/spring-boot-actuator/src/test/java/com/neo/ActuatorApplicationTests.java
new file mode 100644
index 000000000..e122032a2
--- /dev/null
+++ b/2.x/spring-boot-actuator/src/test/java/com/neo/ActuatorApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ActuatorApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello word");
+ }
+
+}
diff --git a/2.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloTests.java b/2.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloTests.java
new file mode 100644
index 000000000..149543930
--- /dev/null
+++ b/2.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloTests.java
@@ -0,0 +1,36 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloTests {
+
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/2.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloWorldControlerTests.java
new file mode 100644
index 000000000..d8b01a50d
--- /dev/null
+++ b/2.x/spring-boot-actuator/src/test/java/com/neo/controller/HelloWorldControlerTests.java
@@ -0,0 +1,34 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloWorldControlerTests {
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-admin-simple/pom.xml b/2.x/spring-boot-admin-simple/pom.xml
new file mode 100644
index 000000000..b75244055
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+ com.neo
+ spring-boot-admin-simple
+ 1.0.0.BUILD-SNAPSHOT
+
+
+ spring-boot-admin-server
+ spring-boot-admin-client
+
+
+ pom
+ Spring boot admin
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ Edgware.SR1
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-client/pom.xml b/2.x/spring-boot-admin-simple/spring-boot-admin-client/pom.xml
new file mode 100644
index 000000000..3f456f43b
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-client/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-admin-simple
+ 1.0.0.BUILD-SNAPSHOT
+
+ spring-boot-admin-client
+ jar
+
+
+
+ de.codecentric
+ spring-boot-admin-starter-client
+ 2.1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/java/com/neo/AdminClientApplication.java b/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/java/com/neo/AdminClientApplication.java
new file mode 100644
index 000000000..9494e5efe
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/java/com/neo/AdminClientApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class AdminClientApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AdminClientApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/resources/application.properties b/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/resources/application.properties
new file mode 100644
index 000000000..a9ef7959b
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+server.port=8001
+
+spring.application.name=Admin Client
+spring.boot.admin.client.url=http://localhost:8000
+management.endpoints.web.exposure.include=*
\ No newline at end of file
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/test/java/com/neo/AdminClientApplicationTests.java b/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/test/java/com/neo/AdminClientApplicationTests.java
new file mode 100644
index 000000000..ad4141adf
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-client/src/test/java/com/neo/AdminClientApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 AdminClientApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-server/pom.xml b/2.x/spring-boot-admin-simple/spring-boot-admin-server/pom.xml
new file mode 100644
index 000000000..23881f472
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-server/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-admin-simple
+ 1.0.0.BUILD-SNAPSHOT
+
+ spring-boot-admin-server
+ jar
+
+
+
+ de.codecentric
+ spring-boot-admin-starter-server
+ 2.1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/java/com/neo/AdminServerApplication.java b/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/java/com/neo/AdminServerApplication.java
new file mode 100644
index 000000000..b939267cd
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/java/com/neo/AdminServerApplication.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+import de.codecentric.boot.admin.server.config.EnableAdminServer;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableAutoConfiguration
+@EnableAdminServer
+public class AdminServerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AdminServerApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/resources/application.properties b/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/resources/application.properties
new file mode 100644
index 000000000..4e7c8e915
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+server.port=8000
+
diff --git a/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/test/java/com/neo/AdminServerApplicationTests.java b/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/test/java/com/neo/AdminServerApplicationTests.java
new file mode 100644
index 000000000..6179c4d40
--- /dev/null
+++ b/2.x/spring-boot-admin-simple/spring-boot-admin-server/src/test/java/com/neo/AdminServerApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 AdminServerApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-banner/pom.xml b/2.x/spring-boot-banner/pom.xml
new file mode 100644
index 000000000..763b87317
--- /dev/null
+++ b/2.x/spring-boot-banner/pom.xml
@@ -0,0 +1,42 @@
+
+
+ 4.0.0
+
+ com.example
+ spring-boot-banner
+ 2.0.0
+ jar
+
+ Spring Boot banner
+ A very useful project to demonstrate animated gif support in Spring Boot 2
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.RELEASE
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-banner/src/main/java/com/neo/banner/BannerApplication.java b/2.x/spring-boot-banner/src/main/java/com/neo/banner/BannerApplication.java
new file mode 100644
index 000000000..4e7bc12db
--- /dev/null
+++ b/2.x/spring-boot-banner/src/main/java/com/neo/banner/BannerApplication.java
@@ -0,0 +1,12 @@
+package com.neo.banner;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class BannerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(BannerApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-banner/src/main/resources/application.properties b/2.x/spring-boot-banner/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/2.x/spring-boot-banner/src/main/resources/banner.gif b/2.x/spring-boot-banner/src/main/resources/banner.gif
new file mode 100644
index 000000000..73f318282
Binary files /dev/null and b/2.x/spring-boot-banner/src/main/resources/banner.gif differ
diff --git a/2.x/spring-boot-banner/src/main/resources/banner.txt b/2.x/spring-boot-banner/src/main/resources/banner.txt
new file mode 100644
index 000000000..79bcf7576
--- /dev/null
+++ b/2.x/spring-boot-banner/src/main/resources/banner.txt
@@ -0,0 +1,6 @@
+.__ .__ .__ .__ .___
+| |__ ____ | | | | ____ __ _ _____________| | __| _/
+| | \_/ __ \| | | | / _ \ \ \/ \/ / _ \_ __ \ | / __ |
+| Y \ ___/| |_| |_( <_> ) \ ( <_> ) | \/ |__/ /_/ |
+|___| /\___ >____/____/\____/ \/\_/ \____/|__| |____/\____ |
+ \/ \/ \/
\ No newline at end of file
diff --git a/2.x/spring-boot-commandLineRunner/pom.xml b/2.x/spring-boot-commandLineRunner/pom.xml
new file mode 100644
index 000000000..3dd6ee720
--- /dev/null
+++ b/2.x/spring-boot-commandLineRunner/pom.xml
@@ -0,0 +1,42 @@
+
+
+ 4.0.0
+
+ com.example
+ spring-boot-commandLineRunner
+ 2.0.0
+ jar
+
+ Spring Boot banner
+ Spring Boot and commandLineRunner demo
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.RELEASE
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/CommandLineRunnerApplication.java b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/CommandLineRunnerApplication.java
new file mode 100644
index 000000000..d1f685efa
--- /dev/null
+++ b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/CommandLineRunnerApplication.java
@@ -0,0 +1,15 @@
+package com.neo;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CommandLineRunnerApplication {
+
+ public static void main(String[] args) {
+ System.out.println("The service to start.");
+ SpringApplication.run(CommandLineRunnerApplication.class, args);
+ System.out.println("The service has started.");
+ }
+}
diff --git a/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/OrderRunner1.java b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/OrderRunner1.java
new file mode 100644
index 000000000..ea92d0d13
--- /dev/null
+++ b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/OrderRunner1.java
@@ -0,0 +1,15 @@
+package com.neo.runner;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+@Component
+@Order(1)
+public class OrderRunner1 implements CommandLineRunner {
+
+ @Override
+ public void run(String... args) throws Exception {
+ System.out.println("The OrderRunner1 start to initialize ...");
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/OrderRunner2.java b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/OrderRunner2.java
new file mode 100644
index 000000000..7265d82b1
--- /dev/null
+++ b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/OrderRunner2.java
@@ -0,0 +1,15 @@
+package com.neo.runner;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+@Component
+@Order(2)
+public class OrderRunner2 implements CommandLineRunner {
+
+ @Override
+ public void run(String... args) throws Exception {
+ System.out.println("The OrderRunner2 start to initialize ...");
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/Runner.java b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/Runner.java
new file mode 100644
index 000000000..647605d8e
--- /dev/null
+++ b/2.x/spring-boot-commandLineRunner/src/main/java/com/neo/runner/Runner.java
@@ -0,0 +1,13 @@
+package com.neo.runner;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Runner implements CommandLineRunner {
+
+ @Override
+ public void run(String... args) throws Exception {
+ System.out.println("The Runner start to initialize ...");
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-commandLineRunner/src/main/resources/application.properties b/2.x/spring-boot-commandLineRunner/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/2.x/spring-boot-docker/pom.xml b/2.x/spring-boot-docker/pom.xml
new file mode 100644
index 000000000..17946da0c
--- /dev/null
+++ b/2.x/spring-boot-docker/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-docker
+ 1.0
+ jar
+
+ spring-boot-docker
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.RELEASE
+
+
+
+ UTF-8
+ 1.8
+ springboot
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ com.spotify
+ docker-maven-plugin
+ 1.0.0
+
+ ${docker.image.prefix}/${project.artifactId}
+ src/main/docker
+
+
+ /
+ ${project.build.directory}
+ ${project.build.finalName}.jar
+
+
+
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-docker/src/main/docker/Dockerfile b/2.x/spring-boot-docker/src/main/docker/Dockerfile
new file mode 100644
index 000000000..be52a4852
--- /dev/null
+++ b/2.x/spring-boot-docker/src/main/docker/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:8-jdk-alpine
+VOLUME /tmp
+ADD spring-boot-docker-1.0.jar app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/2.x/spring-boot-docker/src/main/java/com/neo/DockerApplication.java b/2.x/spring-boot-docker/src/main/java/com/neo/DockerApplication.java
new file mode 100644
index 000000000..d3a027626
--- /dev/null
+++ b/2.x/spring-boot-docker/src/main/java/com/neo/DockerApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class DockerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DockerApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-docker/src/main/java/com/neo/controller/DockerController.java b/2.x/spring-boot-docker/src/main/java/com/neo/controller/DockerController.java
new file mode 100644
index 000000000..8b6ba6760
--- /dev/null
+++ b/2.x/spring-boot-docker/src/main/java/com/neo/controller/DockerController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class DockerController {
+
+ @RequestMapping("/")
+ public String index() {
+ return "Hello Docker!";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-docker/src/main/resources/application.properties b/2.x/spring-boot-docker/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/2.x/spring-boot-docker/src/test/java/com/neo/DockerApplicationTests.java b/2.x/spring-boot-docker/src/test/java/com/neo/DockerApplicationTests.java
new file mode 100644
index 000000000..b08b68913
--- /dev/null
+++ b/2.x/spring-boot-docker/src/test/java/com/neo/DockerApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class DockerApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello docker");
+ }
+
+}
diff --git a/2.x/spring-boot-elasticsearch/pom.xml b/2.x/spring-boot-elasticsearch/pom.xml
new file mode 100644
index 000000000..939098a08
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-elasticsearch
+ 1.0
+ jar
+
+ spring-boot-elasticsearch
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-elasticsearch
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-elasticsearch/src/main/java/com/neo/ElasticsearchApplication.java b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/ElasticsearchApplication.java
new file mode 100644
index 000000000..e16db52a3
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/ElasticsearchApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ElasticsearchApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ElasticsearchApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-elasticsearch/src/main/java/com/neo/model/Customer.java b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/model/Customer.java
new file mode 100644
index 000000000..e71076db0
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/model/Customer.java
@@ -0,0 +1,71 @@
+
+package com.neo.model;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.elasticsearch.annotations.Document;
+import org.springframework.data.elasticsearch.annotations.Field;
+
+@Document(indexName = "customer", type = "customer", shards = 1, replicas = 0, refreshInterval = "-1")
+public class Customer {
+
+ //Id注解加上后,在Elasticsearch里相应于该列就是主键了,在查询时就可以直接用主键查询
+ @Id
+ private String id;
+
+ private String userName;
+
+ private String address;
+
+ private int age;
+
+ public Customer() {
+ }
+
+ public Customer(String userName, String address, int age) {
+ this.userName = userName;
+ this.address = address;
+ this.age = age;
+ }
+
+ public String getId() {
+ return this.id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ @Override
+ public String toString() {
+ return "Customer{" +
+ "id='" + id + '\'' +
+ ", userName='" + userName + '\'' +
+ ", address='" + address + '\'' +
+ ", age=" + age +
+ '}';
+ }
+}
diff --git a/2.x/spring-boot-elasticsearch/src/main/java/com/neo/repository/CustomerRepository.java b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/repository/CustomerRepository.java
new file mode 100644
index 000000000..fec24b4d4
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/repository/CustomerRepository.java
@@ -0,0 +1,19 @@
+
+package com.neo.repository;
+
+import com.neo.model.Customer;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+
+import java.util.List;
+
+
+public interface CustomerRepository extends ElasticsearchRepository {
+ public List findByAddress(String address);
+ public Customer findByUserName(String userName);
+ public int deleteByUserName(String userName);
+ public Page findByAddress(String address, Pageable pageable);
+
+
+}
diff --git a/2.x/spring-boot-elasticsearch/src/main/java/com/neo/service/CustomersInterface.java b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/service/CustomersInterface.java
new file mode 100644
index 000000000..ad36175a9
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/service/CustomersInterface.java
@@ -0,0 +1,12 @@
+package com.neo.service;
+
+import com.neo.model.Customer;
+
+import java.util.List;
+
+public interface CustomersInterface {
+
+ public List searchCity(Integer pageNumber, Integer pageSize, String searchContent);
+
+
+}
diff --git a/2.x/spring-boot-elasticsearch/src/main/java/com/neo/service/impl/CustomersInterfaceImpl.java b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/service/impl/CustomersInterfaceImpl.java
new file mode 100644
index 000000000..742a52b1d
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/main/java/com/neo/service/impl/CustomersInterfaceImpl.java
@@ -0,0 +1,50 @@
+package com.neo.service.impl;
+
+import com.neo.model.Customer;
+import com.neo.repository.CustomerRepository;
+import com.neo.service.CustomersInterface;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
+import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
+import org.springframework.data.elasticsearch.core.query.SearchQuery;
+
+import java.util.List;
+
+public class CustomersInterfaceImpl implements CustomersInterface {
+
+ Logger logger= LoggerFactory.getLogger(this.getClass());
+ @Autowired
+ private CustomerRepository customerRepository;
+
+ @Override
+ public List searchCity(Integer pageNumber, Integer pageSize, String searchContent) {
+/* // 分页参数
+ Pageable pageable = new PageRequest(pageNumber, pageSize);
+
+ // Function Score Query
+ FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery()
+ .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("cityname", searchContent)),
+ ScoreFunctionBuilders.weightFactorFunction(1000))
+ .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("description", searchContent)),
+ ScoreFunctionBuilders.weightFactorFunction(100));
+
+ // 创建搜索 DSL 查询
+ SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withPageable(pageable)
+ .withQuery(functionScoreQueryBuilder).build();
+
+ logger.info("\n searchCity(): searchContent [" + searchContent + "] \n DSL = \n " + searchQuery.getQuery().toString());
+
+ Page searchPageResults = customerRepository.search(searchQuery);
+ return searchPageResults.getContent();
+ */
+ return null;
+ }
+}
diff --git a/2.x/spring-boot-elasticsearch/src/main/resources/application.properties b/2.x/spring-boot-elasticsearch/src/main/resources/application.properties
new file mode 100644
index 000000000..6b48fb388
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.data.elasticsearch.cluster-name=es-mongodb
+spring.data.elasticsearch.cluster-nodes=192.168.0.53:9300
\ No newline at end of file
diff --git a/2.x/spring-boot-elasticsearch/src/test/java/com/neo/ElasticsearchApplicationTests.java b/2.x/spring-boot-elasticsearch/src/test/java/com/neo/ElasticsearchApplicationTests.java
new file mode 100644
index 000000000..4a07e8e84
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/test/java/com/neo/ElasticsearchApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ElasticsearchApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("Spring Boot Test");
+ }
+
+}
diff --git a/2.x/spring-boot-elasticsearch/src/test/java/com/neo/repository/CustomerRepositoryTest.java b/2.x/spring-boot-elasticsearch/src/test/java/com/neo/repository/CustomerRepositoryTest.java
new file mode 100644
index 000000000..a9e3c4286
--- /dev/null
+++ b/2.x/spring-boot-elasticsearch/src/test/java/com/neo/repository/CustomerRepositoryTest.java
@@ -0,0 +1,135 @@
+package com.neo.repository;
+
+import com.neo.model.Customer;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.aggregations.Aggregation;
+import org.elasticsearch.search.aggregations.AggregationBuilders;
+import org.elasticsearch.search.aggregations.Aggregations;
+import org.elasticsearch.search.aggregations.metrics.sum.InternalSum;
+import org.elasticsearch.search.aggregations.metrics.sum.SumAggregationBuilder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
+import org.springframework.data.elasticsearch.core.ResultsExtractor;
+import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
+import org.springframework.data.elasticsearch.core.query.SearchQuery;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+import java.util.Map;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class CustomerRepositoryTest {
+ @Autowired
+ private CustomerRepository repository;
+ @Autowired
+ private ElasticsearchTemplate elasticsearchTemplate;
+
+ @Test
+ public void saveCustomers() {
+ repository.save(new Customer("Alice", "北京",13));
+ repository.save(new Customer("Bob", "北京",23));
+ repository.save(new Customer("neo", "西安",30));
+ repository.save(new Customer("summer", "烟台",22));
+ }
+
+ @Test
+ public void fetchAllCustomers() {
+ System.out.println("Customers found with findAll():");
+ System.out.println("-------------------------------");
+ Iterable iterable=repository.findAll();
+ for (Customer customer :iterable) {
+ System.out.println(customer);
+ }
+ }
+
+ @Test
+ public void deleteCustomers() {
+ repository.deleteAll();
+// repository.deleteByUserName("neo");
+ }
+
+ @Test
+ public void updateCustomers() {
+ Customer customer= repository.findByUserName("summer");
+ System.out.println(customer);
+ customer.setAddress("北京市海淀区西直门");
+ repository.save(customer);
+ Customer xcustomer=repository.findByUserName("summer");
+ System.out.println(xcustomer);
+ }
+
+ @Test
+ public void fetchIndividualCustomers() {
+ System.out.println("Customer found with findByUserName('summer'):");
+ System.out.println("--------------------------------");
+ System.out.println(repository.findByUserName("summer"));
+ System.out.println("--------------------------------");
+ System.out.println("Customers found with findByAddress(\"北京\"):");
+ String q="北京";
+ for (Customer customer : repository.findByAddress(q)) {
+ System.out.println(customer);
+ }
+ }
+
+ @Test
+ public void fetchPageCustomers() {
+ System.out.println("Customers found with fetchPageCustomers:");
+ System.out.println("-------------------------------");
+ Sort sort = new Sort(Sort.Direction.DESC, "address.keyword");
+ Pageable pageable = PageRequest.of(0, 10, sort);
+ Page customers=repository.findByAddress("北京", pageable);
+ System.out.println("Page customers "+customers.getContent().toString());
+ }
+
+ @Test
+ public void fetchPage2Customers() {
+ System.out.println("Customers found with fetchPageCustomers:");
+ System.out.println("-------------------------------");
+ QueryBuilder customerQuery = QueryBuilders.boolQuery()
+ .must(QueryBuilders.matchQuery("address", "北京"));
+ Page page = repository.search(customerQuery, PageRequest.of(0, 10));
+ System.out.println("Page customers "+page.getContent().toString());
+ page = repository.search(customerQuery, PageRequest.of(1, 10));
+ System.out.println("Page customers "+page.getContent().toString());
+ }
+
+ @Test
+ public void fetchAggregation() {
+ System.out.println("Customers found with fetchAggregation:");
+ System.out.println("-------------------------------");
+
+ QueryBuilder customerQuery = QueryBuilders.boolQuery()
+ .must(QueryBuilders.matchQuery("address", "北京"));
+
+ SumAggregationBuilder sumBuilder = AggregationBuilders.sum("sumAge").field("age");
+
+ SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(customerQuery)
+ .addAggregation(sumBuilder)
+ .build();
+
+ Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor() {
+ @Override
+ public Aggregations extract(SearchResponse response) {
+ return response.getAggregations();
+ }
+ });
+
+ //转换成map集合
+ Map aggregationMap = aggregations.asMap();
+ //获得对应的聚合函数的聚合子类,该聚合子类也是个map集合,里面的value就是桶Bucket,我们要获得Bucket
+ InternalSum sumAge = (InternalSum) aggregationMap.get("sumAge");
+ System.out.println("sum age is "+sumAge.getValue());
+ }
+
+}
diff --git a/2.x/spring-boot-fastDFS/pom.xml b/2.x/spring-boot-fastDFS/pom.xml
new file mode 100644
index 000000000..73c12c74e
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/pom.xml
@@ -0,0 +1,52 @@
+
+ 4.0.0
+
+ com.neo
+ spring-boot-fastDFS
+ jar
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.csource
+ fastdfs-client-java
+ 1.27-SNAPSHOT
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-fastDFS/src/main/java/com/neo/FastDFSApplication.java b/2.x/spring-boot-fastDFS/src/main/java/com/neo/FastDFSApplication.java
new file mode 100644
index 000000000..197c98205
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/java/com/neo/FastDFSApplication.java
@@ -0,0 +1,30 @@
+package com.neo;
+
+import org.apache.coyote.http11.AbstractHttp11Protocol;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication
+public class FastDFSApplication {
+
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(FastDFSApplication.class, args);
+ }
+
+ //Tomcat large file upload connection reset
+ @Bean
+ public TomcatServletWebServerFactory tomcatEmbedded() {
+ TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
+ tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
+ if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol>)) {
+ //-1 means unlimited
+ ((AbstractHttp11Protocol>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
+ }
+ });
+ return tomcat;
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-fastDFS/src/main/java/com/neo/controller/GlobalExceptionHandler.java b/2.x/spring-boot-fastDFS/src/main/java/com/neo/controller/GlobalExceptionHandler.java
new file mode 100644
index 000000000..fd6e17c23
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/java/com/neo/controller/GlobalExceptionHandler.java
@@ -0,0 +1,20 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.multipart.MultipartException;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+ //https://jira.spring.io/browse/SPR-14651
+ //4.3.5 supports RedirectAttributes redirectAttributes
+ @ExceptionHandler(MultipartException.class)
+ public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {
+
+ redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
+ return "redirect:/uploadStatus";
+
+ }
+}
diff --git a/2.x/spring-boot-fastDFS/src/main/java/com/neo/controller/UploadController.java b/2.x/spring-boot-fastDFS/src/main/java/com/neo/controller/UploadController.java
new file mode 100644
index 000000000..4dd3bf286
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/java/com/neo/controller/UploadController.java
@@ -0,0 +1,80 @@
+package com.neo.controller;
+
+import com.neo.fastdfs.FastDFSClient;
+import com.neo.fastdfs.FastDFSFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+@Controller
+public class UploadController {
+ private static Logger logger = LoggerFactory.getLogger(UploadController.class);
+
+ @GetMapping("/")
+ public String index() {
+ return "upload";
+ }
+
+ @PostMapping("/upload") //new annotation since 4.3
+ public String singleFileUpload(@RequestParam("file") MultipartFile file,
+ RedirectAttributes redirectAttributes) {
+ if (file.isEmpty()) {
+ redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
+ return "redirect:uploadStatus";
+ }
+ try {
+ // Get the file and save it somewhere
+ String path=saveFile(file);
+ redirectAttributes.addFlashAttribute("message",
+ "You successfully uploaded '" + file.getOriginalFilename() + "'");
+ redirectAttributes.addFlashAttribute("path",
+ "file path url '" + path + "'");
+ } catch (Exception e) {
+ logger.error("upload file failed",e);
+ }
+ return "redirect:/uploadStatus";
+ }
+
+ @GetMapping("/uploadStatus")
+ public String uploadStatus() {
+ return "uploadStatus";
+ }
+
+ /**
+ * @param multipartFile
+ * @return
+ * @throws IOException
+ */
+ public String saveFile(MultipartFile multipartFile) throws IOException {
+ String[] fileAbsolutePath={};
+ String fileName=multipartFile.getOriginalFilename();
+ String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
+ byte[] file_buff = null;
+ InputStream inputStream=multipartFile.getInputStream();
+ if(inputStream!=null){
+ int len1 = inputStream.available();
+ file_buff = new byte[len1];
+ inputStream.read(file_buff);
+ }
+ inputStream.close();
+ FastDFSFile file = new FastDFSFile(fileName, file_buff, ext);
+ try {
+ fileAbsolutePath = FastDFSClient.upload(file); //upload to fastdfs
+ } catch (Exception e) {
+ logger.error("upload file Exception!",e);
+ }
+ if (fileAbsolutePath==null) {
+ logger.error("upload file failed,please upload again!");
+ }
+ String path=FastDFSClient.getTrackerUrl()+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
+ return path;
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSClient.java b/2.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSClient.java
similarity index 100%
rename from spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSClient.java
rename to 2.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSClient.java
diff --git a/2.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSFile.java b/2.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSFile.java
new file mode 100644
index 000000000..adee175bc
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/java/com/neo/fastdfs/FastDFSFile.java
@@ -0,0 +1,70 @@
+package com.neo.fastdfs;
+
+public class FastDFSFile {
+ private String name;
+
+ private byte[] content;
+
+ private String ext;
+
+ private String md5;
+
+ private String author;
+
+ public FastDFSFile(String name, byte[] content, String ext, String height,
+ String width, String author) {
+ super();
+ this.name = name;
+ this.content = content;
+ this.ext = ext;
+ this.author = author;
+ }
+
+ public FastDFSFile(String name, byte[] content, String ext) {
+ super();
+ this.name = name;
+ this.content = content;
+ this.ext = ext;
+
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public byte[] getContent() {
+ return content;
+ }
+
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+
+ public String getExt() {
+ return ext;
+ }
+
+ public void setExt(String ext) {
+ this.ext = ext;
+ }
+
+ public String getMd5() {
+ return md5;
+ }
+
+ public void setMd5(String md5) {
+ this.md5 = md5;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-fastDFS/src/main/resources/application.properties b/2.x/spring-boot-fastDFS/src/main/resources/application.properties
new file mode 100644
index 000000000..cd48cf526
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+#http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
+#search multipart
+spring.servlet.http.multipart.max-file-size=10MB
+spring.servlet.http.multipart.max-request-size=10MB
+
diff --git a/2.x/spring-boot-fastDFS/src/main/resources/fdfs_client.conf b/2.x/spring-boot-fastDFS/src/main/resources/fdfs_client.conf
new file mode 100644
index 000000000..95cb59cc7
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/resources/fdfs_client.conf
@@ -0,0 +1,9 @@
+connect_timeout = 60
+network_timeout = 60
+charset = UTF-8
+http.tracker_http_port = 8080
+http.anti_steal_token = no
+http.secret_key = 123456
+
+tracker_server = 192.168.53.85:22122
+tracker_server = 192.168.53.86:22122
diff --git a/2.x/spring-boot-fastDFS/src/main/resources/logback.xml b/2.x/spring-boot-fastDFS/src/main/resources/logback.xml
new file mode 100644
index 000000000..0c0f833bc
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/resources/logback.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-fastDFS/src/main/resources/templates/upload.html b/2.x/spring-boot-fastDFS/src/main/resources/templates/upload.html
new file mode 100644
index 000000000..2e93a58dd
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/resources/templates/upload.html
@@ -0,0 +1,13 @@
+
+
+
+
+Spring Boot file upload example
+
+
+
+
+
diff --git a/2.x/spring-boot-fastDFS/src/main/resources/templates/uploadStatus.html b/2.x/spring-boot-fastDFS/src/main/resources/templates/uploadStatus.html
new file mode 100644
index 000000000..bcdab68f3
--- /dev/null
+++ b/2.x/spring-boot-fastDFS/src/main/resources/templates/uploadStatus.html
@@ -0,0 +1,16 @@
+
+
+
+
+Spring Boot - Upload Status
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-file-upload/pom.xml b/2.x/spring-boot-file-upload/pom.xml
new file mode 100644
index 000000000..af0bb9aae
--- /dev/null
+++ b/2.x/spring-boot-file-upload/pom.xml
@@ -0,0 +1,48 @@
+
+ 4.0.0
+
+ com.neo
+ spring-boot-file-upload
+ jar
+ 1.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java b/2.x/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java
new file mode 100644
index 000000000..059ae73fc
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java
@@ -0,0 +1,30 @@
+package com.neo;
+
+import org.apache.coyote.http11.AbstractHttp11Protocol;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication
+public class FileUploadWebApplication {
+
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(FileUploadWebApplication.class, args);
+ }
+
+ //Tomcat large file upload connection reset
+ @Bean
+ public TomcatServletWebServerFactory tomcatEmbedded() {
+ TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
+ tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
+ if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol>)) {
+ //-1 means unlimited
+ ((AbstractHttp11Protocol>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
+ }
+ });
+ return tomcat;
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java b/2.x/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java
new file mode 100644
index 000000000..8f5caf6cc
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java
@@ -0,0 +1,18 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.multipart.MultipartException;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+ //https://jira.spring.io/browse/SPR-14651
+ //4.3.5 supports RedirectAttributes redirectAttributes
+ @ExceptionHandler(MultipartException.class)
+ public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {
+ redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
+ return "redirect:/uploadStatus";
+ }
+}
diff --git a/2.x/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java b/2.x/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java
new file mode 100644
index 000000000..f72b2026a
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java
@@ -0,0 +1,58 @@
+package com.neo.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Controller
+public class UploadController {
+ //Save the uploaded file to this folder
+ private static String UPLOADED_FOLDER = "E://temp//";
+
+ @GetMapping("/")
+ public String index() {
+ return "upload";
+ }
+
+ @PostMapping("/upload") // //new annotation since 4.3
+ public String singleFileUpload(@RequestParam("file") MultipartFile file,
+ RedirectAttributes redirectAttributes) {
+ if (file.isEmpty()) {
+ redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
+ return "redirect:uploadStatus";
+ }
+
+ try {
+ // Get the file and save it somewhere
+ byte[] bytes = file.getBytes();
+ Path dir = Paths.get(UPLOADED_FOLDER);
+ Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
+ // Create parent dir if not exists
+ if(!Files.exists(dir)) {
+ Files.createDirectories(dir);
+ }
+ Files.write(path, bytes);
+ redirectAttributes.addFlashAttribute("message",
+ "You successfully uploaded '" + file.getOriginalFilename() + "'");
+
+ } catch (IOException e) {
+ redirectAttributes.addFlashAttribute("message", "Server throw IOException");
+ e.printStackTrace();
+ }
+ return "redirect:/uploadStatus";
+ }
+
+ @GetMapping("/uploadStatus")
+ public String uploadStatus() {
+ return "uploadStatus";
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-file-upload/src/main/resources/application.properties b/2.x/spring-boot-file-upload/src/main/resources/application.properties
new file mode 100644
index 000000000..61a7fd433
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+#http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
+#search multipart
+spring.servlet.multipart.max-file-size=10MB
+spring.servlet.multipart.max-request-size=10MB
\ No newline at end of file
diff --git a/2.x/spring-boot-file-upload/src/main/resources/logback.xml b/2.x/spring-boot-file-upload/src/main/resources/logback.xml
new file mode 100644
index 000000000..0c0f833bc
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/resources/logback.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-file-upload/src/main/resources/templates/from_file.html b/2.x/spring-boot-file-upload/src/main/resources/templates/from_file.html
new file mode 100644
index 000000000..3f95f35e1
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/resources/templates/from_file.html
@@ -0,0 +1,51 @@
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-file-upload/src/main/resources/templates/upload.html b/2.x/spring-boot-file-upload/src/main/resources/templates/upload.html
new file mode 100644
index 000000000..2e93a58dd
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/resources/templates/upload.html
@@ -0,0 +1,13 @@
+
+
+
+
+Spring Boot file upload example
+
+
+
+
+
diff --git a/2.x/spring-boot-file-upload/src/main/resources/templates/uploadStatus.html b/2.x/spring-boot-file-upload/src/main/resources/templates/uploadStatus.html
new file mode 100644
index 000000000..71fb76d3c
--- /dev/null
+++ b/2.x/spring-boot-file-upload/src/main/resources/templates/uploadStatus.html
@@ -0,0 +1,12 @@
+
+
+
+
+Spring Boot - Upload Status
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-hello/pom.xml b/2.x/spring-boot-hello/pom.xml
new file mode 100644
index 000000000..eba435698
--- /dev/null
+++ b/2.x/spring-boot-hello/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-hello
+ 1.0
+ jar
+
+ spring-boot-hello
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.RELEASE
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-hello/src/main/java/com/neo/HelloApplication.java b/2.x/spring-boot-hello/src/main/java/com/neo/HelloApplication.java
new file mode 100644
index 000000000..fc7cea256
--- /dev/null
+++ b/2.x/spring-boot-hello/src/main/java/com/neo/HelloApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class HelloApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(HelloApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-hello/src/main/java/com/neo/controller/HelloController.java b/2.x/spring-boot-hello/src/main/java/com/neo/controller/HelloController.java
new file mode 100644
index 000000000..2c1c06de1
--- /dev/null
+++ b/2.x/spring-boot-hello/src/main/java/com/neo/controller/HelloController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+
+ @RequestMapping("/")
+ public String index() {
+ return "Hello Spring Boot 2.0!";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-hello/src/main/resources/application.properties b/2.x/spring-boot-hello/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/2.x/spring-boot-hello/src/test/java/com/neo/HelloApplicationTests.java b/2.x/spring-boot-hello/src/test/java/com/neo/HelloApplicationTests.java
new file mode 100644
index 000000000..09ba4ff06
--- /dev/null
+++ b/2.x/spring-boot-hello/src/test/java/com/neo/HelloApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("Hello Spring Boot 2.0!");
+ }
+
+}
diff --git a/2.x/spring-boot-helloWorld/pom.xml b/2.x/spring-boot-helloWorld/pom.xml
new file mode 100644
index 000000000..460a54832
--- /dev/null
+++ b/2.x/spring-boot-helloWorld/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-helloworld
+ 1.0.0-SNAPSHOT
+ jar
+
+ spring-boot-helloworld
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.3.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-helloWorld/src/main/java/com/neo/Application.java b/2.x/spring-boot-helloWorld/src/main/java/com/neo/Application.java
new file mode 100644
index 000000000..6cda50c81
--- /dev/null
+++ b/2.x/spring-boot-helloWorld/src/main/java/com/neo/Application.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/2.x/spring-boot-helloWorld/src/main/java/com/neo/controller/HelloWorldController.java b/2.x/spring-boot-helloWorld/src/main/java/com/neo/controller/HelloWorldController.java
new file mode 100644
index 000000000..7d0256b4a
--- /dev/null
+++ b/2.x/spring-boot-helloWorld/src/main/java/com/neo/controller/HelloWorldController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloWorldController {
+
+ @RequestMapping("/hello")
+ public String index() {
+ return "Hello World";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-helloWorld/src/main/resources/application.properties b/2.x/spring-boot-helloWorld/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/2.x/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java b/2.x/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java
new file mode 100644
index 000000000..1faf3f2e7
--- /dev/null
+++ b/2.x/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello word");
+ }
+
+}
diff --git a/2.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java b/2.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java
new file mode 100644
index 000000000..d42211135
--- /dev/null
+++ b/2.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java
@@ -0,0 +1,39 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloTests {
+
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/2.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloWorldControlerTests.java
new file mode 100644
index 000000000..7abaf5818
--- /dev/null
+++ b/2.x/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloWorldControlerTests.java
@@ -0,0 +1,37 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloWorldControlerTests {
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/pom.xml b/2.x/spring-boot-jpa-thymeleaf-curd/pom.xml
new file mode 100644
index 000000000..a642bcec9
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+ spring-boot-jpa-thymeleaf-curd
+ spring-boot-jpa-thymeleaf-curd
+ spring-boot-jpa-thymeleaf-curd
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java
new file mode 100644
index 000000000..20dc3f130
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java
@@ -0,0 +1,20 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+
+@SpringBootApplication
+public class JpaThymeleafApplication extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(JpaThymeleafApplication.class);
+ }
+
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(JpaThymeleafApplication.class, args);
+ }
+}
+
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/model/User.java b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..4aa977176
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/model/User.java
@@ -0,0 +1,55 @@
+package com.neo.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class User {
+ @Id
+ @GeneratedValue
+ private long id;
+ @Column(nullable = false, unique = true)
+ private String userName;
+ @Column(nullable = false)
+ private String password;
+ @Column(nullable = false)
+ private int age;
+
+ public long getId() {
+ return id;
+ }
+
+ public User setId(long id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public User setUserName(String userName) {
+ this.userName = userName;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public User setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public User setAge(int age) {
+ this.age = age;
+ return this;
+ }
+}
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..f6a00c8c3
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,11 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserRepository extends JpaRepository {
+
+ User findById(long id);
+
+ void deleteById(Long id);
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java
new file mode 100644
index 000000000..ba82b95f2
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java
@@ -0,0 +1,20 @@
+package com.neo.service;
+
+import com.neo.model.User;
+
+import java.util.List;
+
+public interface UserService {
+
+ public List getUserList();
+
+ public User findUserById(long id);
+
+ public void save(User user);
+
+ public void edit(User user);
+
+ public void delete(long id);
+
+
+}
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java
new file mode 100644
index 000000000..a8a956174
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java
@@ -0,0 +1,43 @@
+package com.neo.service.impl;
+
+import com.neo.model.User;
+import com.neo.repository.UserRepository;
+import com.neo.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class UserServiceImpl implements UserService{
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Override
+ public List getUserList() {
+ return userRepository.findAll();
+ }
+
+ @Override
+ public User findUserById(long id) {
+ return userRepository.findById(id);
+ }
+
+ @Override
+ public void save(User user) {
+ userRepository.save(user);
+ }
+
+ @Override
+ public void edit(User user) {
+ userRepository.save(user);
+ }
+
+ @Override
+ public void delete(long id) {
+ userRepository.deleteById(id);
+ }
+}
+
+
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/HelloController.java b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..82136eb19
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,16 @@
+package com.neo.web;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@Controller
+public class HelloController {
+
+ @RequestMapping("/hello")
+ public String hello(Model model, @RequestParam(value="name", required=false, defaultValue="World") String name) {
+ model.addAttribute("name", name);
+ return "hello";
+ }
+}
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..b6992aac4
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,61 @@
+package com.neo.web;
+
+import com.neo.model.User;
+import com.neo.service.UserService;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Controller
+public class UserController {
+
+ @Resource
+ UserService userService;
+
+
+ @RequestMapping("/")
+ public String index() {
+ return "redirect:/list";
+ }
+
+ @RequestMapping("/list")
+ public String list(Model model) {
+ List users=userService.getUserList();
+ model.addAttribute("users", users);
+ return "user/list";
+ }
+
+ @RequestMapping("/toAdd")
+ public String toAdd() {
+ return "user/userAdd";
+ }
+
+ @RequestMapping("/add")
+ public String add(User user) {
+ userService.save(user);
+ return "redirect:/list";
+ }
+
+ @RequestMapping("/toEdit")
+ public String toEdit(Model model,Long id) {
+ User user=userService.findUserById(id);
+ model.addAttribute("user", user);
+ return "user/userEdit";
+ }
+
+ @RequestMapping("/edit")
+ public String edit(User user) {
+ userService.edit(user);
+ return "redirect:/list";
+ }
+
+
+ @RequestMapping("/delete")
+ public String delete(Long id) {
+ userService.delete(id);
+ return "redirect:/list";
+ }
+}
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties
new file mode 100644
index 000000000..59008fe5d
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties
@@ -0,0 +1,10 @@
+spring.datasource.url=jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.jpa.properties.hibernate.hbm2ddl.auto=create
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.show-sql= true
+
+spring.thymeleaf.cache=false
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/static/css/bootstrap.css b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/static/css/bootstrap.css
new file mode 100644
index 000000000..42c79d6e4
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/static/css/bootstrap.css
@@ -0,0 +1,6760 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+[hidden],
+template {
+ display: none;
+}
+a {
+ background-color: transparent;
+}
+a:active,
+a:hover {
+ outline: 0;
+}
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+b,
+strong {
+ font-weight: bold;
+}
+dfn {
+ font-style: italic;
+}
+h1 {
+ margin: .67em 0;
+ font-size: 2em;
+}
+mark {
+ color: #000;
+ background: #ff0;
+}
+small {
+ font-size: 80%;
+}
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+sup {
+ top: -.5em;
+}
+sub {
+ bottom: -.25em;
+}
+img {
+ border: 0;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 1em 40px;
+}
+hr {
+ height: 0;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+pre {
+ overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0;
+ font: inherit;
+ color: inherit;
+}
+button {
+ overflow: visible;
+}
+button,
+select {
+ text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+input {
+ line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
+}
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+fieldset {
+ padding: .35em .625em .75em;
+ margin: 0 2px;
+ border: 1px solid #c0c0c0;
+}
+legend {
+ padding: 0;
+ border: 0;
+}
+textarea {
+ overflow: auto;
+}
+optgroup {
+ font-weight: bold;
+}
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+td,
+th {
+ padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ }
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+ pre,
+ blockquote {
+ border: 1px solid #999;
+
+ page-break-inside: avoid;
+ }
+ thead {
+ display: table-header-group;
+ }
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+ img {
+ max-width: 100% !important;
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+ .navbar {
+ display: none;
+ }
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+ .label {
+ border: 1px solid #000;
+ }
+ .table {
+ border-collapse: collapse !important;
+ }
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+@font-face {
+ font-family: 'Glyphicons Halflings';
+
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.glyphicon-asterisk:before {
+ content: "\002a";
+}
+.glyphicon-plus:before {
+ content: "\002b";
+}
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+.glyphicon-minus:before {
+ content: "\2212";
+}
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+.glyphicon-glass:before {
+ content: "\e001";
+}
+.glyphicon-music:before {
+ content: "\e002";
+}
+.glyphicon-search:before {
+ content: "\e003";
+}
+.glyphicon-heart:before {
+ content: "\e005";
+}
+.glyphicon-star:before {
+ content: "\e006";
+}
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+.glyphicon-user:before {
+ content: "\e008";
+}
+.glyphicon-film:before {
+ content: "\e009";
+}
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+.glyphicon-th:before {
+ content: "\e011";
+}
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+.glyphicon-ok:before {
+ content: "\e013";
+}
+.glyphicon-remove:before {
+ content: "\e014";
+}
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+.glyphicon-off:before {
+ content: "\e017";
+}
+.glyphicon-signal:before {
+ content: "\e018";
+}
+.glyphicon-cog:before {
+ content: "\e019";
+}
+.glyphicon-trash:before {
+ content: "\e020";
+}
+.glyphicon-home:before {
+ content: "\e021";
+}
+.glyphicon-file:before {
+ content: "\e022";
+}
+.glyphicon-time:before {
+ content: "\e023";
+}
+.glyphicon-road:before {
+ content: "\e024";
+}
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+.glyphicon-download:before {
+ content: "\e026";
+}
+.glyphicon-upload:before {
+ content: "\e027";
+}
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+.glyphicon-lock:before {
+ content: "\e033";
+}
+.glyphicon-flag:before {
+ content: "\e034";
+}
+.glyphicon-headphones:before {
+ content: "\e035";
+}
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+.glyphicon-tag:before {
+ content: "\e041";
+}
+.glyphicon-tags:before {
+ content: "\e042";
+}
+.glyphicon-book:before {
+ content: "\e043";
+}
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+.glyphicon-print:before {
+ content: "\e045";
+}
+.glyphicon-camera:before {
+ content: "\e046";
+}
+.glyphicon-font:before {
+ content: "\e047";
+}
+.glyphicon-bold:before {
+ content: "\e048";
+}
+.glyphicon-italic:before {
+ content: "\e049";
+}
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+.glyphicon-list:before {
+ content: "\e056";
+}
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+.glyphicon-picture:before {
+ content: "\e060";
+}
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+.glyphicon-tint:before {
+ content: "\e064";
+}
+.glyphicon-edit:before {
+ content: "\e065";
+}
+.glyphicon-share:before {
+ content: "\e066";
+}
+.glyphicon-check:before {
+ content: "\e067";
+}
+.glyphicon-move:before {
+ content: "\e068";
+}
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+.glyphicon-backward:before {
+ content: "\e071";
+}
+.glyphicon-play:before {
+ content: "\e072";
+}
+.glyphicon-pause:before {
+ content: "\e073";
+}
+.glyphicon-stop:before {
+ content: "\e074";
+}
+.glyphicon-forward:before {
+ content: "\e075";
+}
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+.glyphicon-eject:before {
+ content: "\e078";
+}
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+.glyphicon-gift:before {
+ content: "\e102";
+}
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+.glyphicon-fire:before {
+ content: "\e104";
+}
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+.glyphicon-plane:before {
+ content: "\e108";
+}
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+.glyphicon-random:before {
+ content: "\e110";
+}
+.glyphicon-comment:before {
+ content: "\e111";
+}
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+.glyphicon-bell:before {
+ content: "\e123";
+}
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+.glyphicon-globe:before {
+ content: "\e135";
+}
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+.glyphicon-filter:before {
+ content: "\e138";
+}
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+.glyphicon-link:before {
+ content: "\e144";
+}
+.glyphicon-phone:before {
+ content: "\e145";
+}
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+.glyphicon-usd:before {
+ content: "\e148";
+}
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+.glyphicon-sort:before {
+ content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+.glyphicon-expand:before {
+ content: "\e158";
+}
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+.glyphicon-flash:before {
+ content: "\e162";
+}
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+.glyphicon-record:before {
+ content: "\e165";
+}
+.glyphicon-save:before {
+ content: "\e166";
+}
+.glyphicon-open:before {
+ content: "\e167";
+}
+.glyphicon-saved:before {
+ content: "\e168";
+}
+.glyphicon-import:before {
+ content: "\e169";
+}
+.glyphicon-export:before {
+ content: "\e170";
+}
+.glyphicon-send:before {
+ content: "\e171";
+}
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+.glyphicon-header:before {
+ content: "\e180";
+}
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+.glyphicon-tower:before {
+ content: "\e184";
+}
+.glyphicon-stats:before {
+ content: "\e185";
+}
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+.glyphicon-cd:before {
+ content: "\e201";
+}
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+.glyphicon-copy:before {
+ content: "\e205";
+}
+.glyphicon-paste:before {
+ content: "\e206";
+}
+.glyphicon-alert:before {
+ content: "\e209";
+}
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+.glyphicon-king:before {
+ content: "\e211";
+}
+.glyphicon-queen:before {
+ content: "\e212";
+}
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+.glyphicon-knight:before {
+ content: "\e215";
+}
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+.glyphicon-bed:before {
+ content: "\e219";
+}
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+.glyphicon-erase:before {
+ content: "\e221";
+}
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+.glyphicon-btc:before {
+ content: "\e227";
+}
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+.glyphicon-scale:before {
+ content: "\e230";
+}
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+.glyphicon-education:before {
+ content: "\e233";
+}
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+.glyphicon-oil:before {
+ content: "\e238";
+}
+.glyphicon-grain:before {
+ content: "\e239";
+}
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+.glyphicon-console:before {
+ content: "\e254";
+}
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html {
+ font-size: 10px;
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #333;
+ background-color: #fff;
+}
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+a {
+ color: #337ab7;
+ text-decoration: none;
+}
+a:hover,
+a:focus {
+ color: #23527c;
+ text-decoration: underline;
+}
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+figure {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+.img-rounded {
+ border-radius: 6px;
+}
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
+}
+.img-circle {
+ border-radius: 50%;
+}
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eee;
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+[role="button"] {
+ cursor: pointer;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #777;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+h1,
+.h1 {
+ font-size: 36px;
+}
+h2,
+.h2 {
+ font-size: 30px;
+}
+h3,
+.h3 {
+ font-size: 24px;
+}
+h4,
+.h4 {
+ font-size: 18px;
+}
+h5,
+.h5 {
+ font-size: 14px;
+}
+h6,
+.h6 {
+ font-size: 12px;
+}
+p {
+ margin: 0 0 10px;
+}
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+small,
+.small {
+ font-size: 85%;
+}
+mark,
+.mark {
+ padding: .2em;
+ background-color: #fcf8e3;
+}
+.text-left {
+ text-align: left;
+}
+.text-right {
+ text-align: right;
+}
+.text-center {
+ text-align: center;
+}
+.text-justify {
+ text-align: justify;
+}
+.text-nowrap {
+ white-space: nowrap;
+}
+.text-lowercase {
+ text-transform: lowercase;
+}
+.text-uppercase {
+ text-transform: uppercase;
+}
+.text-capitalize {
+ text-transform: capitalize;
+}
+.text-muted {
+ color: #777;
+}
+.text-primary {
+ color: #337ab7;
+}
+a.text-primary:hover,
+a.text-primary:focus {
+ color: #286090;
+}
+.text-success {
+ color: #3c763d;
+}
+a.text-success:hover,
+a.text-success:focus {
+ color: #2b542c;
+}
+.text-info {
+ color: #31708f;
+}
+a.text-info:hover,
+a.text-info:focus {
+ color: #245269;
+}
+.text-warning {
+ color: #8a6d3b;
+}
+a.text-warning:hover,
+a.text-warning:focus {
+ color: #66512c;
+}
+.text-danger {
+ color: #a94442;
+}
+a.text-danger:hover,
+a.text-danger:focus {
+ color: #843534;
+}
+.bg-primary {
+ color: #fff;
+ background-color: #337ab7;
+}
+a.bg-primary:hover,
+a.bg-primary:focus {
+ background-color: #286090;
+}
+.bg-success {
+ background-color: #dff0d8;
+}
+a.bg-success:hover,
+a.bg-success:focus {
+ background-color: #c1e2b3;
+}
+.bg-info {
+ background-color: #d9edf7;
+}
+a.bg-info:hover,
+a.bg-info:focus {
+ background-color: #afd9ee;
+}
+.bg-warning {
+ background-color: #fcf8e3;
+}
+a.bg-warning:hover,
+a.bg-warning:focus {
+ background-color: #f7ecb5;
+}
+.bg-danger {
+ background-color: #f2dede;
+}
+a.bg-danger:hover,
+a.bg-danger:focus {
+ background-color: #e4b9b9;
+}
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #eee;
+}
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none;
+}
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
+}
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+dt,
+dd {
+ line-height: 1.42857143;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #777;
+}
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #eee;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #777;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #eee;
+ border-left: 0;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 4px;
+}
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #333;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+}
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #333;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+.row {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+.col-xs-12 {
+ width: 100%;
+}
+.col-xs-11 {
+ width: 91.66666667%;
+}
+.col-xs-10 {
+ width: 83.33333333%;
+}
+.col-xs-9 {
+ width: 75%;
+}
+.col-xs-8 {
+ width: 66.66666667%;
+}
+.col-xs-7 {
+ width: 58.33333333%;
+}
+.col-xs-6 {
+ width: 50%;
+}
+.col-xs-5 {
+ width: 41.66666667%;
+}
+.col-xs-4 {
+ width: 33.33333333%;
+}
+.col-xs-3 {
+ width: 25%;
+}
+.col-xs-2 {
+ width: 16.66666667%;
+}
+.col-xs-1 {
+ width: 8.33333333%;
+}
+.col-xs-pull-12 {
+ right: 100%;
+}
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+.col-xs-pull-9 {
+ right: 75%;
+}
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+.col-xs-pull-6 {
+ right: 50%;
+}
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+.col-xs-pull-3 {
+ right: 25%;
+}
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+.col-xs-pull-0 {
+ right: auto;
+}
+.col-xs-push-12 {
+ left: 100%;
+}
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+.col-xs-push-9 {
+ left: 75%;
+}
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+.col-xs-push-6 {
+ left: 50%;
+}
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+.col-xs-push-3 {
+ left: 25%;
+}
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+.col-xs-push-0 {
+ left: auto;
+}
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+ .col-sm-3 {
+ width: 25%;
+ }
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-sm-pull-0 {
+ right: auto;
+ }
+ .col-sm-push-12 {
+ left: 100%;
+ }
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+ .col-sm-push-9 {
+ left: 75%;
+ }
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+ .col-sm-push-6 {
+ left: 50%;
+ }
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+ .col-sm-push-3 {
+ left: 25%;
+ }
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+ .col-sm-push-0 {
+ left: auto;
+ }
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-sm-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+ .col-md-pull-12 {
+ right: 100%;
+ }
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-md-pull-9 {
+ right: 75%;
+ }
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-md-pull-6 {
+ right: 50%;
+ }
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-md-pull-3 {
+ right: 25%;
+ }
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-md-pull-0 {
+ right: auto;
+ }
+ .col-md-push-12 {
+ left: 100%;
+ }
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+ .col-md-push-9 {
+ left: 75%;
+ }
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+ .col-md-push-6 {
+ left: 50%;
+ }
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+ .col-md-push-3 {
+ left: 25%;
+ }
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+ .col-md-push-0 {
+ left: auto;
+ }
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-md-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+ .col-lg-9 {
+ width: 75%;
+ }
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-lg-pull-0 {
+ right: auto;
+ }
+ .col-lg-push-12 {
+ left: 100%;
+ }
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+ .col-lg-push-9 {
+ left: 75%;
+ }
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+ .col-lg-push-6 {
+ left: 50%;
+ }
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+ .col-lg-push-3 {
+ left: 25%;
+ }
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+ .col-lg-push-0 {
+ left: auto;
+ }
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-lg-offset-0 {
+ margin-left: 0;
+ }
+}
+table {
+ background-color: transparent;
+}
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #777;
+ text-align: left;
+}
+th {
+ text-align: left;
+}
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #ddd;
+}
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #ddd;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+.table > tbody + tbody {
+ border-top: 2px solid #ddd;
+}
+.table .table {
+ background-color: #fff;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+.table-bordered {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #ddd;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+ position: static;
+ display: table-column;
+ float: none;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ display: table-cell;
+ float: none;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
+}
+.table-responsive {
+ min-height: .01%;
+ overflow-x: auto;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #ddd;
+ }
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: bold;
+}
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+input[type="file"] {
+ display: block;
+}
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+select[multiple],
+select[size] {
+ height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #555;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+}
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+ color: #999;
+}
+.form-control::-webkit-input-placeholder {
+ color: #999;
+}
+.form-control::-ms-expand {
+ background-color: transparent;
+ border: 0;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #eee;
+ opacity: 1;
+}
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+textarea.form-control {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: none;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"].form-control,
+ input[type="time"].form-control,
+ input[type="datetime-local"].form-control,
+ input[type="month"].form-control {
+ line-height: 34px;
+ }
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 46px;
+ }
+}
+.form-group {
+ margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ vertical-align: middle;
+ cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+.form-control-static {
+ min-height: 34px;
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.form-group-sm select.form-control {
+ height: 30px;
+ line-height: 30px;
+}
+.form-group-sm textarea.form-control,
+.form-group-sm select[multiple].form-control {
+ height: auto;
+}
+.form-group-sm .form-control-static {
+ height: 30px;
+ min-height: 32px;
+ padding: 6px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+.form-group-lg select.form-control {
+ height: 46px;
+ line-height: 46px;
+}
+.form-group-lg textarea.form-control,
+.form-group-lg select[multiple].form-control {
+ height: auto;
+}
+.form-group-lg .form-control-static {
+ height: 46px;
+ min-height: 38px;
+ padding: 11px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.has-feedback {
+ position: relative;
+}
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #3c763d;
+}
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d;
+}
+.has-success .form-control-feedback {
+ color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #8a6d3b;
+}
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #8a6d3b;
+}
+.has-warning .form-control-feedback {
+ color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #a94442;
+}
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+.has-error .form-control-feedback {
+ color: #a94442;
+}
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #737373;
+}
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
+ }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 11px;
+ font-size: 18px;
+ }
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ font-size: 12px;
+ }
+}
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #333;
+ text-decoration: none;
+}
+.btn:active,
+.btn.active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+.btn-default {
+ color: #333;
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+.btn-default:hover {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #333;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+ color: #333;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default .badge {
+ color: #fff;
+ background-color: #333;
+}
+.btn-primary {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+ color: #fff;
+ background-color: #286090;
+ border-color: #122b40;
+}
+.btn-primary:hover {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #286090;
+ border-color: #204d74;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+ color: #fff;
+ background-color: #204d74;
+ border-color: #122b40;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+ background-color: #337ab7;
+ border-color: #2e6da4;
+}
+.btn-primary .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+.btn-success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+.btn-info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+.btn-warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+.btn-danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+.btn-link {
+ font-weight: normal;
+ color: #337ab7;
+ border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+ color: #23527c;
+ text-decoration: underline;
+ background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #777;
+ text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+.btn-block {
+ display: block;
+ width: 100%;
+}
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
+}
+.fade.in {
+ opacity: 1;
+}
+.collapse {
+ display: none;
+}
+.collapse.in {
+ display: block;
+}
+tr.collapse.in {
+ display: table-row;
+}
+tbody.collapse.in {
+ display: table-row-group;
+}
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility;
+}
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-top: 4px solid \9;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+.dropup,
+.dropdown {
+ position: relative;
+}
+.dropdown-toggle:focus {
+ outline: 0;
+}
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ font-size: 14px;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #333;
+ white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ color: #262626;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #fff;
+ text-decoration: none;
+ background-color: #337ab7;
+ outline: 0;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #777;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
+.open > .dropdown-menu {
+ display: block;
+}
+.open > a {
+ outline: 0;
+}
+.dropdown-menu-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #777;
+ white-space: nowrap;
+}
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990;
+}
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: 4px dashed;
+ border-bottom: 4px solid \9;
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto;
+ }
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0;
+ }
+}
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+.btn-toolbar {
+ margin-left: -5px;
+}
+.btn-toolbar .btn,
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px;
+}
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn .caret {
+ margin-left: 0;
+}
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+.input-group[class*="col-"] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+.input-group .form-control:focus {
+ z-index: 3;
+}
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 6px;
+}
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
+}
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #555;
+ text-align: center;
+ background-color: #eee;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 3px;
+}
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 6px;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group-addon:first-child {
+ border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.input-group-addon:last-child {
+ border-left: 0;
+}
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+.input-group-btn > .btn {
+ position: relative;
+}
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ z-index: 2;
+ margin-left: -1px;
+}
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+.nav > li {
+ position: relative;
+ display: block;
+}
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.nav > li.disabled > a {
+ color: #777;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #777;
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #eee;
+ border-color: #337ab7;
+}
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.nav > li > a > img {
+ max-width: none;
+}
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 4px 4px 0 0;
+}
+.nav-tabs > li > a:hover {
+ border-color: #eee #eee #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #555;
+ cursor: default;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+.nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.nav-pills > li {
+ float: left;
+}
+.nav-pills > li > a {
+ border-radius: 4px;
+}
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #fff;
+ background-color: #337ab7;
+}
+.nav-stacked > li {
+ float: none;
+}
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+.nav-justified {
+ width: 100%;
+}
+.nav-justified > li {
+ float: none;
+}
+.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 4px;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 4px 4px 0 0;
+ }
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #fff;
+ }
+}
+.tab-content > .tab-pane {
+ display: none;
+}
+.tab-content > .active {
+ display: block;
+}
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar {
+ position: relative;
+ min-height: 50px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+}
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 4px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+.navbar-collapse {
+ padding-right: 15px;
+ padding-left: 15px;
+ overflow-x: visible;
+ -webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+}
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+.navbar-brand {
+ float: left;
+ height: 50px;
+ padding: 15px 15px;
+ font-size: 18px;
+ line-height: 20px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+.navbar-brand > img {
+ display: block;
+}
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-top: 8px;
+ margin-right: 15px;
+ margin-bottom: 8px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.navbar-toggle:focus {
+ outline: 0;
+}
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+.navbar-nav {
+ margin: 7.5px -15px;
+}
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+ .navbar-nav > li {
+ float: left;
+ }
+ .navbar-nav > li > a {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ }
+}
+.navbar-form {
+ padding: 10px 15px;
+ margin-top: 8px;
+ margin-right: -15px;
+ margin-bottom: 8px;
+ margin-left: -15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+}
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.navbar-btn {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+.navbar-btn.btn-sm {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.navbar-btn.btn-xs {
+ margin-top: 14px;
+ margin-bottom: 14px;
+}
+.navbar-text {
+ margin-top: 15px;
+ margin-bottom: 15px;
+}
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+.navbar-default {
+ background-color: #f8f8f8;
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-brand {
+ color: #777;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #5e5e5e;
+ background-color: transparent;
+}
+.navbar-default .navbar-text {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a {
+ color: #777;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #333;
+ background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+ border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #e7e7e7;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+}
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #777;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #333;
+ background-color: transparent;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #555;
+ background-color: #e7e7e7;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+}
+.navbar-default .navbar-link {
+ color: #777;
+}
+.navbar-default .navbar-link:hover {
+ color: #333;
+}
+.navbar-default .btn-link {
+ color: #777;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #333;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+ border-color: #333;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #333;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #9d9d9d;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+ }
+}
+.navbar-inverse .navbar-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .navbar-link:hover {
+ color: #fff;
+}
+.navbar-inverse .btn-link {
+ color: #9d9d9d;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+}
+.breadcrumb > li {
+ display: inline-block;
+}
+.breadcrumb > li + li:before {
+ padding: 0 5px;
+ color: #ccc;
+ content: "/\00a0";
+}
+.breadcrumb > .active {
+ color: #777;
+}
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 4px;
+}
+.pagination > li {
+ display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ margin-left: -1px;
+ line-height: 1.42857143;
+ color: #337ab7;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ z-index: 2;
+ color: #23527c;
+ background-color: #eee;
+ border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 3;
+ color: #fff;
+ cursor: default;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-top-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+}
+.pager li {
+ display: inline;
+}
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #eee;
+}
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #fff;
+}
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.label:empty {
+ display: none;
+}
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+.label-default {
+ background-color: #777;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #5e5e5e;
+}
+.label-primary {
+ background-color: #337ab7;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #286090;
+}
+.label-success {
+ background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+.label-info {
+ background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+.label-warning {
+ background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+.label-danger {
+ background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #777;
+ border-radius: 10px;
+}
+.badge:empty {
+ display: none;
+}
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.list-group-item > .badge {
+ float: right;
+}
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+.jumbotron {
+ padding-top: 30px;
+ padding-bottom: 30px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #eee;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+.jumbotron > hr {
+ border-top-color: #d5d5d5;
+}
+.container .jumbotron,
+.container-fluid .jumbotron {
+ padding-right: 15px;
+ padding-left: 15px;
+ border-radius: 6px;
+}
+.jumbotron .container {
+ max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding-top: 48px;
+ padding-bottom: 48px;
+ }
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-right: 60px;
+ padding-left: 60px;
+ }
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+ margin-right: auto;
+ margin-left: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #337ab7;
+}
+.thumbnail .caption {
+ padding: 9px;
+ color: #333;
+}
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 4px;
+}
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+.alert .alert-link {
+ font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+.alert > p + p {
+ margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+.alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.alert-success hr {
+ border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+ color: #2b542c;
+}
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.alert-info hr {
+ border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+ color: #245269;
+}
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.alert-warning hr {
+ border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+ color: #66512c;
+}
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.alert-danger hr {
+ border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+ color: #843534;
+}
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f5f5f5;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+.progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #337ab7;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.media {
+ margin-top: 15px;
+}
+.media:first-child {
+ margin-top: 0;
+}
+.media,
+.media-body {
+ overflow: hidden;
+ zoom: 1;
+}
+.media-body {
+ width: 10000px;
+}
+.media-object {
+ display: block;
+}
+.media-object.img-thumbnail {
+ max-width: none;
+}
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+.media-middle {
+ vertical-align: middle;
+}
+.media-bottom {
+ vertical-align: bottom;
+}
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+.list-group {
+ padding-left: 0;
+ margin-bottom: 20px;
+}
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.list-group-item:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+a.list-group-item,
+button.list-group-item {
+ color: #555;
+}
+a.list-group-item .list-group-item-heading,
+button.list-group-item .list-group-item-heading {
+ color: #333;
+}
+a.list-group-item:hover,
+button.list-group-item:hover,
+a.list-group-item:focus,
+button.list-group-item:focus {
+ color: #555;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+button.list-group-item {
+ width: 100%;
+ text-align: left;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ color: #777;
+ cursor: not-allowed;
+ background-color: #eee;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #777;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #c7ddef;
+}
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+}
+a.list-group-item-success,
+button.list-group-item-success {
+ color: #3c763d;
+}
+a.list-group-item-success .list-group-item-heading,
+button.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-success:hover,
+button.list-group-item-success:hover,
+a.list-group-item-success:focus,
+button.list-group-item-success:focus {
+ color: #3c763d;
+ background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+button.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+button.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus,
+button.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d;
+}
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7;
+}
+a.list-group-item-info,
+button.list-group-item-info {
+ color: #31708f;
+}
+a.list-group-item-info .list-group-item-heading,
+button.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-info:hover,
+button.list-group-item-info:hover,
+a.list-group-item-info:focus,
+button.list-group-item-info:focus {
+ color: #31708f;
+ background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+button.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+button.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus,
+button.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f;
+}
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+a.list-group-item-warning,
+button.list-group-item-warning {
+ color: #8a6d3b;
+}
+a.list-group-item-warning .list-group-item-heading,
+button.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-warning:hover,
+button.list-group-item-warning:hover,
+a.list-group-item-warning:focus,
+button.list-group-item-warning:focus {
+ color: #8a6d3b;
+ background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+button.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+button.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus,
+button.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b;
+}
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede;
+}
+a.list-group-item-danger,
+button.list-group-item-danger {
+ color: #a94442;
+}
+a.list-group-item-danger .list-group-item-heading,
+button.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-danger:hover,
+button.list-group-item-danger:hover,
+a.list-group-item-danger:focus,
+button.list-group-item-danger:focus {
+ color: #a94442;
+ background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+button.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+button.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus,
+button.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442;
+}
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+.panel-body {
+ padding: 15px;
+}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: 3px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: 3px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-right-radius: 3px;
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: 3px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: 3px;
+}
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #ddd;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+.panel > .table-responsive {
+ margin-bottom: 0;
+ border: 0;
+}
+.panel-group {
+ margin-bottom: 20px;
+}
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 4px;
+}
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #ddd;
+}
+.panel-group .panel-footer {
+ border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd;
+}
+.panel-default {
+ border-color: #ddd;
+}
+.panel-default > .panel-heading {
+ color: #333;
+ background-color: #f5f5f5;
+ border-color: #ddd;
+}
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd;
+}
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #333;
+}
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd;
+}
+.panel-primary {
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #337ab7;
+ border-color: #337ab7;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #337ab7;
+}
+.panel-primary > .panel-heading .badge {
+ color: #337ab7;
+ background-color: #fff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #337ab7;
+}
+.panel-success {
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6;
+}
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d;
+}
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6;
+}
+.panel-info {
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1;
+}
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f;
+}
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1;
+}
+.panel-warning {
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc;
+}
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b;
+}
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc;
+}
+.panel-danger {
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1;
+}
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442;
+}
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1;
+}
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+}
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+}
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15);
+}
+.well-lg {
+ padding: 24px;
+ border-radius: 6px;
+}
+.well-sm {
+ padding: 9px;
+ border-radius: 3px;
+}
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ filter: alpha(opacity=20);
+ opacity: .2;
+}
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+button.close {
+ -webkit-appearance: none;
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+}
+.modal-open {
+ overflow: hidden;
+}
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+}
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+}
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000;
+}
+.modal-backdrop.fade {
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+.modal-backdrop.in {
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+ margin-top: -2px;
+}
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ }
+ .modal-sm {
+ width: 300px;
+ }
+}
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ filter: alpha(opacity=0);
+ opacity: 0;
+
+ line-break: auto;
+}
+.tooltip.in {
+ filter: alpha(opacity=90);
+ opacity: .9;
+}
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px;
+}
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px;
+}
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px;
+}
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px;
+}
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 4px;
+}
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-left .tooltip-arrow {
+ right: 5px;
+ bottom: 0;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000;
+}
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000;
+}
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+
+ line-break: auto;
+}
+.popover.top {
+ margin-top: -10px;
+}
+.popover.right {
+ margin-left: 10px;
+}
+.popover.bottom {
+ margin-top: 10px;
+}
+.popover.left {
+ margin-left: -10px;
+}
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: 5px 5px 0 0;
+}
+.popover-content {
+ padding: 9px 14px;
+}
+.popover > .arrow,
+.popover > .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+.popover > .arrow {
+ border-width: 11px;
+}
+.popover > .arrow:after {
+ content: "";
+ border-width: 10px;
+}
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
+ border-bottom-width: 0;
+}
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
+ border-bottom-width: 0;
+}
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
+ border-left-width: 0;
+}
+.popover.right > .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
+ border-left-width: 0;
+}
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25);
+}
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: #fff;
+}
+.popover.left > .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-right-width: 0;
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, .25);
+}
+.popover.left > .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff;
+}
+.carousel {
+ position: relative;
+}
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000px;
+ perspective: 1000px;
+ }
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+.carousel-inner > .active {
+ left: 0;
+}
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+.carousel-inner > .next {
+ left: 100%;
+}
+.carousel-inner > .prev {
+ left: -100%;
+}
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+.carousel-inner > .active.left {
+ left: -100%;
+}
+.carousel-inner > .active.right {
+ left: 100%;
+}
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 15%;
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+ background-color: rgba(0, 0, 0, 0);
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control.right {
+ right: 0;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control:hover,
+.carousel-control:focus {
+ color: #fff;
+ text-decoration: none;
+ filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+ margin-top: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ font-family: serif;
+ line-height: 1;
+}
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none;
+}
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px;
+}
+.carousel-indicators .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: #fff;
+}
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+}
+.carousel-caption .btn {
+ text-shadow: none;
+}
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -10px;
+ font-size: 30px;
+ }
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -10px;
+ }
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -10px;
+ }
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px;
+ }
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-header:before,
+.modal-header:after,
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ content: " ";
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-header:after,
+.modal-footer:after {
+ clear: both;
+}
+.center-block {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.hidden {
+ display: none !important;
+}
+.affix {
+ position: fixed;
+}
+@-ms-viewport {
+ width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+ table.visible-xs {
+ display: table !important;
+ }
+ tr.visible-xs {
+ display: table-row !important;
+ }
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+ table.visible-sm {
+ display: table !important;
+ }
+ tr.visible-sm {
+ display: table-row !important;
+ }
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+ table.visible-md {
+ display: table !important;
+ }
+ tr.visible-md {
+ display: table-row !important;
+ }
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+ table.visible-lg {
+ display: table !important;
+ }
+ tr.visible-lg {
+ display: table-row !important;
+ }
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+.visible-print {
+ display: none !important;
+}
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+ table.visible-print {
+ display: table !important;
+ }
+ tr.visible-print {
+ display: table-row !important;
+ }
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+.visible-print-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/hello.html b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/hello.html
new file mode 100644
index 000000000..bd1f7817e
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/hello.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Hello Thymeleaf!
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/list.html b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/list.html
new file mode 100644
index 000000000..4126a3de1
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/list.html
@@ -0,0 +1,43 @@
+
+
+
+
+ userList
+
+
+
+
+用户列表
+
+
+
+
+
+ | # |
+ User Name |
+ Password |
+ Age |
+ Edit |
+ Delete |
+
+
+
+
+ | 1 |
+ neo |
+ Otto |
+ 6 |
+ edit |
+ delete |
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userAdd.html b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userAdd.html
new file mode 100644
index 000000000..0fa93c38a
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userAdd.html
@@ -0,0 +1,43 @@
+
+
+
+
+ user
+
+
+
+
+添加用户
+
+
+
+
diff --git a/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userEdit.html b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userEdit.html
new file mode 100644
index 000000000..b312daa37
--- /dev/null
+++ b/2.x/spring-boot-jpa-thymeleaf-curd/src/main/resources/templates/user/userEdit.html
@@ -0,0 +1,44 @@
+
+
+
+
+ user
+
+
+
+
+修改用户
+
+
+
+
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/pom.xml b/2.x/spring-boot-jpa/spring-boot-jpa/pom.xml
new file mode 100644
index 000000000..b42ead5ee
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-Jpa
+ 1.0.0
+ jar
+
+ spring-boot-Jpa
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/JpaApplication.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/JpaApplication.java
new file mode 100644
index 000000000..a1b5532be
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/JpaApplication.java
@@ -0,0 +1,13 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+
+@SpringBootApplication
+public class JpaApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(JpaApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/Address.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/Address.java
new file mode 100644
index 000000000..883ea20c6
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/Address.java
@@ -0,0 +1,59 @@
+package com.neo.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class Address {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false)
+ private Long userId;
+ private String province;
+ private String city;
+ private String street;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public String getProvince() {
+ return province;
+ }
+
+ public void setProvince(String province) {
+ this.province = province;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/User.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..7ec1e8bad
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/User.java
@@ -0,0 +1,87 @@
+package com.neo.model;
+
+
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import java.io.Serializable;
+
+@Entity
+public class User {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false, unique = true)
+ private String userName;
+ @Column(nullable = false)
+ private String passWord;
+ @Column(nullable = false, unique = true)
+ private String email;
+ @Column(nullable = true, unique = true)
+ private String nickName;
+ @Column(nullable = false)
+ private String regTime;
+
+ public User() {
+ }
+
+ public User(String userName, String passWord, String email, String nickName, String regTime) {
+ this.userName = userName;
+ this.passWord = passWord;
+ this.email = email;
+ this.nickName = nickName;
+ this.regTime = regTime;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public String getRegTime() {
+ return regTime;
+ }
+
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserDetail.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserDetail.java
new file mode 100644
index 000000000..4f3c67da8
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserDetail.java
@@ -0,0 +1,102 @@
+package com.neo.model;
+
+
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+public class UserDetail {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false, unique = true)
+ private Long userId;
+ private Integer age;
+ private String realName;
+ private String status;
+ private String hobby;
+ private String introduction;
+ private String lastLoginIp;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getRealName() {
+ return realName;
+ }
+
+ public void setRealName(String realName) {
+ this.realName = realName;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getHobby() {
+ return hobby;
+ }
+
+ public void setHobby(String hobby) {
+ this.hobby = hobby;
+ }
+
+ public String getIntroduction() {
+ return introduction;
+ }
+
+ public void setIntroduction(String introduction) {
+ this.introduction = introduction;
+ }
+
+ public String getLastLoginIp() {
+ return lastLoginIp;
+ }
+
+ public void setLastLoginIp(String lastLoginIp) {
+ this.lastLoginIp = lastLoginIp;
+ }
+
+ @Override
+ public String toString() {
+ return "UserDetail{" +
+ "id=" + id +
+ ", userId=" + userId +
+ ", age=" + age +
+ ", realName='" + realName + '\'' +
+ ", status='" + status + '\'' +
+ ", hobby='" + hobby + '\'' +
+ ", introduction='" + introduction + '\'' +
+ ", lastLoginIp='" + lastLoginIp + '\'' +
+ '}';
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserInfo.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserInfo.java
new file mode 100644
index 000000000..5a5ae5eb3
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserInfo.java
@@ -0,0 +1,8 @@
+package com.neo.model;
+
+public interface UserInfo {
+ String getUserName();
+ String getEmail();
+ String getHobby();
+ String getIntroduction();
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/param/UserDetailParam.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/param/UserDetailParam.java
new file mode 100644
index 000000000..0f7a49714
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/param/UserDetailParam.java
@@ -0,0 +1,65 @@
+package com.neo.param;
+
+
+import com.neo.model.Address;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import javax.persistence.*;
+
+public class UserDetailParam {
+ private String userId;
+ private Integer minAge;
+ private Integer maxAge;
+ private String realName;
+ private String introduction;
+ private String city;
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public Integer getMinAge() {
+ return minAge;
+ }
+
+ public void setMinAge(Integer minAge) {
+ this.minAge = minAge;
+ }
+
+ public Integer getMaxAge() {
+ return maxAge;
+ }
+
+ public void setMaxAge(Integer maxAge) {
+ this.maxAge = maxAge;
+ }
+
+ public String getRealName() {
+ return realName;
+ }
+
+ public void setRealName(String realName) {
+ this.realName = realName;
+ }
+
+ public String getIntroduction() {
+ return introduction;
+ }
+
+ public void setIntroduction(String introduction) {
+ this.introduction = introduction;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/AddressRepository.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/AddressRepository.java
new file mode 100644
index 000000000..3bba02753
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/AddressRepository.java
@@ -0,0 +1,7 @@
+package com.neo.repository;
+
+import com.neo.model.Address;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AddressRepository extends JpaRepository {
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserDetailRepository.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserDetailRepository.java
new file mode 100644
index 000000000..e133b0564
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserDetailRepository.java
@@ -0,0 +1,20 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import com.neo.model.UserDetail;
+import com.neo.model.UserInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+
+public interface UserDetailRepository extends JpaSpecificationExecutor,JpaRepository {
+
+ UserDetail findByHobby(String hobby);
+
+ @Query("select u.userName as userName, u.email as email, d.introduction as introduction , d.hobby as hobby from User u , UserDetail d " +
+ "where u.id=d.userId and d.hobby = ?1 ")
+ List findUserInfo(String hobby);
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserRepository.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..8318068a5
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,40 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.transaction.annotation.Transactional;
+
+
+public interface UserRepository extends JpaRepository {
+
+ User findByUserName(String userName);
+
+ User findByUserNameOrEmail(String username, String email);
+
+ @Transactional(timeout = 10)
+ @Modifying
+ @Query("update User set userName = ?1 where id = ?2")
+ int modifyById(String userName, Long id);
+
+ @Transactional
+ @Modifying
+ @Query("delete from User where id = ?1")
+ void deleteById(Long id);
+
+ @Query("select u from User u where u.email = ?1")
+ User findByEmail(String email);
+
+ @Query("select u from User u")
+ Page findALL(Pageable pageable);
+
+ Page findByNickName(String nickName, Pageable pageable);
+
+ Slice findByNickNameAndEmail(String nickName, String email,Pageable pageable);
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailService.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailService.java
new file mode 100644
index 000000000..a5d14ead7
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailService.java
@@ -0,0 +1,10 @@
+package com.neo.service;
+
+import com.neo.model.UserDetail;
+import com.neo.param.UserDetailParam;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+public interface UserDetailService {
+ public Page findByCondition(UserDetailParam detailParam, Pageable pageable);
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailServiceImpl.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailServiceImpl.java
new file mode 100644
index 000000000..18eaba979
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailServiceImpl.java
@@ -0,0 +1,48 @@
+package com.neo.service;
+
+import com.mysql.cj.util.StringUtils;
+import com.neo.model.UserDetail;
+import com.neo.param.UserDetailParam;
+import com.neo.repository.UserDetailRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.persistence.criteria.Predicate;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class UserDetailServiceImpl implements UserDetailService{
+
+ @Resource
+ private UserDetailRepository userDetailRepository;
+
+ @Override
+ public Page findByCondition(UserDetailParam detailParam, Pageable pageable){
+
+ return userDetailRepository.findAll((root, query, cb) -> {
+ List predicates = new ArrayList();
+ //equal 示例
+ if (!StringUtils.isNullOrEmpty(detailParam.getIntroduction())){
+ predicates.add(cb.equal(root.get("introduction"),detailParam.getIntroduction()));
+ }
+ //like 示例
+ if (!StringUtils.isNullOrEmpty(detailParam.getRealName())){
+ predicates.add(cb.like(root.get("realName"),"%"+detailParam.getRealName()+"%"));
+ }
+ //between 示例
+ if (detailParam.getMinAge()!=null && detailParam.getMaxAge()!=null) {
+ Predicate agePredicate = cb.between(root.get("age"), detailParam.getMinAge(), detailParam.getMaxAge());
+ predicates.add(agePredicate);
+ }
+ //greaterThan 大于等于示例
+ if (detailParam.getMinAge()!=null){
+ predicates.add(cb.greaterThan(root.get("age"),detailParam.getMinAge()));
+ }
+ return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
+ }, pageable);
+
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/main/resources/application.properties b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/resources/application.properties
new file mode 100644
index 000000000..b0b5ebe9a
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/main/resources/application.properties
@@ -0,0 +1,11 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.jpa.properties.hibernate.hbm2ddl.auto=create
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+#sql\u8F93\u51FA
+spring.jpa.show-sql=true
+#format\u4E00\u4E0Bsql\u8FDB\u884C\u8F93\u51FA
+spring.jpa.properties.hibernate.format_sql=true
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/JpaApplicationTests.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/JpaApplicationTests.java
new file mode 100644
index 000000000..4fe4fdbe0
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/JpaApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 JpaApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/JpaSpecificationTests.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/JpaSpecificationTests.java
new file mode 100644
index 000000000..751b7d351
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/JpaSpecificationTests.java
@@ -0,0 +1,40 @@
+package com.neo.repository;
+
+import com.neo.model.UserDetail;
+import com.neo.param.UserDetailParam;
+import com.neo.service.UserDetailService;
+import com.neo.service.UserDetailServiceImpl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class JpaSpecificationTests {
+
+ @Resource
+ private UserDetailService userDetailService;
+
+ @Test
+ public void testFindByCondition() {
+ int page=0,size=10;
+ Sort sort = new Sort(Sort.Direction.DESC, "id");
+ Pageable pageable = PageRequest.of(page, size, sort);
+ UserDetailParam param=new UserDetailParam();
+ param.setIntroduction("程序员");
+ param.setMinAge(10);
+ param.setMaxAge(30);
+ Page page1=userDetailService.findByCondition(param,pageable);
+ for (UserDetail userDetail:page1){
+ System.out.println("userDetail: "+userDetail.toString());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserDetailRepositoryTests.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserDetailRepositoryTests.java
new file mode 100644
index 000000000..679efb18a
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserDetailRepositoryTests.java
@@ -0,0 +1,59 @@
+package com.neo.repository;
+
+import com.neo.model.Address;
+import com.neo.model.User;
+import com.neo.model.UserDetail;
+import com.neo.model.UserInfo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserDetailRepositoryTests {
+
+ @Resource
+ private AddressRepository addressRepository;
+ @Resource
+ private UserDetailRepository userDetailRepository;
+
+ @Test
+ public void testSaveAddress() {
+ Address address=new Address();
+ address.setUserId(1L);
+ address.setCity("北京");
+ address.setProvince("北京");
+ address.setStreet("分钟寺");
+ addressRepository.save(address);
+ }
+
+ @Test
+ public void testSaveUserDetail() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+ UserDetail userDetail=new UserDetail();
+ userDetail.setUserId(3L);
+ userDetail.setHobby("吃鸡游戏");
+ userDetail.setAge(28);
+ userDetail.setIntroduction("一个爱玩的人");
+ userDetailRepository.save(userDetail);
+ }
+
+ @Test
+ public void testUserInfo() {
+ List userInfos=userDetailRepository.findUserInfo("钓鱼");
+ for (UserInfo userInfo:userInfos){
+ System.out.println("userInfo: "+userInfo.getUserName()+"-"+userInfo.getEmail()+"-"+userInfo.getHobby()+"-"+userInfo.getIntroduction());
+ }
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserRepositoryTests.java b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
new file mode 100644
index 000000000..c689ce573
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
@@ -0,0 +1,71 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import java.text.DateFormat;
+import java.util.Date;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTests {
+
+ @Resource
+ private UserRepository userRepository;
+
+ @Test
+ public void testSave() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+
+ userRepository.save(new User("aa", "aa123456","aa@126.com", "aa", formattedDate));
+ userRepository.save(new User("bb", "bb123456","bb@126.com", "bb", formattedDate));
+ userRepository.save(new User("cc", "cc123456","cc@126.com", "cc", formattedDate));
+
+// Assert.assertEquals(3, userRepository.findAll().size());
+// Assert.assertEquals("bb", userRepository.findByUserNameOrEmail("bb", "bb@126.com").getNickName());
+// userRepository.delete(userRepository.findByUserName("aa"));
+ }
+
+
+ @Test
+ public void testBaseQuery() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+ User user=new User("ff", "ff123456","ff@126.com", "ff", formattedDate);
+ userRepository.findAll();
+ userRepository.findById(3L);
+ userRepository.save(user);
+ user.setId(2L);
+ userRepository.delete(user);
+ userRepository.count();
+ userRepository.existsById(3L);
+ }
+
+ @Test
+ public void testCustomSql() {
+ userRepository.modifyById("neo",3L);
+ userRepository.deleteById(3L);
+ userRepository.findByEmail("ff@126.com");
+ }
+
+
+ @Test
+ public void testPageQuery() {
+ int page=1,size=2;
+ Sort sort = new Sort(Sort.Direction.DESC, "id");
+ Pageable pageable = PageRequest.of(page, size, sort);
+ userRepository.findALL(pageable);
+ userRepository.findByNickName("aa", pageable);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/pom.xml b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/pom.xml
new file mode 100644
index 000000000..78e5e2e04
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-multi-Jpa
+ 1.0
+ jar
+
+ spring-boot-multi-Jpa
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/MultiJpaApplication.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/MultiJpaApplication.java
new file mode 100644
index 000000000..2a9a26b17
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/MultiJpaApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MultiJpaApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MultiJpaApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/DataSourceConfig.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/DataSourceConfig.java
new file mode 100644
index 000000000..09f2b757d
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/DataSourceConfig.java
@@ -0,0 +1,41 @@
+package com.neo.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import javax.sql.DataSource;
+import java.util.Map;
+
+@Configuration
+public class DataSourceConfig {
+
+ @Autowired
+ private JpaProperties jpaProperties;
+ @Autowired
+ private HibernateProperties hibernateProperties;
+
+ @Bean(name = "primaryDataSource")
+ @Primary
+ @ConfigurationProperties("spring.datasource.primary")
+ public DataSource firstDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "secondaryDataSource")
+ @ConfigurationProperties("spring.datasource.secondary")
+ public DataSource secondDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "vendorProperties")
+ public Map getVendorProperties() {
+ return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/PrimaryConfig.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/PrimaryConfig.java
new file mode 100644
index 000000000..588cf91b7
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/PrimaryConfig.java
@@ -0,0 +1,59 @@
+package com.neo.config;
+
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+ entityManagerFactoryRef="entityManagerFactoryPrimary",
+ transactionManagerRef="transactionManagerPrimary",
+ basePackages= { "com.neo.repository.test1" })//设置dao(repo)所在位置
+public class PrimaryConfig {
+
+ @Autowired
+ @Qualifier("primaryDataSource")
+ private DataSource primaryDataSource;
+
+ @Autowired
+ @Qualifier("vendorProperties")
+ private Map vendorProperties;
+
+ @Bean(name = "entityManagerFactoryPrimary")
+ @Primary
+ public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
+ return builder
+ .dataSource(primaryDataSource)
+ .properties(vendorProperties)
+ .packages("com.neo.model") //设置实体类所在位置
+ .persistenceUnit("primaryPersistenceUnit")
+ .build();
+ }
+
+ @Bean(name = "entityManagerPrimary")
+ @Primary
+ public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
+ return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
+ }
+
+ @Bean(name = "transactionManagerPrimary")
+ @Primary
+ PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
+ return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/SecondaryConfig.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/SecondaryConfig.java
new file mode 100644
index 000000000..241f4764b
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/SecondaryConfig.java
@@ -0,0 +1,54 @@
+package com.neo.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManager;
+import javax.sql.DataSource;
+import java.util.Map;
+
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+ entityManagerFactoryRef="entityManagerFactorySecondary",
+ transactionManagerRef="transactionManagerSecondary",
+ basePackages= { "com.neo.repository.test2" })
+public class SecondaryConfig {
+
+ @Autowired
+ @Qualifier("secondaryDataSource")
+ private DataSource secondaryDataSource;
+
+ @Autowired
+ @Qualifier("vendorProperties")
+ private Map vendorProperties;
+
+ @Bean(name = "entityManagerFactorySecondary")
+ public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
+ return builder
+ .dataSource(secondaryDataSource)
+ .properties(vendorProperties)
+ .packages("com.neo.model")
+ .persistenceUnit("secondaryPersistenceUnit")
+ .build();
+ }
+
+ @Bean(name = "entityManagerSecondary")
+ public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
+ return entityManagerFactorySecondary(builder).getObject().createEntityManager();
+ }
+
+ @Bean(name = "transactionManagerSecondary")
+ PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
+ return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/model/User.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..f4cb974df
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/model/User.java
@@ -0,0 +1,86 @@
+package com.neo.model;
+
+
+
+import javax.persistence.*;
+
+import java.io.Serializable;
+
+@Entity
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+ @Column(nullable = false, unique = true)
+ private String userName;
+ @Column(nullable = false)
+ private String passWord;
+ @Column(nullable = false, unique = true)
+ private String email;
+ @Column(nullable = true, unique = true)
+ private String nickName;
+ @Column(nullable = false)
+ private String regTime;
+
+ public User() {
+ }
+
+ public User(String userName, String passWord, String email, String nickName, String regTime) {
+ this.userName = userName;
+ this.passWord = passWord;
+ this.email = email;
+ this.nickName = nickName;
+ this.regTime = regTime;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public String getRegTime() {
+ return regTime;
+ }
+
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test1/UserTest1Repository.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test1/UserTest1Repository.java
new file mode 100644
index 000000000..feecceab6
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test1/UserTest1Repository.java
@@ -0,0 +1,10 @@
+package com.neo.repository.test1;
+
+import com.neo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserTest1Repository extends JpaRepository {
+ User findById(long id);
+ User findByUserName(String userName);
+ User findByUserNameOrEmail(String username, String email);
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test2/UserTest2Repository.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test2/UserTest2Repository.java
new file mode 100644
index 000000000..45f8c24fd
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test2/UserTest2Repository.java
@@ -0,0 +1,11 @@
+package com.neo.repository.test2;
+
+import com.neo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface UserTest2Repository extends JpaRepository {
+ User findById(long id);
+ User findByUserName(String userName);
+ User findByUserNameOrEmail(String username, String email);
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/resources/application.properties b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/resources/application.properties
new file mode 100644
index 000000000..cab7dd706
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/main/resources/application.properties
@@ -0,0 +1,16 @@
+spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.primary.username=root
+spring.datasource.primary.password=root
+spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.secondary.username=root
+spring.datasource.secondary.password=root
+spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
+
+#sql\u8F93\u51FA
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.hbm2ddl.auto=create
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+#format\u4E00\u4E0Bsql\u8FDB\u884C\u8F93\u51FA
+spring.jpa.properties.hibernate.format_sql=true
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/MultiJpaApplicationTests.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/MultiJpaApplicationTests.java
new file mode 100644
index 000000000..c87999ccd
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/MultiJpaApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MultiJpaApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("Hello MultiJpa!");
+ }
+
+}
diff --git a/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/repository/UserRepositoryTests.java b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
new file mode 100644
index 000000000..693986f5d
--- /dev/null
+++ b/2.x/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
@@ -0,0 +1,58 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import com.neo.repository.test1.UserTest1Repository;
+import com.neo.repository.test2.UserTest2Repository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.text.DateFormat;
+import java.util.Date;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTests {
+ @Resource
+ private UserTest1Repository userTest1Repository;
+ @Resource
+ private UserTest2Repository userTest2Repository;
+
+ @Test
+ public void testSave() throws Exception {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+
+ userTest1Repository.save(new User("aa", "aa123456","aa@126.com", "aa", formattedDate));
+ userTest1Repository.save(new User("bb", "bb123456","bb@126.com", "bb", formattedDate));
+ userTest2Repository.save(new User("cc", "cc123456","cc@126.com", "cc", formattedDate));
+ }
+
+
+ @Test
+ public void testDelete() throws Exception {
+ userTest1Repository.deleteAll();
+ userTest2Repository.deleteAll();
+ }
+
+ @Test
+ public void testBaseQuery() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+ User user=new User("ff", "ff123456","ff@126.com", "ff", formattedDate);
+ userTest1Repository.findAll();
+ userTest2Repository.findById(3l);
+ userTest2Repository.save(user);
+ user.setId(2l);
+ userTest1Repository.delete(user);
+ userTest1Repository.count();
+ userTest2Repository.findById(3l);
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mail/pom.xml b/2.x/spring-boot-mail/pom.xml
new file mode 100644
index 000000000..142d89224
--- /dev/null
+++ b/2.x/spring-boot-mail/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mail
+ 1.0.0
+ jar
+
+ spring-boot-mail
+ Demo project for Spring Boot and mail
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.springframework
+ spring-context-support
+ RELEASE
+
+
+ com.sun.mail
+ javax.mail
+ RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-mail/src/main/java/com/neo/MailApplication.java b/2.x/spring-boot-mail/src/main/java/com/neo/MailApplication.java
new file mode 100644
index 000000000..c0aee4155
--- /dev/null
+++ b/2.x/spring-boot-mail/src/main/java/com/neo/MailApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MailApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MailApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mail/src/main/java/com/neo/service/MailService.java b/2.x/spring-boot-mail/src/main/java/com/neo/service/MailService.java
new file mode 100644
index 000000000..41df35605
--- /dev/null
+++ b/2.x/spring-boot-mail/src/main/java/com/neo/service/MailService.java
@@ -0,0 +1,16 @@
+package com.neo.service;
+
+/**
+ * Created by summer on 2017/5/4.
+ */
+public interface MailService {
+
+ void sendSimpleMail(String to, String subject, String content);
+
+ void sendHtmlMail(String to, String subject, String content);
+
+ void sendAttachmentsMail(String to, String subject, String content, String filePath);
+
+ void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);
+
+}
diff --git a/2.x/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java b/2.x/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java
new file mode 100644
index 000000000..ee161e54a
--- /dev/null
+++ b/2.x/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java
@@ -0,0 +1,140 @@
+package com.neo.service.impl;
+
+import com.neo.service.MailService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Component;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.io.File;
+
+/**
+ * Created by summer on 2017/5/4.
+ */
+@Component
+public class MailServiceImpl implements MailService{
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Autowired
+ private JavaMailSender mailSender;
+
+ @Value("${mail.fromMail.addr}")
+ private String from;
+
+ /**
+ * 发送文本邮件
+ * @param to
+ * @param subject
+ * @param content
+ */
+ @Override
+ public void sendSimpleMail(String to, String subject, String content) {
+ SimpleMailMessage message = new SimpleMailMessage();
+ message.setFrom(from);
+ message.setTo(to);
+ message.setSubject(subject);
+ message.setText(content);
+
+ try {
+ mailSender.send(message);
+ logger.info("简单邮件已经发送。");
+ } catch (Exception e) {
+ logger.error("发送简单邮件时发生异常!", e);
+ }
+
+ }
+
+ /**
+ * 发送html邮件
+ * @param to
+ * @param subject
+ * @param content
+ */
+ @Override
+ public void sendHtmlMail(String to, String subject, String content) {
+ MimeMessage message = mailSender.createMimeMessage();
+
+ try {
+ //true表示需要创建一个multipart message
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setFrom(from);
+ helper.setTo(to);
+ helper.setSubject(subject);
+ helper.setText(content, true);
+
+ mailSender.send(message);
+ logger.info("html邮件发送成功");
+ } catch (MessagingException e) {
+ logger.error("发送html邮件时发生异常!", e);
+ }
+ }
+
+
+ /**
+ * 发送带附件的邮件
+ * @param to
+ * @param subject
+ * @param content
+ * @param filePath
+ */
+ @Override
+ public void sendAttachmentsMail(String to, String subject, String content, String filePath){
+ MimeMessage message = mailSender.createMimeMessage();
+
+ try {
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setFrom(from);
+ helper.setTo(to);
+ helper.setSubject(subject);
+ helper.setText(content, true);
+
+ FileSystemResource file = new FileSystemResource(new File(filePath));
+ String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
+ helper.addAttachment(fileName, file);
+ //helper.addAttachment("test"+fileName, file);
+
+ mailSender.send(message);
+ logger.info("带附件的邮件已经发送。");
+ } catch (MessagingException e) {
+ logger.error("发送带附件的邮件时发生异常!", e);
+ }
+ }
+
+
+ /**
+ * 发送正文中有静态资源(图片)的邮件
+ * @param to
+ * @param subject
+ * @param content
+ * @param rscPath
+ * @param rscId
+ */
+ @Override
+ public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
+ MimeMessage message = mailSender.createMimeMessage();
+
+ try {
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setFrom(from);
+ helper.setTo(to);
+ helper.setSubject(subject);
+ helper.setText(content, true);
+
+ FileSystemResource res = new FileSystemResource(new File(rscPath));
+ helper.addInline(rscId, res);
+
+ mailSender.send(message);
+ logger.info("嵌入静态资源的邮件已经发送。");
+ } catch (MessagingException e) {
+ logger.error("发送嵌入静态资源的邮件时发生异常!", e);
+ }
+ }
+}
diff --git a/2.x/spring-boot-mail/src/main/resources/application.properties b/2.x/spring-boot-mail/src/main/resources/application.properties
new file mode 100644
index 000000000..dcbb52168
--- /dev/null
+++ b/2.x/spring-boot-mail/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+spring.application.name=spirng-boot-mail
+
+spring.mail.host=smtp.163.com
+spring.mail.username=xxoo@xxoo.com
+spring.mail.password=xxoo
+spring.mail.default-encoding=UTF-8
+
+mail.fromMail.addr=xxoo@xxoo.com
+
diff --git a/2.x/spring-boot-mail/src/main/resources/templates/emailTemplate.html b/2.x/spring-boot-mail/src/main/resources/templates/emailTemplate.html
new file mode 100644
index 000000000..387a4fbcd
--- /dev/null
+++ b/2.x/spring-boot-mail/src/main/resources/templates/emailTemplate.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Title
+
+
+ 您好,这是验证邮件,请点击下面的链接完成验证,
+ 激活账号
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-mail/src/test/java/com/neo/MailApplicationTests.java b/2.x/spring-boot-mail/src/test/java/com/neo/MailApplicationTests.java
new file mode 100644
index 000000000..7a9e7a09b
--- /dev/null
+++ b/2.x/spring-boot-mail/src/test/java/com/neo/MailApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MailApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java b/2.x/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java
new file mode 100644
index 000000000..91c4bbfd2
--- /dev/null
+++ b/2.x/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java
@@ -0,0 +1,65 @@
+package com.neo.service;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.context.Context;
+
+/**
+ * Created by summer on 2017/5/4.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MailServiceTest {
+
+ @Autowired
+ private MailService mailService;
+
+ @Autowired
+ private TemplateEngine templateEngine;
+
+ @Test
+ public void testSimpleMail() throws Exception {
+ mailService.sendSimpleMail("ityouknow@126.com","test simple mail"," hello this is simple mail");
+ }
+
+ @Test
+ public void testHtmlMail() throws Exception {
+ String content="\n" +
+ "\n" +
+ " hello world ! 这是一封html邮件!
\n" +
+ "\n" +
+ "";
+ mailService.sendHtmlMail("ityouknow@126.com","test simple mail",content);
+ }
+
+ @Test
+ public void sendAttachmentsMail() {
+ String filePath="e:\\tmp\\application.log";
+ mailService.sendAttachmentsMail("ityouknow@126.com", "主题:带附件的邮件", "有附件,请查收!", filePath);
+ }
+
+
+ @Test
+ public void sendInlineResourceMail() {
+ String rscId = "neo006";
+ String content="这是有图片的邮件:
";
+ String imgPath = "C:\\Users\\summer\\Pictures\\favicon.png";
+
+ mailService.sendInlineResourceMail("ityouknow@126.com", "主题:这是有图片的邮件", content, imgPath, rscId);
+ }
+
+
+ @Test
+ public void sendTemplateMail() {
+ //创建邮件正文
+ Context context = new Context();
+ context.setVariable("id", "006");
+ String emailContent = templateEngine.process("emailTemplate", context);
+
+ mailService.sendHtmlMail("ityouknow@126.com","主题:这是模板邮件",emailContent);
+ }
+}
diff --git a/2.x/spring-boot-memcache-spymemcached/pom.xml b/2.x/spring-boot-memcache-spymemcached/pom.xml
new file mode 100644
index 000000000..307afdb75
--- /dev/null
+++ b/2.x/spring-boot-memcache-spymemcached/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-memcache-spymemcached
+ 1.0.0
+ jar
+
+ spring-boot-memcache-spymemcached
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.4.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ net.spy
+ spymemcached
+ 2.12.2
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/MemcacheApplication.java b/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/MemcacheApplication.java
new file mode 100644
index 000000000..434519a5b
--- /dev/null
+++ b/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/MemcacheApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MemcacheApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MemcacheApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcacheSource.java b/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcacheSource.java
new file mode 100644
index 000000000..e3e421ac8
--- /dev/null
+++ b/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcacheSource.java
@@ -0,0 +1,29 @@
+package com.neo.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "memcache")
+public class MemcacheSource {
+
+ private String ip;
+
+ private int port;
+
+ public String getIp() {
+ return ip;
+ }
+
+ public void setIp(String ip) {
+ this.ip = ip;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+}
diff --git a/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcachedRunner.java b/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcachedRunner.java
new file mode 100644
index 000000000..e1175b654
--- /dev/null
+++ b/2.x/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcachedRunner.java
@@ -0,0 +1,35 @@
+package com.neo.config;
+
+import net.spy.memcached.MemcachedClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+@Component
+public class MemcachedRunner implements CommandLineRunner {
+ protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Resource
+ private MemcacheSource memcacheSource;
+
+ private MemcachedClient client = null;
+
+ @Override
+ public void run(String... args) throws Exception {
+ try {
+ client = new MemcachedClient(new InetSocketAddress(memcacheSource.getIp(),memcacheSource.getPort()));
+ } catch (IOException e) {
+ logger.error("inint MemcachedClient failed ",e);
+ }
+ }
+
+ public MemcachedClient getClient() {
+ return client;
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-memcache-spymemcached/src/main/resources/application.properties b/2.x/spring-boot-memcache-spymemcached/src/main/resources/application.properties
new file mode 100644
index 000000000..4d0269621
--- /dev/null
+++ b/2.x/spring-boot-memcache-spymemcached/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+memcache.ip=192.168.0.161
+memcache.port=11211
\ No newline at end of file
diff --git a/2.x/spring-boot-memcache-spymemcached/src/test/java/com/neo/MemcacheApplicationTests.java b/2.x/spring-boot-memcache-spymemcached/src/test/java/com/neo/MemcacheApplicationTests.java
new file mode 100644
index 000000000..d2a66dc4d
--- /dev/null
+++ b/2.x/spring-boot-memcache-spymemcached/src/test/java/com/neo/MemcacheApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 MemcacheApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-memcache-spymemcached/src/test/java/com/neo/RepositoryTests.java b/2.x/spring-boot-memcache-spymemcached/src/test/java/com/neo/RepositoryTests.java
new file mode 100644
index 000000000..ceaef2205
--- /dev/null
+++ b/2.x/spring-boot-memcache-spymemcached/src/test/java/com/neo/RepositoryTests.java
@@ -0,0 +1,26 @@
+package com.neo;
+
+import com.neo.config.MemcachedRunner;
+import net.spy.memcached.MemcachedClient;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class RepositoryTests {
+
+ @Resource
+ private MemcachedRunner memcachedRunner;
+
+ @Test
+ public void testSetGet() {
+ MemcachedClient memcachedClient = memcachedRunner.getClient();
+ memcachedClient.set("testkey",1000,"666666");
+ System.out.println("*********** "+memcachedClient.get("testkey").toString());
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/pom.xml b/2.x/spring-boot-mongodb/spring-boot-mongodb/pom.xml
new file mode 100644
index 000000000..e1ef7d580
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mongodb
+ 1.0.0
+ jar
+
+ spring-boot-mongodb
+ Demo project for Spring Boot and mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/MongoDBApplication.java b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/MongoDBApplication.java
new file mode 100644
index 000000000..b8c63d563
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/MongoDBApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MongoDBApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MongoDBApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/model/User.java b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..c15340ae7
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/model/User.java
@@ -0,0 +1,46 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+public class User implements Serializable {
+ private static final long serialVersionUID = -3258839839160856613L;
+ private Long id;
+ private String userName;
+ private String passWord;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ @Override
+ public String toString() {
+ return "UserEntity{" +
+ "id=" + id +
+ ", userName='" + userName + '\'' +
+ ", passWord='" + passWord + '\'' +
+ '}';
+ }
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/UserRepository.java b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..e1a3d4134
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,18 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+public interface UserRepository {
+
+ public void saveUser(User user);
+
+ public User findUserByUserName(String userName);
+
+ public long updateUser(User user);
+
+ public void deleteUserById(Long id);
+
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/impl/UserRepositoryImpl.java b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/impl/UserRepositoryImpl.java
new file mode 100644
index 000000000..8c96f5a42
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/impl/UserRepositoryImpl.java
@@ -0,0 +1,70 @@
+package com.neo.repository.impl;
+
+import com.mongodb.client.result.UpdateResult;
+import com.neo.repository.UserRepository;
+import com.neo.model.User;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+@Component
+public class UserRepositoryImpl implements UserRepository {
+
+ @Autowired
+ private MongoTemplate mongoTemplate;
+
+ /**
+ * 创建对象
+ * @param user
+ */
+ @Override
+ public void saveUser(User user) {
+ mongoTemplate.save(user);
+ }
+
+ /**
+ * 根据用户名查询对象
+ * @param userName
+ * @return
+ */
+ @Override
+ public User findUserByUserName(String userName) {
+ Query query=new Query(Criteria.where("userName").is(userName));
+ User user = mongoTemplate.findOne(query , User.class);
+ return user;
+ }
+
+ /**
+ * 更新对象
+ * @param user
+ */
+ @Override
+ public long updateUser(User user) {
+ Query query=new Query(Criteria.where("id").is(user.getId()));
+ Update update= new Update().set("userName", user.getUserName()).set("passWord", user.getPassWord());
+ //更新查询返回结果集的第一条
+ UpdateResult result =mongoTemplate.updateFirst(query,update,User.class);
+ //更新查询返回结果集的所有
+ // mongoTemplate.updateMulti(query,update,UserEntity.class);
+ if(result!=null)
+ return result.getMatchedCount();
+ else
+ return 0;
+ }
+
+ /**
+ * 删除对象
+ * @param id
+ */
+ @Override
+ public void deleteUserById(Long id) {
+ Query query=new Query(Criteria.where("id").is(id));
+ mongoTemplate.remove(query,User.class);
+ }
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/resources/application.properties b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/resources/application.properties
new file mode 100644
index 000000000..32e5ca921
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+spring.application.name=spring-boot-mongodb
+
+spring.data.mongodb.uri=mongodb://192.168.0.75:20000/test
+
+
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/MongoDBApplicationTests.java b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/MongoDBApplicationTests.java
new file mode 100644
index 000000000..cd30276df
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/MongoDBApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MongoDBApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/repository/UserRepositoryTest.java b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/repository/UserRepositoryTest.java
new file mode 100644
index 000000000..cb6372f02
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/repository/UserRepositoryTest.java
@@ -0,0 +1,49 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTest {
+
+ @Autowired
+ private UserRepository userDao;
+
+ @Test
+ public void testSaveUser() throws Exception {
+ User user=new User();
+ user.setId(2l);
+ user.setUserName("小明");
+ user.setPassWord("fffooo123");
+ userDao.saveUser(user);
+ }
+
+ @Test
+ public void findUserByUserName(){
+ User user= userDao.findUserByUserName("小明");
+ System.out.println("user is "+user);
+ }
+
+ @Test
+ public void updateUser(){
+ User user=new User();
+ user.setId(2l);
+ user.setUserName("天空");
+ user.setPassWord("fffxxxx");
+ userDao.updateUser(user);
+ }
+
+ @Test
+ public void deleteUserById(){
+ userDao.deleteUserById(1l);
+ }
+
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/pom.xml b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/pom.xml
new file mode 100644
index 000000000..e38f5ba0c
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-multi-mongodb
+ 1.0.0
+ jar
+
+ spring-boot-multi-mongodb
+ Demo project for Spring Boot and multi mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/MultiMongodbApplication.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/MultiMongodbApplication.java
new file mode 100644
index 000000000..e33c97dae
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/MultiMongodbApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MultiMongodbApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MultiMongodbApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java
new file mode 100644
index 000000000..5d4a2f5bb
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java
@@ -0,0 +1,46 @@
+package com.neo.config;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientURI;
+import com.neo.config.props.MultipleMongoProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.mongo.MongoProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.mongodb.MongoDbFactory;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
+
+@Configuration
+public class MultipleMongoConfig {
+
+ @Autowired
+ private MultipleMongoProperties mongoProperties;
+
+ @Primary
+ @Bean(name = "primaryMongoTemplate")
+ public MongoTemplate primaryMongoTemplate() throws Exception {
+ return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
+ }
+
+ @Bean
+ @Qualifier("secondaryMongoTemplate")
+ public MongoTemplate secondaryMongoTemplate() throws Exception {
+ return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
+ }
+
+ @Bean
+ @Primary
+ public MongoDbFactory primaryFactory(MongoProperties mongo) throws Exception {
+ MongoClient client = new MongoClient(new MongoClientURI(mongoProperties.getPrimary().getUri()));
+ return new SimpleMongoDbFactory(client, mongoProperties.getPrimary().getDatabase());
+ }
+
+ @Bean
+ public MongoDbFactory secondaryFactory(MongoProperties mongo) throws Exception {
+ MongoClient client = new MongoClient(new MongoClientURI(mongoProperties.getSecondary().getUri()));
+ return new SimpleMongoDbFactory(client, mongoProperties.getSecondary().getDatabase());
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java
new file mode 100644
index 000000000..7920d185d
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java
@@ -0,0 +1,23 @@
+package com.neo.config;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientURI;
+import com.neo.config.props.MultipleMongoProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.mongo.MongoProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.mongodb.MongoDbFactory;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+
+@Configuration
+@EnableConfigurationProperties(MultipleMongoProperties.class)
+@EnableMongoRepositories(basePackages = "com.neo.repository.primary",
+ mongoTemplateRef = "primaryMongoTemplate")
+public class PrimaryMongoConfig {
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java
new file mode 100644
index 000000000..c50e2282f
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java
@@ -0,0 +1,24 @@
+package com.neo.config;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientURI;
+import com.neo.config.props.MultipleMongoProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.mongo.MongoProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.MongoDbFactory;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+
+@Configuration
+@EnableConfigurationProperties(MultipleMongoProperties.class)
+@EnableMongoRepositories(basePackages = "com.neo.repository.secondary",
+ mongoTemplateRef = "secondaryMongoTemplate")
+public class SecondaryMongoConfig {
+
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java
new file mode 100644
index 000000000..5bf4ff66a
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java
@@ -0,0 +1,27 @@
+package com.neo.config.props;
+
+import org.springframework.boot.autoconfigure.mongo.MongoProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "mongodb")
+public class MultipleMongoProperties {
+
+ private MongoProperties primary = new MongoProperties();
+ private MongoProperties secondary = new MongoProperties();
+
+ public MongoProperties getPrimary() {
+ return primary;
+ }
+
+ public void setPrimary(MongoProperties primary) {
+ this.primary = primary;
+ }
+
+ public MongoProperties getSecondary() {
+ return secondary;
+ }
+
+ public void setSecondary(MongoProperties secondary) {
+ this.secondary = secondary;
+ }
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/model/User.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..b5cd0a861
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/model/User.java
@@ -0,0 +1,49 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+
+public class User implements Serializable {
+ private static final long serialVersionUID = -3258839839160856613L;
+ private String id;
+ private String userName;
+ private String passWord;
+
+ public User(String userName, String passWord) {
+ this.userName = userName;
+ this.passWord = passWord;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "id='" + id + '\'' +
+ ", userName='" + userName + '\'' +
+ ", passWord='" + passWord + '\'' +
+ '}';
+ }
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/primary/PrimaryRepository.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/primary/PrimaryRepository.java
new file mode 100644
index 000000000..50877eb1c
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/primary/PrimaryRepository.java
@@ -0,0 +1,10 @@
+package com.neo.repository.primary;
+
+import com.neo.model.User;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+/**
+ * @author neo
+ */
+public interface PrimaryRepository extends MongoRepository {
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/secondary/SecondaryRepository.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/secondary/SecondaryRepository.java
new file mode 100644
index 000000000..11df9153a
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/secondary/SecondaryRepository.java
@@ -0,0 +1,10 @@
+package com.neo.repository.secondary;
+
+import com.neo.model.User;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+/**
+ * @author neo
+ */
+public interface SecondaryRepository extends MongoRepository {
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/resources/application.properties b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/resources/application.properties
new file mode 100644
index 000000000..d4287a17a
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/resources/application.properties
@@ -0,0 +1,8 @@
+spring.application.name=spring-boot-multi-mongodb
+
+mongodb.primary.uri=mongodb://192.168.0.75:20000
+mongodb.primary.database=primary
+mongodb.secondary.uri=mongodb://192.168.0.75:20000
+mongodb.secondary.database=secondary
+
+
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/MultiMongodbApplicationTests.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/MultiMongodbApplicationTests.java
new file mode 100644
index 000000000..8f59e588d
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/MultiMongodbApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MultiMongodbApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/repository/MuliDatabaseTest.java b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/repository/MuliDatabaseTest.java
new file mode 100644
index 000000000..42bf1b447
--- /dev/null
+++ b/2.x/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/repository/MuliDatabaseTest.java
@@ -0,0 +1,45 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import com.neo.repository.primary.PrimaryRepository;
+import com.neo.repository.secondary.SecondaryRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MuliDatabaseTest {
+
+ @Autowired
+ private PrimaryRepository primaryRepository;
+
+ @Autowired
+ private SecondaryRepository secondaryRepository;
+
+ @Test
+ public void TestSave() {
+ System.out.println("************************************************************");
+ System.out.println("测试开始");
+ System.out.println("************************************************************");
+ this.primaryRepository.save(new User("小张", "123456"));
+ this.secondaryRepository.save(new User("小王", "654321"));
+ List primaries = this.primaryRepository.findAll();
+ for (User primary : primaries) {
+ System.out.println(primary.toString());
+ }
+ List secondaries = this.secondaryRepository.findAll();
+ for (User secondary : secondaries) {
+ System.out.println(secondary.toString());
+ }
+ System.out.println("************************************************************");
+ System.out.println("测试完成");
+ System.out.println("************************************************************");
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis-plus/pom.xml b/2.x/spring-boot-mybatis-plus/pom.xml
new file mode 100644
index 000000000..6f088774e
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.example
+ spring-boot-mybatis-plus
+ 1.0.0
+ jar
+
+ Spring Boot MyBatis Plus
+ Spring Boot 2 Demo
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.4.RELEASE
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.1.1
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/MyBatisPlusApplication.java b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/MyBatisPlusApplication.java
new file mode 100644
index 000000000..8cadbf0c6
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/MyBatisPlusApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MyBatisPlusApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MyBatisPlusApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/config/MybatisPlusConfig.java b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/config/MybatisPlusConfig.java
new file mode 100644
index 000000000..914ffbbab
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/config/MybatisPlusConfig.java
@@ -0,0 +1,19 @@
+package com.neo.config;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@MapperScan("com.neo.mapper")
+public class MybatisPlusConfig {
+
+ /**
+ * 分页插件
+ */
+ @Bean
+ public PaginationInterceptor paginationInterceptor() {
+ return new PaginationInterceptor();
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/mapper/UserMapper.java b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/mapper/UserMapper.java
new file mode 100644
index 000000000..227c33c92
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/mapper/UserMapper.java
@@ -0,0 +1,8 @@
+package com.neo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.neo.model.User;
+
+public interface UserMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/model/User.java b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..0cf4eccd0
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/main/java/com/neo/model/User.java
@@ -0,0 +1,11 @@
+package com.neo.model;
+
+import lombok.Data;
+
+@Data
+public class User {
+ private Long id;
+ private String name;
+ private Integer age;
+ private String email;
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis-plus/src/main/resources/application.yml b/2.x/spring-boot-mybatis-plus/src/main/resources/application.yml
new file mode 100644
index 000000000..46530ce41
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/main/resources/application.yml
@@ -0,0 +1,14 @@
+# DataSource Config
+spring:
+ datasource:
+ driver-class-name: org.h2.Driver
+ schema: classpath:db/schema-h2.sql
+ data: classpath:db/data-h2.sql
+ url: jdbc:h2:mem:test
+ username: root
+ password: test
+
+# Logger Config
+logging:
+ level:
+ com.neo: debug
diff --git a/2.x/spring-boot-mybatis-plus/src/main/resources/db/data-h2.sql b/2.x/spring-boot-mybatis-plus/src/main/resources/db/data-h2.sql
new file mode 100644
index 000000000..7e97dbde4
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/main/resources/db/data-h2.sql
@@ -0,0 +1,8 @@
+DELETE FROM user;
+
+INSERT INTO user (id, name, age, email) VALUES
+(1, 'neo', 18, 'smile1@ityouknow.com'),
+(2, 'keep', 36, 'smile@ityouknow.com'),
+(3, 'pure', 28, 'smile@ityouknow.com'),
+(4, 'smile', 21, 'smile@ityouknow.com'),
+(5, 'it', 24, 'smile@ityouknow.com');
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis-plus/src/main/resources/db/schema-h2.sql b/2.x/spring-boot-mybatis-plus/src/main/resources/db/schema-h2.sql
new file mode 100644
index 000000000..baa5a6160
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/main/resources/db/schema-h2.sql
@@ -0,0 +1,10 @@
+DROP TABLE IF EXISTS user;
+
+CREATE TABLE user
+(
+ id BIGINT(20) NOT NULL COMMENT '主键ID',
+ name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
+ age INT(11) NULL DEFAULT NULL COMMENT '年龄',
+ email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
+ PRIMARY KEY (id)
+);
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis-plus/src/test/java/com/neo/MyBatisPlusApplicationTests.java b/2.x/spring-boot-mybatis-plus/src/test/java/com/neo/MyBatisPlusApplicationTests.java
new file mode 100644
index 000000000..1eaf2857a
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/test/java/com/neo/MyBatisPlusApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 MyBatisPlusApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis-plus/src/test/java/com/neo/MyBatisPlusTest.java b/2.x/spring-boot-mybatis-plus/src/test/java/com/neo/MyBatisPlusTest.java
new file mode 100644
index 000000000..d68233528
--- /dev/null
+++ b/2.x/spring-boot-mybatis-plus/src/test/java/com/neo/MyBatisPlusTest.java
@@ -0,0 +1,102 @@
+package com.neo;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.neo.mapper.UserMapper;
+import com.neo.model.User;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MyBatisPlusTest {
+
+ @Autowired
+ private UserMapper userMapper;
+
+
+ @Test
+ public void testSelectOne() {
+ User user = userMapper.selectById(1L);
+ System.out.println(user);
+ }
+
+ @Test
+ public void testInsert() {
+ User user = new User();
+ user.setName("微笑");
+ user.setAge(3);
+ user.setEmail("neo@tooool.org");
+ assertThat(userMapper.insert(user)).isGreaterThan(0);
+ // 成功直接拿会写的 ID
+ assertThat(user.getId()).isNotNull();
+ }
+
+ @Test
+ public void testDelete() {
+ assertThat(userMapper.deleteById(3L)).isGreaterThan(0);
+ assertThat(userMapper.delete(new QueryWrapper()
+ .lambda().eq(User::getName, "smile"))).isGreaterThan(0);
+ }
+
+ @Test
+ public void testUpdate() {
+ User user = userMapper.selectById(2);
+ assertThat(user.getAge()).isEqualTo(36);
+ assertThat(user.getName()).isEqualTo("keep");
+
+ userMapper.update(
+ null,
+ Wrappers.lambdaUpdate().set(User::getEmail, "123@123").eq(User::getId, 2)
+ );
+ assertThat(userMapper.selectById(2).getEmail()).isEqualTo("123@123");
+ }
+
+ @Test
+ public void testSelect() {
+ List userList = userMapper.selectList(null);
+ Assert.assertEquals(5, userList.size());
+ userList.forEach(System.out::println);
+ }
+
+ @Test
+ public void testSelectCondition() {
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.select("max(id) as id");
+ List userList = userMapper.selectList(wrapper);
+ userList.forEach(System.out::println);
+ }
+
+ @Test
+ public void testPage() {
+ System.out.println("----- baseMapper 自带分页 ------");
+ Page page = new Page<>(1, 2);
+ IPage userIPage = userMapper.selectPage(page, new QueryWrapper()
+ .gt("age", 6));
+ assertThat(page).isSameAs(userIPage);
+ System.out.println("总条数 ------> " + userIPage.getTotal());
+ System.out.println("当前页数 ------> " + userIPage.getCurrent());
+ System.out.println("当前每页显示数 ------> " + userIPage.getSize());
+ print(userIPage.getRecords());
+ System.out.println("----- baseMapper 自带分页 ------");
+ }
+
+ private void print(List list) {
+ if (!CollectionUtils.isEmpty(list)) {
+ list.forEach(System.out::println);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/pom.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/pom.xml
new file mode 100644
index 000000000..fc8412fd3
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-annotation-mulidatasource
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-annotation-mulidatasource
+ Demo project for Spring Boot and mybatis with annotation
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/MAMApplication.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/MAMApplication.java
new file mode 100644
index 000000000..a77fe795e
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/MAMApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MAMApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MAMApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
new file mode 100644
index 000000000..2db7d6533
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
@@ -0,0 +1,51 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
+public class DataSource1Config {
+
+ @Bean(name = "test1DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test1")
+ @Primary
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test1SqlSessionFactory")
+ @Primary
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ return bean.getObject();
+ }
+
+ @Bean(name = "test1TransactionManager")
+ @Primary
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test1SqlSessionTemplate")
+ @Primary
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
new file mode 100644
index 000000000..e52928c43
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
@@ -0,0 +1,46 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
+public class DataSource2Config {
+
+ @Bean(name = "test2DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test2")
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test2SqlSessionFactory")
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ return bean.getObject();
+ }
+
+ @Bean(name = "test2TransactionManager")
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test2SqlSessionTemplate")
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
new file mode 100644
index 000000000..6ab2e6a09
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
@@ -0,0 +1,35 @@
+package com.neo.mapper.test1;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+
+public interface User1Mapper {
+
+
+ @Select("SELECT * FROM users")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ List getAll();
+
+ @Select("SELECT * FROM users WHERE id = #{id}")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ User getOne(Long id);
+
+ @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
+ void insert(User user);
+
+ @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
+ void update(User user);
+
+ @Delete("DELETE FROM users WHERE id =#{id}")
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
new file mode 100644
index 000000000..50c5c855d
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
@@ -0,0 +1,35 @@
+package com.neo.mapper.test2;
+
+import java.util.List;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import org.apache.ibatis.annotations.*;
+
+public interface User2Mapper {
+
+
+ @Select("SELECT * FROM users")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ List getAll();
+
+ @Select("SELECT * FROM users WHERE id = #{id}")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ User getOne(Long id);
+
+ @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
+ void insert(User user);
+
+ @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
+ void update(User user);
+
+ @Delete("DELETE FROM users WHERE id =#{id}")
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/model/User.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..c92c15d66
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,50 @@
+package com.neo.web;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+import com.neo.model.User;
+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 com.neo.mapper.test2.User2Mapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private User1Mapper user1Mapper;
+
+ @Autowired
+ private User2Mapper user2Mapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=user1Mapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=user2Mapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ user2Mapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ user2Mapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ user1Mapper.delete(id);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties
new file mode 100644
index 000000000..819d06c92
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties
@@ -0,0 +1,12 @@
+mybatis.type-aliases-package=com.neo.model
+
+spring.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test1.username=root
+spring.datasource.test1.password=root
+spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test2.username=root
+spring.datasource.test2.password=root
+spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/MAMApplicationTests.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/MAMApplicationTests.java
new file mode 100644
index 000000000..8b7bbef35
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/MAMApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MAMApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
new file mode 100644
index 000000000..b08f07b7c
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
@@ -0,0 +1,52 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+import com.neo.model.User;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User1MapperTest {
+
+ @Autowired
+ private User1Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ Assert.assertEquals(3, userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.size());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(6l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(6l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
new file mode 100644
index 000000000..77ebc4675
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
@@ -0,0 +1,51 @@
+package com.neo.mapper;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import com.neo.mapper.test2.User2Mapper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User2MapperTest {
+
+ @Autowired
+ private User2Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ Assert.assertEquals(3, userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.toString());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(6l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(6l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/users.sql b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/pom.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/pom.xml
new file mode 100644
index 000000000..45ab8ec36
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-annotation
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-annotation
+ Demo project for Spring Boot and mybatis
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/MybatisAnnotationApplication.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/MybatisAnnotationApplication.java
new file mode 100644
index 000000000..ebac358ad
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/MybatisAnnotationApplication.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("com.neo.mapper")
+public class MybatisAnnotationApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MybatisAnnotationApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java
new file mode 100644
index 000000000..0189ea95c
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java
@@ -0,0 +1,40 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.model.User;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Result;
+import org.apache.ibatis.annotations.Results;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import com.neo.enums.UserSexEnum;
+
+public interface UserMapper {
+
+ @Select("SELECT * FROM users")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ List getAll();
+
+ @Select("SELECT * FROM users WHERE id = #{id}")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ User getOne(Long id);
+
+ @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
+ void insert(User user);
+
+ @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
+ void update(User user);
+
+ @Delete("DELETE FROM users WHERE id =#{id}")
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/model/User.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..25144b362
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,47 @@
+package com.neo.web;
+
+import java.util.List;
+
+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 com.neo.model.User;
+import com.neo.mapper.UserMapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=userMapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=userMapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ userMapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ userMapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ userMapper.delete(id);
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/resources/application.properties b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/resources/application.properties
new file mode 100644
index 000000000..06400e91a
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+mybatis.type-aliases-package=com.neo.model
+
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/MybatisAnnotationApplicationTests.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/MybatisAnnotationApplicationTests.java
new file mode 100644
index 000000000..9a9777482
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/MybatisAnnotationApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MybatisAnnotationApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java
new file mode 100644
index 000000000..0e12f6fd3
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java
@@ -0,0 +1,47 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.model.User;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserMapperTest {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa1", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb1", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc1", "b123456", UserSexEnum.WOMAN));
+
+ Assert.assertEquals(3, userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ System.out.println(users.toString());
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(30l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(30l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/users.sql b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-annotation/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/pom.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/pom.xml
new file mode 100644
index 000000000..66f257af5
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-xml-mulidatasource
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-xml-mulidatasource
+ Demo project for Spring Boot and mybatis
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/MXMApplication.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/MXMApplication.java
new file mode 100644
index 000000000..ad7b9d9d7
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/MXMApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MXMApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MXMApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
new file mode 100644
index 000000000..40bcf28d5
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
@@ -0,0 +1,53 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
+public class DataSource1Config {
+
+ @Bean(name = "test1DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test1")
+ @Primary
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test1SqlSessionFactory")
+ @Primary
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
+ return bean.getObject();
+ }
+
+ @Bean(name = "test1TransactionManager")
+ @Primary
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test1SqlSessionTemplate")
+ @Primary
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
new file mode 100644
index 000000000..67864089a
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
@@ -0,0 +1,48 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
+public class DataSource2Config {
+
+ @Bean(name = "test2DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test2")
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test2SqlSessionFactory")
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
+ return bean.getObject();
+ }
+
+ @Bean(name = "test2TransactionManager")
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test2SqlSessionTemplate")
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
new file mode 100644
index 000000000..d9502822f
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
@@ -0,0 +1,19 @@
+package com.neo.mapper.test1;
+
+import com.neo.model.User;
+
+import java.util.List;
+
+public interface User1Mapper {
+
+ List getAll();
+
+ User getOne(Long id);
+
+ void insert(User user);
+
+ void update(User user);
+
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
new file mode 100644
index 000000000..d5c91ebf1
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
@@ -0,0 +1,19 @@
+package com.neo.mapper.test2;
+
+import java.util.List;
+
+import com.neo.model.User;
+
+public interface User2Mapper {
+
+ List getAll();
+
+ User getOne(Long id);
+
+ void insert(User user);
+
+ void update(User user);
+
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/model/User.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/web/UserController.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..a608500f1
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,51 @@
+package com.neo.web;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+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 com.neo.model.User;
+import com.neo.mapper.test2.User2Mapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private User1Mapper user1Mapper;
+
+ @Autowired
+ private User2Mapper user2Mapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=user1Mapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=user2Mapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ user2Mapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ user2Mapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ user1Mapper.delete(id);
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/application.properties b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/application.properties
new file mode 100644
index 000000000..e2e0f4a74
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/application.properties
@@ -0,0 +1,11 @@
+mybatis.config-location=classpath:mybatis/mybatis-config.xml
+
+spring.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test1.username=root
+spring.datasource.test1.password=root
+spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test2.username=root
+spring.datasource.test2.password=root
+spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml
new file mode 100644
index 000000000..0a2ced2ce
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ id, userName, passWord, user_sex, nick_name
+
+
+
+
+
+
+
+ INSERT INTO
+ users
+ (userName,passWord,user_sex)
+ VALUES
+ (#{userName}, #{passWord}, #{userSex})
+
+
+
+ UPDATE
+ users
+ SET
+ userName = #{userName},
+ passWord = #{passWord},
+ nick_name = #{nickName}
+ WHERE
+ id = #{id}
+
+
+
+ DELETE FROM
+ users
+ WHERE
+ id =#{id}
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml
new file mode 100644
index 000000000..da3dc2e7c
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ id, userName, passWord, user_sex, nick_name
+
+
+
+
+
+
+
+ INSERT INTO
+ users
+ (userName,passWord,user_sex)
+ VALUES
+ (#{userName}, #{passWord}, #{userSex})
+
+
+
+ UPDATE
+ users
+ SET
+ userName = #{userName},
+ passWord = #{passWord},
+ nick_name = #{nickName}
+ WHERE
+ id = #{id}
+
+
+
+ DELETE FROM
+ users
+ WHERE
+ id =#{id}
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mybatis-config.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mybatis-config.xml
new file mode 100644
index 000000000..56097ffb9
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mybatis-config.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/MXMApplicationTests.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/MXMApplicationTests.java
new file mode 100644
index 000000000..422edba96
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/MXMApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MXMApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
new file mode 100644
index 000000000..12c4b6aa8
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
@@ -0,0 +1,52 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User1MapperTest {
+
+ @Autowired
+ private User1Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ Assert.assertEquals(3, userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.size());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(6l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(6l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
new file mode 100644
index 000000000..77ebc4675
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
@@ -0,0 +1,51 @@
+package com.neo.mapper;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import com.neo.mapper.test2.User2Mapper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User2MapperTest {
+
+ @Autowired
+ private User2Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ Assert.assertEquals(3, userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.toString());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(6l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(6l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/users.sql b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/pom.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/pom.xml
new file mode 100644
index 000000000..389ee8163
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/pom.xml
@@ -0,0 +1,56 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-xml
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-xml
+ Demo project for Spring Boot and mybatis
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/MybatisXmlApplication.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/MybatisXmlApplication.java
new file mode 100644
index 000000000..863b95aba
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/MybatisXmlApplication.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("com.neo.mapper")
+public class MybatisXmlApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MybatisXmlApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java
new file mode 100644
index 000000000..f08f70bf3
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java
@@ -0,0 +1,19 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.model.User;
+
+public interface UserMapper {
+
+ List getAll();
+
+ User getOne(Long id);
+
+ void insert(User user);
+
+ void update(User user);
+
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/model/User.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..25144b362
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,47 @@
+package com.neo.web;
+
+import java.util.List;
+
+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 com.neo.model.User;
+import com.neo.mapper.UserMapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=userMapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=userMapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ userMapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ userMapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ userMapper.delete(id);
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/application.properties b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/application.properties
new file mode 100644
index 000000000..0e2bea577
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/application.properties
@@ -0,0 +1,8 @@
+mybatis.config-location=classpath:mybatis/mybatis-config.xml
+mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
+mybatis.type-aliases-package=com.neo.model
+
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
new file mode 100644
index 000000000..b84731b11
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ id, userName, passWord, user_sex, nick_name
+
+
+
+
+
+
+
+ INSERT INTO
+ users
+ (userName,passWord,user_sex)
+ VALUES
+ (#{userName}, #{passWord}, #{userSex})
+
+
+
+ UPDATE
+ users
+ SET
+ userName = #{userName},
+ passWord = #{passWord},
+ nick_name = #{nickName}
+ WHERE
+ id = #{id}
+
+
+
+ DELETE FROM
+ users
+ WHERE
+ id =#{id}
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml
new file mode 100644
index 000000000..56097ffb9
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/MybatisXmlApplicationTests.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/MybatisXmlApplicationTests.java
new file mode 100644
index 000000000..3938dfde3
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/MybatisXmlApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MybatisXmlApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java
new file mode 100644
index 000000000..586ff57af
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java
@@ -0,0 +1,51 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserMapperTest {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ Assert.assertEquals(3, userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.toString());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(6l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(6l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java
new file mode 100644
index 000000000..2fd5fa943
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java
@@ -0,0 +1,37 @@
+package com.neo.web;
+
+
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserControllerTest {
+ @Autowired
+ private WebApplicationContext wac;
+ private MockMvc mockMvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); //初始化MockMvc对象
+ }
+
+ @Test
+ public void getUsers() throws Exception {
+ mockMvc.perform(MockMvcRequestBuilders.post("/getUsers")
+ .accept(MediaType.APPLICATION_JSON_UTF8)).andDo(print());
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/users.sql b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/2.x/spring-boot-mybatis/spring-boot-mybatis-xml/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/2.x/spring-boot-package-war/pom.xml b/2.x/spring-boot-package-war/pom.xml
new file mode 100644
index 000000000..c54d0da80
--- /dev/null
+++ b/2.x/spring-boot-package-war/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-package-war
+ 0.0.1-SNAPSHOT
+ war
+
+ spring-boot-package-war
+ Demo project for Spring Boot package war
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.3.6.RELEASE
+
+
+
+
+ UTF-8
+ 1.7
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-package-war/src/main/java/com/neo/Application.java b/2.x/spring-boot-package-war/src/main/java/com/neo/Application.java
new file mode 100644
index 000000000..6cda50c81
--- /dev/null
+++ b/2.x/spring-boot-package-war/src/main/java/com/neo/Application.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/2.x/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java b/2.x/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java
new file mode 100644
index 000000000..e57ead010
--- /dev/null
+++ b/2.x/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.web.SpringBootServletInitializer;
+
+/**
+ * Created by summer on 2017/5/8.
+ */
+public class ServletInitializer extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(Application.class);
+ }
+}
diff --git a/2.x/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java b/2.x/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java
new file mode 100644
index 000000000..c231fae49
--- /dev/null
+++ b/2.x/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloWorldController {
+
+ @RequestMapping("/hello")
+ public String index() {
+ return "Hello World xx";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-package-war/src/main/resources/application.properties b/2.x/spring-boot-package-war/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/2.x/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java b/2.x/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java
new file mode 100644
index 000000000..f35d76c7a
--- /dev/null
+++ b/2.x/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+public class ApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java b/2.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java
new file mode 100644
index 000000000..02133d7ef
--- /dev/null
+++ b/2.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java
@@ -0,0 +1,39 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = MockServletContext.class)
+@WebAppConfiguration
+public class HelloTests {
+
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/2.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java
new file mode 100644
index 000000000..423d57caa
--- /dev/null
+++ b/2.x/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java
@@ -0,0 +1,37 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = MockServletContext.class)
+@WebAppConfiguration
+public class HelloWorldControlerTests {
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-package/pom.xml b/2.x/spring-boot-package/pom.xml
new file mode 100644
index 000000000..58d3791cf
--- /dev/null
+++ b/2.x/spring-boot-package/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-package
+ 1.0.0
+ jar
+
+ spring-boot-package
+ Demo project for Spring Boot package war
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-package/src/main/java/com/neo/PackageApplication.java b/2.x/spring-boot-package/src/main/java/com/neo/PackageApplication.java
new file mode 100644
index 000000000..6611164fa
--- /dev/null
+++ b/2.x/spring-boot-package/src/main/java/com/neo/PackageApplication.java
@@ -0,0 +1,19 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class PackageApplication extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(PackageApplication.class);
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(PackageApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-package/src/main/java/com/neo/controller/HelloController.java b/2.x/spring-boot-package/src/main/java/com/neo/controller/HelloController.java
new file mode 100644
index 000000000..5e93f0dda
--- /dev/null
+++ b/2.x/spring-boot-package/src/main/java/com/neo/controller/HelloController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+
+ @RequestMapping("/hello")
+ public String index() {
+ return "Hello World";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-package/src/main/resources/application-dev.properties b/2.x/spring-boot-package/src/main/resources/application-dev.properties
new file mode 100644
index 000000000..c83a6aaa9
--- /dev/null
+++ b/2.x/spring-boot-package/src/main/resources/application-dev.properties
@@ -0,0 +1,2 @@
+info.app.name=spring-boot-test
+info.app.version= 1.0.0
\ No newline at end of file
diff --git a/2.x/spring-boot-package/src/main/resources/application-pro.properties b/2.x/spring-boot-package/src/main/resources/application-pro.properties
new file mode 100644
index 000000000..5bc6c5ce3
--- /dev/null
+++ b/2.x/spring-boot-package/src/main/resources/application-pro.properties
@@ -0,0 +1,2 @@
+info.app.name=spring-boot-pro
+info.app.version= 1.0.0
\ No newline at end of file
diff --git a/2.x/spring-boot-package/src/main/resources/application-test.properties b/2.x/spring-boot-package/src/main/resources/application-test.properties
new file mode 100644
index 000000000..995c6d213
--- /dev/null
+++ b/2.x/spring-boot-package/src/main/resources/application-test.properties
@@ -0,0 +1,2 @@
+info.app.name=spring-boot-uat
+info.app.version= 1.0.0
\ No newline at end of file
diff --git a/2.x/spring-boot-package/src/main/resources/application.properties b/2.x/spring-boot-package/src/main/resources/application.properties
new file mode 100644
index 000000000..bba9dfd9a
--- /dev/null
+++ b/2.x/spring-boot-package/src/main/resources/application.properties
@@ -0,0 +1,26 @@
+# \u9879\u76EEcontextPath\uFF0C\u4E00\u822C\u4E0D\u914D\u7F6E
+#server.servlet.context-path=/myspringboot
+# \u9519\u8BEF\u9875\uFF0C\u6307\u5B9A\u53D1\u751F\u9519\u8BEF\u65F6\uFF0C\u8DF3\u8F6C\u7684URL\u3002
+server.error.path=/error
+# \u670D\u52A1\u7AEF\u53E3
+server.port=8080
+# session\u6700\u5927\u8D85\u65F6\u65F6\u95F4(\u5206\u949F)\uFF0C\u9ED8\u8BA4\u4E3A30
+server.session-timeout=60
+# \u8BE5\u670D\u52A1\u7ED1\u5B9AIP\u5730\u5740\uFF0C\u542F\u52A8\u670D\u52A1\u5668\u65F6\u5982\u672C\u673A\u4E0D\u662F\u8BE5IP\u5730\u5740\u5219\u629B\u51FA\u5F02\u5E38\u542F\u52A8\u5931\u8D25\uFF0C\u53EA\u6709\u7279\u6B8A\u9700\u6C42\u7684\u60C5\u51B5\u4E0B\u624D\u914D\u7F6E
+#server.address=192.168.0.6
+
+# tomcat \u6700\u5927\u7EBF\u7A0B\u6570\uFF0C\u9ED8\u8BA4\u4E3A200
+server.tomcat.max-threads=600
+# tomcat\u7684URI\u7F16\u7801
+server.tomcat.uri-encoding=UTF-8
+# \u5B58\u653ETomcat\u7684\u65E5\u5FD7\u3001Dump\u7B49\u6587\u4EF6\u7684\u4E34\u65F6\u6587\u4EF6\u5939\uFF0C\u9ED8\u8BA4\u4E3A\u7CFB\u7EDF\u7684tmp\u6587\u4EF6\u5939
+server.tomcat.basedir=/tmp/log
+# \u6253\u5F00Tomcat\u7684Access\u65E5\u5FD7\uFF0C\u5E76\u53EF\u4EE5\u8BBE\u7F6E\u65E5\u5FD7\u683C\u5F0F
+#server.tomcat.access-log-enabled=true
+#server.tomcat.access-log-pattern=
+# accesslog\u76EE\u5F55\uFF0C\u9ED8\u8BA4\u5728basedir/logs
+#server.tomcat.accesslog.directory=
+# \u65E5\u5FD7\u6587\u4EF6\u76EE\u5F55
+logging.path=/tmp/log
+# \u65E5\u5FD7\u6587\u4EF6\u540D\u79F0\uFF0C\u9ED8\u8BA4\u4E3Aspring.log
+logging.file=myapp.log
\ No newline at end of file
diff --git a/2.x/spring-boot-package/src/test/java/com/neo/PackageApplicationTests.java b/2.x/spring-boot-package/src/test/java/com/neo/PackageApplicationTests.java
new file mode 100644
index 000000000..ff737b922
--- /dev/null
+++ b/2.x/spring-boot-package/src/test/java/com/neo/PackageApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 PackageApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-package/src/test/java/com/neo/controller/HelloTests.java b/2.x/spring-boot-package/src/test/java/com/neo/controller/HelloTests.java
new file mode 100644
index 000000000..149543930
--- /dev/null
+++ b/2.x/spring-boot-package/src/test/java/com/neo/controller/HelloTests.java
@@ -0,0 +1,36 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloTests {
+
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-package/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/2.x/spring-boot-package/src/test/java/com/neo/controller/HelloWorldControlerTests.java
new file mode 100644
index 000000000..d8b01a50d
--- /dev/null
+++ b/2.x/spring-boot-package/src/test/java/com/neo/controller/HelloWorldControlerTests.java
@@ -0,0 +1,34 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloWorldControlerTests {
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/pom.xml b/2.x/spring-boot-rabbitmq/pom.xml
new file mode 100644
index 000000000..a23b8581d
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-rabbitmq
+ 1.0.0
+ jar
+
+ spring-boot-rabbitmq
+ Demo project for Spring Boot and rabbitmq
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/RabbitMQApplication.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/RabbitMQApplication.java
new file mode 100644
index 000000000..15d177f39
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/RabbitMQApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class RabbitMQApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(RabbitMQApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/model/User.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..f4eec95e4
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/model/User.java
@@ -0,0 +1,37 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by summer on 2016/11/29.
+ */
+public class User implements Serializable{
+
+ private String name;
+
+ private String pass;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPass() {
+ return pass;
+ }
+
+ public void setPass(String pass) {
+ this.pass = pass;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "name='" + name + '\'' +
+ ", pass='" + pass + '\'' +
+ '}';
+ }
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/FanoutRabbitConfig.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/FanoutRabbitConfig.java
new file mode 100644
index 000000000..4fe21fa9f
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/FanoutRabbitConfig.java
@@ -0,0 +1,49 @@
+package com.neo.rabbit;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class FanoutRabbitConfig {
+
+ @Bean
+ public Queue AMessage() {
+ return new Queue("fanout.A");
+ }
+
+ @Bean
+ public Queue BMessage() {
+ return new Queue("fanout.B");
+ }
+
+ @Bean
+ public Queue CMessage() {
+ return new Queue("fanout.C");
+ }
+
+ @Bean
+ FanoutExchange fanoutExchange() {
+ return new FanoutExchange("fanoutExchange");
+ }
+
+ @Bean
+ Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange) {
+ return BindingBuilder.bind(AMessage).to(fanoutExchange);
+ }
+
+ @Bean
+ Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
+ return BindingBuilder.bind(BMessage).to(fanoutExchange);
+ }
+
+ @Bean
+ Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
+ return BindingBuilder.bind(CMessage).to(fanoutExchange);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/RabbitConfig.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/RabbitConfig.java
new file mode 100644
index 000000000..d5d649b5c
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/RabbitConfig.java
@@ -0,0 +1,27 @@
+package com.neo.rabbit;
+
+import org.springframework.amqp.core.Queue;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class RabbitConfig {
+
+ @Bean
+ public Queue helloQueue() {
+ return new Queue("hello");
+ }
+
+ @Bean
+ public Queue neoQueue() {
+ return new Queue("neo");
+ }
+
+ @Bean
+ public Queue objectQueue() {
+ return new Queue("object");
+ }
+
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/TopicRabbitConfig.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/TopicRabbitConfig.java
new file mode 100644
index 000000000..7bd2a096c
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/TopicRabbitConfig.java
@@ -0,0 +1,41 @@
+package com.neo.rabbit;
+
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class TopicRabbitConfig {
+
+ final static String message = "topic.message";
+ final static String messages = "topic.messages";
+
+ @Bean
+ public Queue queueMessage() {
+ return new Queue(TopicRabbitConfig.message);
+ }
+
+ @Bean
+ public Queue queueMessages() {
+ return new Queue(TopicRabbitConfig.messages);
+ }
+
+ @Bean
+ TopicExchange exchange() {
+ return new TopicExchange("topicExchange");
+ }
+
+ @Bean
+ Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
+ return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
+ }
+
+ @Bean
+ Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
+ return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
+ }
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverA.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverA.java
new file mode 100644
index 000000000..256de2eee
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverA.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "fanout.A")
+public class FanoutReceiverA {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("fanout Receiver A : " + message);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverB.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverB.java
new file mode 100644
index 000000000..a721da684
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverB.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "fanout.B")
+public class FanoutReceiverB {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("fanout Receiver B: " + message);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverC.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverC.java
new file mode 100644
index 000000000..aceef8b08
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutReceiverC.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "fanout.C")
+public class FanoutReceiverC {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("fanout Receiver C: " + message);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutSender.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutSender.java
new file mode 100644
index 000000000..2fa62d39c
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/fanout/FanoutSender.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.fanout;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class FanoutSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send() {
+ String context = "hi, fanout msg ";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("fanoutExchange","", context);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloReceiver.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloReceiver.java
new file mode 100644
index 000000000..2d59b1740
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloReceiver.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.hello;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+@RabbitListener(queues = "hello")
+public class HelloReceiver {
+
+ @RabbitHandler
+ public void process(String hello) {
+ System.out.println("Receiver : " + hello);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloSender.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloSender.java
new file mode 100644
index 000000000..05fc740ac
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/hello/HelloSender.java
@@ -0,0 +1,22 @@
+package com.neo.rabbit.hello;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class HelloSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send() {
+ String context = "hello " + new Date();
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("hello", context);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver1.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver1.java
new file mode 100644
index 000000000..c352fbeb5
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver1.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "neo")
+public class NeoReceiver1 {
+
+ @RabbitHandler
+ public void process(String neo) {
+ System.out.println("Receiver 1: " + neo);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver2.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver2.java
new file mode 100644
index 000000000..d7cbdd758
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoReceiver2.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "neo")
+public class NeoReceiver2 {
+
+ @RabbitHandler
+ public void process(String neo) {
+ System.out.println("Receiver 2: " + neo);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender.java
new file mode 100644
index 000000000..755918fb6
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NeoSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(int i) {
+ String context = "spirng boot neo queue"+" ****** "+i;
+ System.out.println("Sender1 : " + context);
+ this.rabbitTemplate.convertAndSend("neo", context);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender2.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender2.java
new file mode 100644
index 000000000..e34cce647
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/many/NeoSender2.java
@@ -0,0 +1,19 @@
+package com.neo.rabbit.many;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NeoSender2 {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(int i) {
+ String context = "spirng boot neo queue"+" ****** "+i;
+ System.out.println("Sender2 : " + context);
+ this.rabbitTemplate.convertAndSend("neo", context);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectReceiver.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectReceiver.java
new file mode 100644
index 000000000..b97f8a026
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectReceiver.java
@@ -0,0 +1,17 @@
+package com.neo.rabbit.object;
+
+import com.neo.model.User;
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "object")
+public class ObjectReceiver {
+
+ @RabbitHandler
+ public void process(User user) {
+ System.out.println("Receiver object : " + user);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectSender.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectSender.java
new file mode 100644
index 000000000..9c7aba927
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/object/ObjectSender.java
@@ -0,0 +1,21 @@
+package com.neo.rabbit.object;
+
+import com.neo.model.User;
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class ObjectSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(User user) {
+ System.out.println("Sender object: " + user.toString());
+ this.rabbitTemplate.convertAndSend("object", user);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver.java
new file mode 100644
index 000000000..14523941a
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.topic;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "topic.message")
+public class TopicReceiver {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("Topic Receiver1 : " + message);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver2.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver2.java
new file mode 100644
index 000000000..9ea81d7fe
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicReceiver2.java
@@ -0,0 +1,16 @@
+package com.neo.rabbit.topic;
+
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RabbitListener(queues = "topic.messages")
+public class TopicReceiver2 {
+
+ @RabbitHandler
+ public void process(String message) {
+ System.out.println("Topic Receiver2 : " + message);
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicSender.java b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicSender.java
new file mode 100644
index 000000000..8f17c34e3
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/java/com/neo/rabbit/topic/TopicSender.java
@@ -0,0 +1,33 @@
+package com.neo.rabbit.topic;
+
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class TopicSender {
+
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send() {
+ String context = "hi, i am message all";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("topicExchange", "topic.1", context);
+ }
+
+ public void send1() {
+ String context = "hi, i am message 1";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("topicExchange", "topic.message", context);
+ }
+
+ public void send2() {
+ String context = "hi, i am messages 2";
+ System.out.println("Sender : " + context);
+ this.rabbitTemplate.convertAndSend("topicExchange", "topic.messages", context);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/main/resources/application.properties b/2.x/spring-boot-rabbitmq/src/main/resources/application.properties
new file mode 100644
index 000000000..c43cab4b7
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+spring.application.name=spring-boot-rabbitmq
+
+spring.rabbitmq.host=192.168.0.56
+spring.rabbitmq.port=5672
+spring.rabbitmq.username=zzq
+spring.rabbitmq.password=zzq
diff --git a/2.x/spring-boot-rabbitmq/src/test/java/com/neo/RabbitMQApplicationTests.java b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/RabbitMQApplicationTests.java
new file mode 100644
index 000000000..2bec30988
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/RabbitMQApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 RabbitMQApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/FanoutTest.java b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/FanoutTest.java
new file mode 100644
index 000000000..d9ee0afd9
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/FanoutTest.java
@@ -0,0 +1,24 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.fanout.FanoutSender;
+import com.neo.rabbit.topic.TopicSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class FanoutTest {
+
+ @Autowired
+ private FanoutSender sender;
+
+ @Test
+ public void fanoutSender() throws Exception {
+ sender.send();
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/HelloTest.java b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/HelloTest.java
new file mode 100644
index 000000000..f790b0452
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/HelloTest.java
@@ -0,0 +1,23 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.hello.HelloSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloTest {
+
+ @Autowired
+ private HelloSender helloSender;
+
+ @Test
+ public void hello() throws Exception {
+ helloSender.send();
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ManyTest.java b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ManyTest.java
new file mode 100644
index 000000000..08c701cfd
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ManyTest.java
@@ -0,0 +1,35 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.many.NeoSender;
+import com.neo.rabbit.many.NeoSender2;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ManyTest {
+ @Autowired
+ private NeoSender neoSender;
+
+ @Autowired
+ private NeoSender2 neoSender2;
+
+ @Test
+ public void oneToMany() throws Exception {
+ for (int i=0;i<100;i++){
+ neoSender.send(i);
+ }
+ }
+
+ @Test
+ public void manyToMany() throws Exception {
+ for (int i=0;i<100;i++){
+ neoSender.send(i);
+ neoSender2.send(i);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ObjectTest.java b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ObjectTest.java
new file mode 100644
index 000000000..e36daf7ed
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/ObjectTest.java
@@ -0,0 +1,26 @@
+package com.neo.rabbitmq;
+
+import com.neo.model.User;
+import com.neo.rabbit.object.ObjectSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ObjectTest {
+
+ @Autowired
+ private ObjectSender sender;
+
+ @Test
+ public void sendOject() throws Exception {
+ User user=new User();
+ user.setName("neo");
+ user.setPass("123456");
+ sender.send(user);
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/TopicTest.java b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/TopicTest.java
new file mode 100644
index 000000000..d69a5b85e
--- /dev/null
+++ b/2.x/spring-boot-rabbitmq/src/test/java/com/neo/rabbitmq/TopicTest.java
@@ -0,0 +1,32 @@
+package com.neo.rabbitmq;
+
+import com.neo.rabbit.topic.TopicSender;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class TopicTest {
+
+ @Autowired
+ private TopicSender sender;
+
+ @Test
+ public void topic() throws Exception {
+ sender.send();
+ }
+
+ @Test
+ public void topic1() throws Exception {
+ sender.send1();
+ }
+
+ @Test
+ public void topic2() throws Exception {
+ sender.send2();
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-redis/pom.xml b/2.x/spring-boot-redis/pom.xml
new file mode 100644
index 000000000..3f836ab99
--- /dev/null
+++ b/2.x/spring-boot-redis/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-redis
+ 1.0.0-SNAPSHOT
+ jar
+
+ spring-boot-redis
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ org.apache.commons
+ commons-pool2
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.session
+ spring-session-data-redis
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-redis/src/main/java/com/neo/RedisApplication.java b/2.x/spring-boot-redis/src/main/java/com/neo/RedisApplication.java
new file mode 100644
index 000000000..9c41bedc0
--- /dev/null
+++ b/2.x/spring-boot-redis/src/main/java/com/neo/RedisApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class RedisApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(RedisApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-redis/src/main/java/com/neo/config/RedisConfig.java b/2.x/spring-boot-redis/src/main/java/com/neo/config/RedisConfig.java
new file mode 100644
index 000000000..f26748985
--- /dev/null
+++ b/2.x/spring-boot-redis/src/main/java/com/neo/config/RedisConfig.java
@@ -0,0 +1,34 @@
+package com.neo.config;
+
+import java.lang.reflect.Method;
+
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.core.RedisTemplate;
+
+
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport{
+
+ @Bean
+ public KeyGenerator keyGenerator() {
+ return new KeyGenerator() {
+ @Override
+ public Object generate(Object target, Method method, Object... params) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(target.getClass().getName());
+ sb.append(method.getName());
+ for (Object obj : params) {
+ sb.append(obj.toString());
+ }
+ return sb.toString();
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-redis/src/main/java/com/neo/config/SessionConfig.java b/2.x/spring-boot-redis/src/main/java/com/neo/config/SessionConfig.java
new file mode 100644
index 000000000..400f03fd7
--- /dev/null
+++ b/2.x/spring-boot-redis/src/main/java/com/neo/config/SessionConfig.java
@@ -0,0 +1,9 @@
+package com.neo.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+@Configuration
+@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
+public class SessionConfig {
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-redis/src/main/java/com/neo/model/User.java b/2.x/spring-boot-redis/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..045748877
--- /dev/null
+++ b/2.x/spring-boot-redis/src/main/java/com/neo/model/User.java
@@ -0,0 +1,88 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String password;
+ private String email;
+ private String nickname;
+ private String regTime;
+
+ public User() {
+ super();
+ }
+ public User(String email, String nickname, String password, String userName, String regTime) {
+ super();
+ this.email = email;
+ this.nickname = nickname;
+ this.password = password;
+ this.userName = userName;
+ this.regTime = regTime;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public String getRegTime() {
+ return regTime;
+ }
+
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "id=" + id +
+ ", userName='" + userName + '\'' +
+ ", password='" + password + '\'' +
+ ", email='" + email + '\'' +
+ ", nickname='" + nickname + '\'' +
+ ", regTime='" + regTime + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-redis/src/main/java/com/neo/web/UserController.java b/2.x/spring-boot-redis/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..0447fd1d6
--- /dev/null
+++ b/2.x/spring-boot-redis/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,33 @@
+package com.neo.web;
+
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.neo.model.User;
+
+import javax.servlet.http.HttpSession;
+import java.util.UUID;
+
+@RestController
+public class UserController {
+
+ @RequestMapping("/getUser")
+ @Cacheable(value="user-key")
+ public User getUser() {
+ User user=new User("aa@126.com", "aa", "aa123456", "aa","123");
+ System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
+ return user;
+ }
+
+
+ @RequestMapping("/uid")
+ String uid(HttpSession session) {
+ UUID uid = (UUID) session.getAttribute("uid");
+ if (uid == null) {
+ uid = UUID.randomUUID();
+ }
+ session.setAttribute("uid", uid);
+ return session.getId();
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-redis/src/main/resources/application.properties b/2.x/spring-boot-redis/src/main/resources/application.properties
new file mode 100644
index 000000000..2d4d7e89b
--- /dev/null
+++ b/2.x/spring-boot-redis/src/main/resources/application.properties
@@ -0,0 +1,17 @@
+# REDIS
+# Redis\u6570\u636E\u5E93\u7D22\u5F15\uFF08\u9ED8\u8BA4\u4E3A0\uFF09
+spring.redis.database=0
+# Redis\u670D\u52A1\u5668\u5730\u5740
+spring.redis.host=localhost
+# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u7AEF\u53E3
+spring.redis.port=6379
+# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u5BC6\u7801\uFF08\u9ED8\u8BA4\u4E3A\u7A7A\uFF09
+spring.redis.password=
+# \u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09 \u9ED8\u8BA4 8
+spring.redis.lettuce.pool.max-active=8
+# \u8FDE\u63A5\u6C60\u6700\u5927\u963B\u585E\u7B49\u5F85\u65F6\u95F4\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09 \u9ED8\u8BA4 -1
+spring.redis.lettuce.pool.max-wait=-1
+# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5 \u9ED8\u8BA4 8
+spring.redis.lettuce.pool.max-idle=8
+# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5 \u9ED8\u8BA4 0
+spring.redis.lettuce.pool.min-idle=0
diff --git a/2.x/spring-boot-redis/src/test/java/com/neo/RedisApplicationTests.java b/2.x/spring-boot-redis/src/test/java/com/neo/RedisApplicationTests.java
new file mode 100644
index 000000000..c92da71f7
--- /dev/null
+++ b/2.x/spring-boot-redis/src/test/java/com/neo/RedisApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class RedisApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello web");
+ }
+
+}
diff --git a/2.x/spring-boot-redis/src/test/java/com/neo/TestRedis.java b/2.x/spring-boot-redis/src/test/java/com/neo/TestRedis.java
new file mode 100644
index 000000000..fe8f86e5f
--- /dev/null
+++ b/2.x/spring-boot-redis/src/test/java/com/neo/TestRedis.java
@@ -0,0 +1,49 @@
+package com.neo;
+
+import com.neo.model.User;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.concurrent.TimeUnit;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class TestRedis {
+
+ @Autowired
+ private StringRedisTemplate stringRedisTemplate;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ @Test
+ public void test() throws Exception {
+ stringRedisTemplate.opsForValue().set("aaa", "111");
+ Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa"));
+ }
+
+ @Test
+ public void testObj() throws Exception {
+ User user=new User("aa@126.com", "aa", "aa123456", "aa","123");
+ ValueOperations operations=redisTemplate.opsForValue();
+ operations.set("com.neox", user);
+ operations.set("com.neo.f", user,1, TimeUnit.SECONDS);
+ Thread.sleep(1000);
+ //redisTemplate.delete("com.neo.f");
+ boolean exists=redisTemplate.hasKey("com.neo.f");
+ if(exists){
+ System.out.println("exists is true");
+ }else{
+ System.out.println("exists is false");
+ }
+ // Assert.assertEquals("aa", operations.get("com.neo.f").getUserName());
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-scheduler/pom.xml b/2.x/spring-boot-scheduler/pom.xml
new file mode 100644
index 000000000..38ad39399
--- /dev/null
+++ b/2.x/spring-boot-scheduler/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-scheduler
+ 1.0.0
+ jar
+
+ spring-boot-scheduler
+ Demo project for Spring Boot and scheduler
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-scheduler/src/main/java/com/neo/SchedulerApplication.java b/2.x/spring-boot-scheduler/src/main/java/com/neo/SchedulerApplication.java
new file mode 100644
index 000000000..1fd012d24
--- /dev/null
+++ b/2.x/spring-boot-scheduler/src/main/java/com/neo/SchedulerApplication.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableScheduling
+public class SchedulerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SchedulerApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-scheduler/src/main/java/com/neo/task/Scheduler2Task.java b/2.x/spring-boot-scheduler/src/main/java/com/neo/task/Scheduler2Task.java
new file mode 100644
index 000000000..7b59c9f2b
--- /dev/null
+++ b/2.x/spring-boot-scheduler/src/main/java/com/neo/task/Scheduler2Task.java
@@ -0,0 +1,23 @@
+package com.neo.task;
+
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by summer on 2016/12/1.
+ */
+
+@Component
+public class Scheduler2Task {
+
+ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
+
+ @Scheduled(fixedRate = 6000)
+ public void reportCurrentTime() {
+ System.out.println("现在时间:" + dateFormat.format(new Date()));
+ }
+
+}
diff --git a/2.x/spring-boot-scheduler/src/main/java/com/neo/task/SchedulerTask.java b/2.x/spring-boot-scheduler/src/main/java/com/neo/task/SchedulerTask.java
new file mode 100644
index 000000000..69885e3cc
--- /dev/null
+++ b/2.x/spring-boot-scheduler/src/main/java/com/neo/task/SchedulerTask.java
@@ -0,0 +1,22 @@
+package com.neo.task;
+
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * Created by summer on 2016/12/1.
+ */
+
+@Component
+public class SchedulerTask {
+
+ private int count=0;
+
+ @Scheduled(cron="*/6 * * * * ?")
+ private void process(){
+ System.out.println("this is scheduler task runing "+(count++));
+ }
+
+}
diff --git a/2.x/spring-boot-scheduler/src/main/resources/application.properties b/2.x/spring-boot-scheduler/src/main/resources/application.properties
new file mode 100644
index 000000000..8978a46f1
--- /dev/null
+++ b/2.x/spring-boot-scheduler/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.application.name=spirng-boot-scheduler
+
diff --git a/2.x/spring-boot-scheduler/src/test/java/com/neo/SchedulerApplicationTests.java b/2.x/spring-boot-scheduler/src/test/java/com/neo/SchedulerApplicationTests.java
new file mode 100644
index 000000000..9a627ba57
--- /dev/null
+++ b/2.x/spring-boot-scheduler/src/test/java/com/neo/SchedulerApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 SchedulerApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/2.x/spring-boot-shiro/pom.xml b/2.x/spring-boot-shiro/pom.xml
new file mode 100644
index 000000000..256443b33
--- /dev/null
+++ b/2.x/spring-boot-shiro/pom.xml
@@ -0,0 +1,79 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-shiro
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-shiro
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ net.sourceforge.nekohtml
+ nekohtml
+ 1.9.22
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.apache.shiro
+ shiro-spring
+ 1.7.2
+
+
+ mysql
+ mysql-connector-java
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/ShiroApplication.java b/2.x/spring-boot-shiro/src/main/java/com/neo/ShiroApplication.java
new file mode 100644
index 000000000..ee576763f
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/ShiroApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ShiroApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ShiroApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/config/MyShiroRealm.java b/2.x/spring-boot-shiro/src/main/java/com/neo/config/MyShiroRealm.java
new file mode 100644
index 000000000..f7d28c553
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/config/MyShiroRealm.java
@@ -0,0 +1,60 @@
+package com.neo.config;
+
+import com.neo.model.SysPermission;
+import com.neo.model.SysRole;
+import com.neo.model.UserInfo;
+import com.neo.sevice.UserInfoService;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.util.ByteSource;
+
+import javax.annotation.Resource;
+
+public class MyShiroRealm extends AuthorizingRealm {
+ @Resource
+ private UserInfoService userInfoService;
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+ System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
+ SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
+ UserInfo userInfo = (UserInfo)principals.getPrimaryPrincipal();
+ for(SysRole role:userInfo.getRoleList()){
+ authorizationInfo.addRole(role.getRole());
+ for(SysPermission p:role.getPermissions()){
+ authorizationInfo.addStringPermission(p.getPermission());
+ }
+ }
+ return authorizationInfo;
+ }
+
+ /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
+ throws AuthenticationException {
+ System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
+ //获取用户的输入的账号.
+ String username = (String)token.getPrincipal();
+ System.out.println(token.getCredentials());
+ //通过username从数据库中查找 User对象,如果找到,没找到.
+ //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
+ UserInfo userInfo = userInfoService.findByUsername(username);
+ System.out.println("----->>userInfo="+userInfo);
+ if(userInfo == null){
+ return null;
+ }
+ SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
+ userInfo, //用户名
+ userInfo.getPassword(), //密码
+ ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt
+ getName() //realm name
+ );
+ return authenticationInfo;
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/config/ShiroConfig.java b/2.x/spring-boot-shiro/src/main/java/com/neo/config/ShiroConfig.java
new file mode 100644
index 000000000..00f524b24
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/config/ShiroConfig.java
@@ -0,0 +1,98 @@
+package com.neo.config;
+
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+@Configuration
+public class ShiroConfig {
+ @Bean
+ public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
+ System.out.println("ShiroConfiguration.shirFilter()");
+ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
+ shiroFilterFactoryBean.setSecurityManager(securityManager);
+ //拦截器.
+ Map filterChainDefinitionMap = new LinkedHashMap();
+ // 配置不会被拦截的链接 顺序判断
+ filterChainDefinitionMap.put("/static/**", "anon");
+ //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
+ filterChainDefinitionMap.put("/logout", "logout");
+ //:这是一个坑呢,一不小心代码就不好使了;
+ //
+ filterChainDefinitionMap.put("/**", "authc");
+ // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
+ shiroFilterFactoryBean.setLoginUrl("/login");
+ // 登录成功后要跳转的链接
+ shiroFilterFactoryBean.setSuccessUrl("/index");
+
+ //未授权界面;
+ shiroFilterFactoryBean.setUnauthorizedUrl("/403");
+ shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
+ return shiroFilterFactoryBean;
+ }
+
+ /**
+ * 凭证匹配器
+ * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
+ * )
+ * @return
+ */
+ @Bean
+ public HashedCredentialsMatcher hashedCredentialsMatcher(){
+ HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
+ hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
+ hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
+ return hashedCredentialsMatcher;
+ }
+
+ @Bean
+ public MyShiroRealm myShiroRealm(){
+ MyShiroRealm myShiroRealm = new MyShiroRealm();
+ myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
+ return myShiroRealm;
+ }
+
+
+ @Bean
+ public SecurityManager securityManager(){
+ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+ securityManager.setRealm(myShiroRealm());
+ return securityManager;
+ }
+
+ /**
+ * 开启shiro aop注解支持.
+ * 使用代理方式;所以需要开启代码支持;
+ * @param securityManager
+ * @return
+ */
+ @Bean
+ public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
+ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
+ authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
+ return authorizationAttributeSourceAdvisor;
+ }
+
+ @Bean(name="simpleMappingExceptionResolver")
+ public SimpleMappingExceptionResolver
+ createSimpleMappingExceptionResolver() {
+ SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
+ Properties mappings = new Properties();
+ mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
+ mappings.setProperty("UnauthorizedException","403");
+ r.setExceptionMappings(mappings); // None by default
+ r.setDefaultErrorView("error"); // No default
+ r.setExceptionAttribute("ex"); // Default is "exception"
+ //r.setWarnLogCategory("example.MvcLogger"); // No default
+ return r;
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/dao/UserInfoDao.java b/2.x/spring-boot-shiro/src/main/java/com/neo/dao/UserInfoDao.java
new file mode 100644
index 000000000..dfd52c3dc
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/dao/UserInfoDao.java
@@ -0,0 +1,9 @@
+package com.neo.dao;
+
+import com.neo.model.UserInfo;
+import org.springframework.data.repository.CrudRepository;
+
+public interface UserInfoDao extends CrudRepository {
+ /**通过username查找用户信息;*/
+ public UserInfo findByUsername(String username);
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/model/SysPermission.java b/2.x/spring-boot-shiro/src/main/java/com/neo/model/SysPermission.java
new file mode 100644
index 000000000..b603d521c
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/model/SysPermission.java
@@ -0,0 +1,94 @@
+package com.neo.model;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.List;
+
+@Entity
+public class SysPermission implements Serializable {
+ @Id@GeneratedValue
+ private Integer id;//主键.
+ private String name;//名称.
+ @Column(columnDefinition="enum('menu','button')")
+ private String resourceType;//资源类型,[menu|button]
+ private String url;//资源路径.
+ private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
+ private Long parentId; //父编号
+ private String parentIds; //父编号列表
+ private Boolean available = Boolean.FALSE;
+ @ManyToMany
+ @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
+ private List roles;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ public void setResourceType(String resourceType) {
+ this.resourceType = resourceType;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getPermission() {
+ return permission;
+ }
+
+ public void setPermission(String permission) {
+ this.permission = permission;
+ }
+
+ public Long getParentId() {
+ return parentId;
+ }
+
+ public void setParentId(Long parentId) {
+ this.parentId = parentId;
+ }
+
+ public String getParentIds() {
+ return parentIds;
+ }
+
+ public void setParentIds(String parentIds) {
+ this.parentIds = parentIds;
+ }
+
+ public Boolean getAvailable() {
+ return available;
+ }
+
+ public void setAvailable(Boolean available) {
+ this.available = available;
+ }
+
+ public List getRoles() {
+ return roles;
+ }
+
+ public void setRoles(List roles) {
+ this.roles = roles;
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/model/SysRole.java b/2.x/spring-boot-shiro/src/main/java/com/neo/model/SysRole.java
new file mode 100644
index 000000000..e22131a44
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/model/SysRole.java
@@ -0,0 +1,71 @@
+package com.neo.model;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Entity
+public class SysRole {
+ @Id@GeneratedValue
+ private Integer id; // 编号
+ private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:
+ private String description; // 角色描述,UI界面显示使用
+ private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户
+
+ //角色 -- 权限关系:多对多关系;
+ @ManyToMany(fetch= FetchType.EAGER)
+ @JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
+ private List permissions;
+
+ // 用户 - 角色关系定义;
+ @ManyToMany
+ @JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="uid")})
+ private List userInfos;// 一个角色对应多个用户
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Boolean getAvailable() {
+ return available;
+ }
+
+ public void setAvailable(Boolean available) {
+ this.available = available;
+ }
+
+ public List getPermissions() {
+ return permissions;
+ }
+
+ public void setPermissions(List permissions) {
+ this.permissions = permissions;
+ }
+
+ public List getUserInfos() {
+ return userInfos;
+ }
+
+ public void setUserInfos(List userInfos) {
+ this.userInfos = userInfos;
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/model/UserInfo.java b/2.x/spring-boot-shiro/src/main/java/com/neo/model/UserInfo.java
new file mode 100644
index 000000000..d23087686
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/model/UserInfo.java
@@ -0,0 +1,86 @@
+package com.neo.model;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.List;
+
+@Entity
+public class UserInfo implements Serializable {
+ @Id
+ @GeneratedValue
+ private Integer uid;
+ @Column(unique =true)
+ private String username;//帐号
+ private String name;//名称(昵称或者真实姓名,不同系统不同定义)
+ private String password; //密码;
+ private String salt;//加密密码的盐
+ private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.
+ @ManyToMany(fetch= FetchType.EAGER)//立即从数据库中进行加载数据;
+ @JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
+ private List roleList;// 一个用户具有多个角色
+
+ public Integer getUid() {
+ return uid;
+ }
+
+ public void setUid(Integer uid) {
+ this.uid = uid;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getSalt() {
+ return salt;
+ }
+
+ public void setSalt(String salt) {
+ this.salt = salt;
+ }
+
+ public byte getState() {
+ return state;
+ }
+
+ public void setState(byte state) {
+ this.state = state;
+ }
+
+ public List getRoleList() {
+ return roleList;
+ }
+
+ public void setRoleList(List roleList) {
+ this.roleList = roleList;
+ }
+
+ /**
+ * 密码盐.
+ * @return
+ */
+ public String getCredentialsSalt(){
+ return this.username+this.salt;
+ }
+ //重新对盐重新进行了定义,用户名+salt,这样就更加不容易被破解
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/sevice/UserInfoService.java b/2.x/spring-boot-shiro/src/main/java/com/neo/sevice/UserInfoService.java
new file mode 100644
index 000000000..b2bc0cb23
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/sevice/UserInfoService.java
@@ -0,0 +1,8 @@
+package com.neo.sevice;
+
+import com.neo.model.UserInfo;
+
+public interface UserInfoService {
+ /**通过username查找用户信息;*/
+ public UserInfo findByUsername(String username);
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/sevice/impl/UserInfoServiceImpl.java b/2.x/spring-boot-shiro/src/main/java/com/neo/sevice/impl/UserInfoServiceImpl.java
new file mode 100644
index 000000000..d63e4f7d0
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/sevice/impl/UserInfoServiceImpl.java
@@ -0,0 +1,19 @@
+package com.neo.sevice.impl;
+
+import com.neo.dao.UserInfoDao;
+import com.neo.model.UserInfo;
+import com.neo.sevice.UserInfoService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class UserInfoServiceImpl implements UserInfoService {
+ @Resource
+ private UserInfoDao userInfoDao;
+ @Override
+ public UserInfo findByUsername(String username) {
+ System.out.println("UserInfoServiceImpl.findByUsername()");
+ return userInfoDao.findByUsername(username);
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/web/HomeController.java b/2.x/spring-boot-shiro/src/main/java/com/neo/web/HomeController.java
new file mode 100644
index 000000000..d1c069694
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/web/HomeController.java
@@ -0,0 +1,52 @@
+package com.neo.web;
+
+import org.apache.shiro.authc.IncorrectCredentialsException;
+import org.apache.shiro.authc.UnknownAccountException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+@Controller
+public class HomeController {
+ @RequestMapping({"/","/index"})
+ public String index(){
+ return"/index";
+ }
+
+ @RequestMapping("/login")
+ public String login(HttpServletRequest request, Map map) throws Exception{
+ System.out.println("HomeController.login()");
+ // 登录失败从request中获取shiro处理的异常信息。
+ // shiroLoginFailure:就是shiro异常类的全类名.
+ String exception = (String) request.getAttribute("shiroLoginFailure");
+ System.out.println("exception=" + exception);
+ String msg = "";
+ if (exception != null) {
+ if (UnknownAccountException.class.getName().equals(exception)) {
+ System.out.println("UnknownAccountException -- > 账号不存在:");
+ msg = "UnknownAccountException -- > 账号不存在:";
+ } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
+ System.out.println("IncorrectCredentialsException -- > 密码不正确:");
+ msg = "IncorrectCredentialsException -- > 密码不正确:";
+ } else if ("kaptchaValidateFailed".equals(exception)) {
+ System.out.println("kaptchaValidateFailed -- > 验证码错误");
+ msg = "kaptchaValidateFailed -- > 验证码错误";
+ } else {
+ msg = "else >> "+exception;
+ System.out.println("else -- >" + exception);
+ }
+ }
+ map.put("msg", msg);
+ // 此方法不处理登录成功,由shiro进行处理
+ return "/login";
+ }
+
+ @RequestMapping("/403")
+ public String unauthorizedRole(){
+ System.out.println("------没有权限-------");
+ return "403";
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/java/com/neo/web/UserInfoController.java b/2.x/spring-boot-shiro/src/main/java/com/neo/web/UserInfoController.java
new file mode 100644
index 000000000..4e8bde77a
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/java/com/neo/web/UserInfoController.java
@@ -0,0 +1,40 @@
+package com.neo.web;
+
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+@RequestMapping("/userInfo")
+public class UserInfoController {
+
+ /**
+ * 用户查询.
+ * @return
+ */
+ @RequestMapping("/userList")
+ @RequiresPermissions("userInfo:view")//权限管理;
+ public String userInfo(){
+ return "userInfo";
+ }
+
+ /**
+ * 用户添加;
+ * @return
+ */
+ @RequestMapping("/userAdd")
+ @RequiresPermissions("userInfo:add")//权限管理;
+ public String userInfoAdd(){
+ return "userInfoAdd";
+ }
+
+ /**
+ * 用户删除;
+ * @return
+ */
+ @RequestMapping("/userDel")
+ @RequiresPermissions("userInfo:del")//权限管理;
+ public String userDel(){
+ return "userInfoDel";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/application.yml b/2.x/spring-boot-shiro/src/main/resources/application.yml
new file mode 100644
index 000000000..c34ffa012
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/application.yml
@@ -0,0 +1,21 @@
+spring:
+ datasource:
+ url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+ username: root
+ password: root
+ #schema: database/import.sql
+ #sql-script-encoding: utf-8
+ driver-class-name: com.mysql.cj.jdbc.Driver
+
+ jpa:
+ database: mysql
+ show-sql: true
+ hibernate:
+ ddl-auto: update
+ properties:
+ hibernate:
+ dialect: org.hibernate.dialect.MySQL5Dialect
+
+ thymeleaf:
+ cache: false
+ mode: HTML
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/database/import.sql b/2.x/spring-boot-shiro/src/main/resources/database/import.sql
new file mode 100644
index 000000000..73a7f02a0
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/database/import.sql
@@ -0,0 +1,12 @@
+INSERT INTO `user_info` (`uid`,`username`,`name`,`password`,`salt`,`state`) VALUES ('1', 'admin', '管理员', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', 0);
+INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (1,0,'用户管理',0,'0/','userInfo:view','menu','userInfo/userList');
+INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (2,0,'用户添加',1,'0/1','userInfo:add','button','userInfo/userAdd');
+INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (3,0,'用户删除',1,'0/1','userInfo:del','button','userInfo/userDel');
+INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (1,0,'管理员','admin');
+INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (2,0,'VIP会员','vip');
+INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (3,1,'test','test');
+INSERT INTO `sys_role_permission` VALUES ('1', '1');
+INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (1,1);
+INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (2,1);
+INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (3,2);
+INSERT INTO `sys_user_role` (`role_id`,`uid`) VALUES (1,1);
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/templates/403.html b/2.x/spring-boot-shiro/src/main/resources/templates/403.html
new file mode 100644
index 000000000..97a10975c
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/templates/403.html
@@ -0,0 +1,10 @@
+
+
+
+
+ 403
+
+
+403没有权限
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/templates/index.html b/2.x/spring-boot-shiro/src/main/resources/templates/index.html
new file mode 100644
index 000000000..088725ce7
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/templates/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+ index
+
+
+index
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/templates/login.html b/2.x/spring-boot-shiro/src/main/resources/templates/login.html
new file mode 100644
index 000000000..07ca33195
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/templates/login.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Login
+
+
+错误信息:
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/templates/userInfo.html b/2.x/spring-boot-shiro/src/main/resources/templates/userInfo.html
new file mode 100644
index 000000000..f835b3fc9
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/templates/userInfo.html
@@ -0,0 +1,10 @@
+
+
+
+
+ UserInfo
+
+
+用户查询界面
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/templates/userInfoAdd.html b/2.x/spring-boot-shiro/src/main/resources/templates/userInfoAdd.html
new file mode 100644
index 000000000..0716e44ff
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/templates/userInfoAdd.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Add
+
+
+用户添加界面
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/main/resources/templates/userInfoDel.html b/2.x/spring-boot-shiro/src/main/resources/templates/userInfoDel.html
new file mode 100644
index 000000000..031e00949
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/main/resources/templates/userInfoDel.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Del
+
+
+用户删除界面
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-shiro/src/test/java/com/neo/ShiroApplicationTests.java b/2.x/spring-boot-shiro/src/test/java/com/neo/ShiroApplicationTests.java
new file mode 100644
index 000000000..fd8a415ef
--- /dev/null
+++ b/2.x/spring-boot-shiro/src/test/java/com/neo/ShiroApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 ShiroApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-swagger/pom.xml b/2.x/spring-boot-swagger/pom.xml
new file mode 100644
index 000000000..d001164db
--- /dev/null
+++ b/2.x/spring-boot-swagger/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+ spring-boot-swagger
+ Spring Boot swagger Sample
+ Spring Boot swagger Sample
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.9.2
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/SwaggerApplication.java b/2.x/spring-boot-swagger/src/main/java/com/neo/SwaggerApplication.java
new file mode 100644
index 000000000..7f12e1bd1
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/SwaggerApplication.java
@@ -0,0 +1,15 @@
+
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+
+@SpringBootApplication
+public class SwaggerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SwaggerApplication.class, args);
+ }
+
+}
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/config/BaseResult.java b/2.x/spring-boot-swagger/src/main/java/com/neo/config/BaseResult.java
new file mode 100644
index 000000000..4e3363fff
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/config/BaseResult.java
@@ -0,0 +1,112 @@
+package com.neo.config;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 通用响应对象
+ */
+@ApiModel(description = "响应对象")
+public class BaseResult {
+ private static final int SUCCESS_CODE = 0;
+ private static final String SUCCESS_MESSAGE = "成功";
+
+ @ApiModelProperty(value = "响应码", name = "code", required = true, example = "" + SUCCESS_CODE)
+ private int code;
+
+ @ApiModelProperty(value = "响应消息", name = "msg", required = true, example = SUCCESS_MESSAGE)
+ private String msg;
+
+ @ApiModelProperty(value = "响应数据", name = "data")
+ private T data;
+
+ private BaseResult(int code, String msg, T data) {
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ private BaseResult() {
+ this(SUCCESS_CODE, SUCCESS_MESSAGE);
+ }
+
+ private BaseResult(int code, String msg) {
+ this(code, msg, null);
+ }
+
+ private BaseResult(T data) {
+ this(SUCCESS_CODE, SUCCESS_MESSAGE, data);
+ }
+
+ public static BaseResult success() {
+ return new BaseResult<>();
+ }
+
+ public static BaseResult successWithData(T data) {
+ return new BaseResult<>(data);
+ }
+
+ public static BaseResult failWithCodeAndMsg(int code, String msg) {
+ return new BaseResult<>(code, msg, null);
+ }
+
+ public static BaseResult buildWithParam(ResponseParam param) {
+ return new BaseResult<>(param.getCode(), param.getMsg(), null);
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+
+
+ public static class ResponseParam {
+ private int code;
+ private String msg;
+
+ private ResponseParam(int code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ public static ResponseParam buildParam(int code, String msg) {
+ return new ResponseParam(code, msg);
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+ }
+}
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/config/SwaggerConfig.java b/2.x/spring-boot-swagger/src/main/java/com/neo/config/SwaggerConfig.java
new file mode 100644
index 000000000..babb224a7
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/config/SwaggerConfig.java
@@ -0,0 +1,39 @@
+package com.neo.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(apiInfo())
+ .select()
+ // 自行修改为自己的包路径
+ .apis(RequestHandlerSelectors.basePackage("com.neo.controller"))
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("客户管理")
+ .description("客户管理中心 API 1.0 操作文档")
+ //服务条款网址
+ .termsOfServiceUrl("http://www.ityouknow.com/")
+ .version("1.0")
+ .contact(new Contact("纯洁的微笑", "http://www.ityouknow.com/", "ityouknow@126.com"))
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/controller/MessageController.java b/2.x/spring-boot-swagger/src/main/java/com/neo/controller/MessageController.java
new file mode 100644
index 000000000..f4ee8b806
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/controller/MessageController.java
@@ -0,0 +1,85 @@
+
+package com.neo.controller;
+
+import com.neo.config.BaseResult;
+import com.neo.model.Message;
+import com.neo.repository.MessageRepository;
+import io.swagger.annotations.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Api(value = "消息", description = "消息操作 API", position = 100, protocols = "http")
+@RestController
+@RequestMapping("/")
+public class MessageController {
+
+ @Autowired
+ private MessageRepository messageRepository;
+
+ @ApiOperation(
+ value = "消息列表",
+ notes = "完整的消息内容列表",
+ produces="application/json, application/xml",
+ consumes="application/json, application/xml",
+ response = List.class)
+ @GetMapping(value = "messages")
+ public List list() {
+ List messages = this.messageRepository.findAll();
+ return messages;
+ }
+
+ @ApiOperation(
+ value = "添加消息",
+ notes = "根据参数创建消息"
+ )
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "消息 ID", required = true, dataType = "Long", paramType = "query"),
+ @ApiImplicitParam(name = "text", value = "正文", required = true, dataType = "String", paramType = "query"),
+ @ApiImplicitParam(name = "summary", value = "摘要", required = false, dataType = "String", paramType = "query"),
+ })
+ @PostMapping(value = "message")
+ public Message create(Message message) {
+ System.out.println("message===="+message.toString());
+ message = this.messageRepository.save(message);
+ return message;
+ }
+
+ @ApiOperation(
+ value = "修改消息",
+ notes = "根据参数修改消息"
+ )
+ @PutMapping(value = "message")
+ @ApiResponses({
+ @ApiResponse(code = 100, message = "请求参数有误"),
+ @ApiResponse(code = 101, message = "未授权"),
+ @ApiResponse(code = 103, message = "禁止访问"),
+ @ApiResponse(code = 104, message = "请求路径不存在"),
+ @ApiResponse(code = 200, message = "服务器内部错误")
+ })
+ public Message modify(Message message) {
+ Message messageResult=this.messageRepository.update(message);
+ return messageResult;
+ }
+
+ @PatchMapping(value="/message/text")
+ public BaseResult patch(Message message) {
+ Message messageResult=this.messageRepository.updateText(message);
+ return BaseResult.successWithData(messageResult);
+ }
+
+ @GetMapping(value = "message/{id}")
+ public Message get(@PathVariable Long id) {
+ Message message = this.messageRepository.findMessage(id);
+ return message;
+ }
+
+ @DeleteMapping(value = "message/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ this.messageRepository.deleteMessage(id);
+ }
+
+
+
+}
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/controller/UserController.java b/2.x/spring-boot-swagger/src/main/java/com/neo/controller/UserController.java
new file mode 100644
index 000000000..74723d09d
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/controller/UserController.java
@@ -0,0 +1,76 @@
+package com.neo.controller;
+
+import com.neo.config.BaseResult;
+import com.neo.model.User;
+import io.swagger.annotations.*;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.*;
+
+
+@Api(value = "用户管理", description = "用户管理API", position = 100, protocols = "http")
+@RestController
+@RequestMapping(value = "/user")
+public class UserController {
+ static Map users = Collections.synchronizedMap(new HashMap<>());
+
+ @ApiOperation(value = "获取用户列表", notes = "查询用户列表")
+ @RequestMapping(value = {""}, method = RequestMethod.GET)
+ @ApiResponses({
+ @ApiResponse(code = 100, message = "异常数据")
+ })
+ public List getUserList() {
+ return new ArrayList<>(users.values());
+ }
+
+ @ApiOperation(value = "创建用户", notes = "根据User对象创建用户")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "query"),
+ @ApiImplicitParam(name = "name", value = "用户名", required = true, dataType = "String", paramType = "query"),
+ @ApiImplicitParam(name = "age", value = "年龄", required = true, dataType = "String", paramType = "query"),
+ @ApiImplicitParam(name = "ipAddr", value = "ip哟", required = false, dataType = "String", paramType = "query")
+ })
+ @RequestMapping(value = "", method = RequestMethod.POST)
+ public BaseResult postUser(@ApiIgnore User user) {
+ users.put(user.getId(), user);
+ return BaseResult.successWithData(user);
+ }
+
+ @ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息")
+ @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path")
+ @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+ public User getUser(@PathVariable Long id) {
+ return users.get(id);
+ }
+
+ @ApiOperation(value = "更新用户信息", notes = "根据用户ID更新信息")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "query"),
+ @ApiImplicitParam(name = "name", value = "用户名", required = true, dataType = "String", paramType = "query"),
+ @ApiImplicitParam(name = "age", value = "年龄", required = true, dataType = "String", paramType = "query")
+ })
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ public BaseResult putUser(@PathVariable Long id, @ApiIgnore User user) {
+ User u = users.get(id);
+ u.setName(user.getName());
+ u.setAge(user.getAge());
+ users.put(id, u);
+ return BaseResult.successWithData(u);
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+ public String deleteUser(@PathVariable Long id) {
+ users.remove(id);
+ return "success";
+ }
+
+ @RequestMapping(value = "/ignoreMe/{id}", method = RequestMethod.DELETE)
+ public String ignoreMe(@PathVariable Long id) {
+ users.remove(id);
+ return "success";
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/model/Message.java b/2.x/spring-boot-swagger/src/main/java/com/neo/model/Message.java
new file mode 100644
index 000000000..c218fffd9
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/model/Message.java
@@ -0,0 +1,60 @@
+package com.neo.model;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import javax.validation.constraints.NotEmpty;
+
+
+public class Message {
+ private Long id;
+ @ApiModelProperty(value = "消息体")
+ private String text;
+ @ApiModelProperty(value = "消息总结")
+ private String summary;
+ private Date createDate;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Date getCreateDate() {
+ return createDate;
+ }
+
+ public void setCreateDate(Date createDate) {
+ this.createDate = createDate;
+ }
+
+ public String getText() {
+ return this.text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public String getSummary() {
+ return this.summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ @Override
+ public String toString() {
+ return "Message{" +
+ "id=" + id +
+ ", text='" + text + '\'' +
+ ", summary='" + summary + '\'' +
+ ", createDate=" + createDate +
+ '}';
+ }
+}
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/model/User.java b/2.x/spring-boot-swagger/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..fde335a7d
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/model/User.java
@@ -0,0 +1,31 @@
+package com.neo.model;
+
+public class User {
+ private Long id;
+ private String name;
+ private int age;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+}
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/repository/InMemoryMessageRepository.java b/2.x/spring-boot-swagger/src/main/java/com/neo/repository/InMemoryMessageRepository.java
new file mode 100644
index 000000000..c550ebb50
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/repository/InMemoryMessageRepository.java
@@ -0,0 +1,59 @@
+package com.neo.repository;
+
+import com.neo.model.Message;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+@Service("messageRepository")
+public class InMemoryMessageRepository implements MessageRepository {
+
+ private static AtomicLong counter = new AtomicLong();
+ private final ConcurrentMap messages = new ConcurrentHashMap<>();
+
+ @Override
+ public List findAll() {
+ List messages = new ArrayList(this.messages.values());
+ return messages;
+ }
+
+ @Override
+ public Message save(Message message) {
+ Long id = message.getId();
+ if (id == null) {
+ id = counter.incrementAndGet();
+ message.setId(id);
+ }
+ this.messages.put(id, message);
+ return message;
+ }
+
+ @Override
+ public Message update(Message message) {
+ this.messages.put(message.getId(), message);
+ return message;
+ }
+
+ @Override
+ public Message updateText(Message message) {
+ Message msg=this.messages.get(message.getId());
+ msg.setText(message.getText());
+ this.messages.put(msg.getId(), msg);
+ return msg;
+ }
+
+ @Override
+ public Message findMessage(Long id) {
+ return this.messages.get(id);
+ }
+
+ @Override
+ public void deleteMessage(Long id) {
+ this.messages.remove(id);
+ }
+
+}
diff --git a/2.x/spring-boot-swagger/src/main/java/com/neo/repository/MessageRepository.java b/2.x/spring-boot-swagger/src/main/java/com/neo/repository/MessageRepository.java
new file mode 100644
index 000000000..99549b5c3
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/java/com/neo/repository/MessageRepository.java
@@ -0,0 +1,22 @@
+
+package com.neo.repository;
+
+import com.neo.model.Message;
+
+import java.util.List;
+
+public interface MessageRepository {
+
+ List findAll();
+
+ Message save(Message message);
+
+ Message update(Message message);
+
+ Message updateText(Message message);
+
+ Message findMessage(Long id);
+
+ void deleteMessage(Long id);
+
+}
diff --git a/2.x/spring-boot-swagger/src/main/resources/application.properties b/2.x/spring-boot-swagger/src/main/resources/application.properties
new file mode 100644
index 000000000..a942fc84d
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/resources/application.properties
@@ -0,0 +1 @@
+logging.level.io.swagger.models.parameters.AbstractSerializableParameter=error
\ No newline at end of file
diff --git a/2.x/spring-boot-swagger/src/main/resources/logback.xml b/2.x/spring-boot-swagger/src/main/resources/logback.xml
new file mode 100644
index 000000000..620db4a2a
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/main/resources/logback.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-swagger/src/test/java/com/neo/SwaggerApplicationTests.java b/2.x/spring-boot-swagger/src/test/java/com/neo/SwaggerApplicationTests.java
new file mode 100644
index 000000000..8b6b178c0
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/test/java/com/neo/SwaggerApplicationTests.java
@@ -0,0 +1,14 @@
+
+package com.neo;
+
+
+
+import org.junit.Test;
+
+public class SwaggerApplicationTests {
+
+ @Test
+ public void test() {
+ }
+
+}
diff --git a/2.x/spring-boot-swagger/src/test/java/com/neo/web/MessageControllerTest.java b/2.x/spring-boot-swagger/src/test/java/com/neo/web/MessageControllerTest.java
new file mode 100644
index 000000000..0aead737a
--- /dev/null
+++ b/2.x/spring-boot-swagger/src/test/java/com/neo/web/MessageControllerTest.java
@@ -0,0 +1,105 @@
+package com.neo.web;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MessageControllerTest {
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
+ saveMessages();
+ }
+
+ @Test
+ public void saveMessage() throws Exception {
+ final MultiValueMap params = new LinkedMultiValueMap<>();
+ params.add("text", "text");
+ params.add("summary", "summary");
+ String mvcResult= mockMvc.perform(MockMvcRequestBuilders.post("/message")
+ .params(params)).andReturn().getResponse().getContentAsString();
+ System.out.println("Result === "+mvcResult);
+ }
+
+ @Test
+ public void getAllMessages() throws Exception {
+ String mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/messages"))
+ .andReturn().getResponse().getContentAsString();
+ System.out.println("Result === "+mvcResult);
+ }
+
+ @Test
+ public void getMessage() throws Exception {
+ String mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/message/6"))
+ .andReturn().getResponse().getContentAsString();
+ System.out.println("Result === "+mvcResult);
+ }
+
+ @Test
+ public void modifyMessage() throws Exception {
+ final MultiValueMap params = new LinkedMultiValueMap<>();
+ params.add("id", "6");
+ params.add("text", "text");
+ params.add("summary", "summary");
+ String mvcResult= mockMvc.perform(MockMvcRequestBuilders.put("/message").params(params))
+ .andReturn().getResponse().getContentAsString();
+ System.out.println("Result === "+mvcResult);
+ }
+
+ @Test
+ public void patchMessage() throws Exception {
+ final MultiValueMap params = new LinkedMultiValueMap<>();
+ params.add("id", "6");
+ params.add("text", "text");
+ String mvcResult= mockMvc.perform(MockMvcRequestBuilders.patch("/message/text").params(params))
+ .andReturn().getResponse().getContentAsString();
+ System.out.println("Result === "+mvcResult);
+ }
+
+ @Test
+ public void deleteMessage() throws Exception {
+ mockMvc.perform(MockMvcRequestBuilders.delete("/message/6"))
+ .andReturn();
+ String mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/messages"))
+ .andReturn().getResponse().getContentAsString();
+ System.out.println("Result === "+mvcResult);
+ }
+
+ private void saveMessages() {
+ for (int i=1;i<10;i++){
+ final MultiValueMap params = new LinkedMultiValueMap<>();
+ params.add("id",""+i);
+ params.add("text", "text"+i);
+ params.add("summary", "summary"+i);
+ try {
+ MvcResult mvcResult= mockMvc.perform(MockMvcRequestBuilders.post("/message")
+ .params(params)).andReturn();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/pom.xml b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/pom.xml
new file mode 100644
index 000000000..d44c1050a
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-thymeleaf-layout
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-thymeleaf-layout
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ nz.net.ultraq.thymeleaf
+ thymeleaf-layout-dialect
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/TLayoutApplication.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/TLayoutApplication.java
new file mode 100644
index 000000000..0e4e29af2
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/TLayoutApplication.java
@@ -0,0 +1,13 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class TLayoutApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TLayoutApplication.class, args);
+ }
+
+}
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/web/IndexController.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/web/IndexController.java
new file mode 100644
index 000000000..3b2554172
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/web/IndexController.java
@@ -0,0 +1,31 @@
+package com.neo.web;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class IndexController {
+
+ @RequestMapping("/index")
+ public String index() {
+ return "index";
+ }
+
+ @RequestMapping("/fragment")
+ public String fragment() {
+ return "fragment";
+ }
+
+ @RequestMapping("/layout")
+ public String layout() {
+ return "layout";
+ }
+
+ @RequestMapping("/home")
+ public String home() {
+ return "home";
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/application.properties b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/application.properties
new file mode 100644
index 000000000..975a5172a
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+com.neo.title=\u7EAF\u6D01\u7684\u5FAE\u7B11
+com.neo.description=\u5206\u4EAB\u751F\u6D3B\u548C\u6280\u672F
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/base.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/base.html
new file mode 100644
index 000000000..6a491191e
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/base.html
@@ -0,0 +1,15 @@
+
+
+
+ comm title
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/fragment.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/fragment.html
new file mode 100644
index 000000000..bb65abe2e
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/fragment.html
@@ -0,0 +1,11 @@
+
+
+
+ Fragment - Page
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/home.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/home.html
new file mode 100644
index 000000000..bd0de8076
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/home.html
@@ -0,0 +1,11 @@
+
+
+
+ Home
+
+
+
+
个性化的内容
+
+
+
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/index.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/index.html
new file mode 100644
index 000000000..40d36573a
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Index
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout.html
new file mode 100644
index 000000000..4bc09f3c9
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Layout
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/copyright.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/copyright.html
new file mode 100644
index 000000000..223de9f3e
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/copyright.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Title
+
+
+
+ © 2018
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/footer.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/footer.html
new file mode 100644
index 000000000..48a9c7def
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/footer.html
@@ -0,0 +1,12 @@
+
+
+
+
+ footer
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/header.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/header.html
new file mode 100644
index 000000000..adc6b8c67
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/header.html
@@ -0,0 +1,12 @@
+
+
+
+
+ header
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/left.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/left.html
new file mode 100644
index 000000000..04d887574
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/left.html
@@ -0,0 +1,12 @@
+
+
+
+
+ left
+
+
+
+ 我是 左侧
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/test/java/com/neo/TLayoutApplicationTests.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/test/java/com/neo/TLayoutApplicationTests.java
new file mode 100644
index 000000000..3e1b0ab0c
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/test/java/com/neo/TLayoutApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 TLayoutApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/pom.xml b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/pom.xml
new file mode 100644
index 000000000..73702eefb
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/pom.xml
@@ -0,0 +1,62 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-thymeleaf
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-thymeleaf
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.0.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java
new file mode 100644
index 000000000..e194e8686
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java
@@ -0,0 +1,13 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ThymeleafApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ThymeleafApplication.class, args);
+ }
+
+}
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/model/User.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..38e19acc9
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/model/User.java
@@ -0,0 +1,49 @@
+package com.neo.model;
+
+import org.hibernate.validator.constraints.Length;
+import org.hibernate.validator.constraints.NotEmpty;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Size;
+
+public class User {
+ private String name;
+ private int age;
+ private String pass;
+
+ public User(String name, int age, String pass) {
+ this.name = name;
+ this.age = age;
+ this.pass = pass;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getPass() {
+ return pass;
+ }
+
+ public void setPass(String pass) {
+ this.pass = pass;
+ }
+
+ @Override
+ public String toString() {
+ return ("name=" + this.name + ",age=" + this.age + ",pass=" + this.pass);
+ }
+}
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/ExampleController.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/ExampleController.java
new file mode 100644
index 000000000..112760366
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/ExampleController.java
@@ -0,0 +1,66 @@
+package com.neo.web;
+
+import com.neo.model.User;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Controller
+public class ExampleController {
+
+ @RequestMapping("/string")
+ public String string(ModelMap map) {
+ map.addAttribute("userName", "ityouknow");
+ return "string";
+ }
+
+ @RequestMapping("/if")
+ public String ifunless(ModelMap map) {
+ map.addAttribute("flag", "yes");
+ return "if";
+ }
+
+ @RequestMapping("/list")
+ public String list(ModelMap map) {
+ map.addAttribute("users", getUserList());
+ return "list";
+ }
+
+ @RequestMapping("/url")
+ public String url(ModelMap map) {
+ map.addAttribute("type", "link");
+ map.addAttribute("pageId", "springcloud/2017/09/11/");
+ map.addAttribute("img", "http://www.ityouknow.com/assets/images/neo.jpg");
+ return "url";
+ }
+
+ @RequestMapping("/eq")
+ public String eq(ModelMap map) {
+ map.addAttribute("name", "neo");
+ map.addAttribute("age", 30);
+ map.addAttribute("flag", "yes");
+ return "eq";
+ }
+
+ @RequestMapping("/switch")
+ public String switchcase(ModelMap map) {
+ map.addAttribute("sex", "woman");
+ return "switch";
+ }
+
+ private List getUserList(){
+ List list=new ArrayList();
+ User user1=new User("大牛",12,"123456");
+ User user2=new User("小牛",6,"123563");
+ User user3=new User("纯洁的微笑",66,"666666");
+ list.add(user1);
+ list.add(user2);
+ list.add(user3);
+ return list;
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/HelloController.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..2eac4e8a9
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,16 @@
+package com.neo.web;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class HelloController {
+
+ @RequestMapping("/")
+ public String index(ModelMap map) {
+ map.addAttribute("message", "http://www.ityouknow.com");
+ return "hello";
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/application.properties b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/application.properties
new file mode 100644
index 000000000..4b9333aa3
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.thymeleaf.cache=false
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/eq.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/eq.html
new file mode 100644
index 000000000..70e65a9fa
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/eq.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Example gt eq
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/hello.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/hello.html
new file mode 100644
index 000000000..28c51163e
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/hello.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Hello
+
+
+Hello World
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/if.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/if.html
new file mode 100644
index 000000000..9127c233c
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/if.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Example If/Unless
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/list.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/list.html
new file mode 100644
index 000000000..017c65e96
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/list.html
@@ -0,0 +1,20 @@
+
+
+
+
+ Example If/Unless
+
+
+
+
for 循环
+
+
+ | neo |
+ 6 |
+ 213 |
+ index |
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/string.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/string.html
new file mode 100644
index 000000000..7a2e3f66d
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/string.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Example String
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/switch.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/switch.html
new file mode 100644
index 000000000..aef5a3031
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/switch.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Example switch
+
+
+
+
+
她是一个姑娘...
+
这是一个爷们!
+
+
未知性别的一个家伙。
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/url.html b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/url.html
new file mode 100644
index 000000000..ded52686f
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/url.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Example If/Unless
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
new file mode 100644
index 000000000..3ccf7f4b9
--- /dev/null
+++ b/2.x/spring-boot-thymeleaf/spring-boot-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 ThymeleafApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/2.x/spring-boot-web-thymeleaf/pom.xml b/2.x/spring-boot-web-thymeleaf/pom.xml
new file mode 100644
index 000000000..29d75f28c
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+ spring-boot-web-thymeleaf
+ Spring Boot Web thymeleaf Sample
+ Spring Boot Web thymeleaf Sample
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.RELEASE
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java
new file mode 100644
index 000000000..3fc821be9
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012-2018 the original author or authors.
+ *
+ * Licensed 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.
+ *
+ * 本示例参数于:
+ * https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-ui
+ */
+package com.neo;
+
+import com.neo.model.Message;
+import com.neo.repository.InMemoryMessageRepository;
+import com.neo.repository.MessageRepository;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.convert.converter.Converter;
+
+
+@SpringBootApplication
+public class ThymeleafApplication {
+
+ @Bean
+ public MessageRepository messageRepository() {
+ return new InMemoryMessageRepository();
+ }
+
+ @Bean
+ public Converter messageConverter() {
+ return new Converter() {
+ @Override
+ public Message convert(String id) {
+ return messageRepository().findMessage(Long.valueOf(id));
+ }
+ };
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(ThymeleafApplication.class, args);
+ }
+
+}
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/controller/MessageController.java b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/controller/MessageController.java
new file mode 100644
index 000000000..0f5b33d0b
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/controller/MessageController.java
@@ -0,0 +1,72 @@
+
+package com.neo.controller;
+
+import javax.validation.Valid;
+
+import com.neo.model.Message;
+import com.neo.repository.MessageRepository;
+import org.springframework.stereotype.Controller;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+@Controller
+@RequestMapping("/")
+public class MessageController {
+
+ private final MessageRepository messageRepository;
+
+ public MessageController(MessageRepository messageRepository) {
+ this.messageRepository = messageRepository;
+ }
+
+ @GetMapping
+ public ModelAndView list() {
+ Iterable messages = this.messageRepository.findAll();
+ return new ModelAndView("messages/list", "messages", messages);
+ }
+
+ @GetMapping("{id}")
+ public ModelAndView view(@PathVariable("id") Message message) {
+ return new ModelAndView("messages/view", "message", message);
+ }
+
+ @GetMapping(params = "form")
+ public String createForm(@ModelAttribute Message message) {
+ return "messages/form";
+ }
+
+ @PostMapping
+ public ModelAndView create(@Valid Message message, BindingResult result,
+ RedirectAttributes redirect) {
+ if (result.hasErrors()) {
+ return new ModelAndView("messages/form", "formErrors", result.getAllErrors());
+ }
+ message = this.messageRepository.save(message);
+ redirect.addFlashAttribute("globalMessage", "Successfully created a new message");
+ return new ModelAndView("redirect:/{message.id}", "message.id", message.getId());
+ }
+
+ @RequestMapping("foo")
+ public String foo() {
+ throw new RuntimeException("Expected exception in controller");
+ }
+
+ @GetMapping(value = "delete/{id}")
+ public ModelAndView delete(@PathVariable("id") Long id) {
+ this.messageRepository.deleteMessage(id);
+ Iterable messages = this.messageRepository.findAll();
+ return new ModelAndView("messages/list", "messages", messages);
+ }
+
+ @GetMapping(value = "modify/{id}")
+ public ModelAndView modifyForm(@PathVariable("id") Message message) {
+ return new ModelAndView("messages/form", "message", message);
+ }
+
+}
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/model/Message.java b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/model/Message.java
new file mode 100644
index 000000000..d4f09e648
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/model/Message.java
@@ -0,0 +1,52 @@
+package com.neo.model;
+
+import java.util.Calendar;
+
+import javax.validation.constraints.NotEmpty;
+
+
+public class Message {
+
+ private Long id;
+
+ @NotEmpty(message = "Text is required.")
+ private String text;
+
+ @NotEmpty(message = "Summary is required.")
+ private String summary;
+
+ private Calendar created = Calendar.getInstance();
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Calendar getCreated() {
+ return this.created;
+ }
+
+ public void setCreated(Calendar created) {
+ this.created = created;
+ }
+
+ public String getText() {
+ return this.text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public String getSummary() {
+ return this.summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+}
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/repository/InMemoryMessageRepository.java b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/repository/InMemoryMessageRepository.java
new file mode 100644
index 000000000..185b19711
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/repository/InMemoryMessageRepository.java
@@ -0,0 +1,44 @@
+
+
+package com.neo.repository;
+
+import com.neo.model.Message;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+
+public class InMemoryMessageRepository implements MessageRepository {
+
+ private static AtomicLong counter = new AtomicLong();
+
+ private final ConcurrentMap messages = new ConcurrentHashMap<>();
+
+ @Override
+ public Iterable findAll() {
+ return this.messages.values();
+ }
+
+ @Override
+ public Message save(Message message) {
+ Long id = message.getId();
+ if (id == null) {
+ id = counter.incrementAndGet();
+ message.setId(id);
+ }
+ this.messages.put(id, message);
+ return message;
+ }
+
+ @Override
+ public Message findMessage(Long id) {
+ return this.messages.get(id);
+ }
+
+ @Override
+ public void deleteMessage(Long id) {
+ this.messages.remove(id);
+ }
+
+}
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/repository/MessageRepository.java b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/repository/MessageRepository.java
new file mode 100644
index 000000000..b4830d8bd
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/java/com/neo/repository/MessageRepository.java
@@ -0,0 +1,16 @@
+
+package com.neo.repository;
+
+import com.neo.model.Message;
+
+public interface MessageRepository {
+
+ Iterable findAll();
+
+ Message save(Message message);
+
+ Message findMessage(Long id);
+
+ void deleteMessage(Long id);
+
+}
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/application.properties b/2.x/spring-boot-web-thymeleaf/src/main/resources/application.properties
new file mode 100644
index 000000000..6665cd62d
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+# Allow Thymeleaf templates to be reloaded at dev time
+spring.thymeleaf.cache: false
+server.tomcat.access_log_enabled: true
+server.tomcat.basedir: target/tomcat
\ No newline at end of file
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/logback.xml b/2.x/spring-boot-web-thymeleaf/src/main/resources/logback.xml
new file mode 100644
index 000000000..620db4a2a
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/resources/logback.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/static/css/bootstrap.min.css b/2.x/spring-boot-web-thymeleaf/src/main/resources/static/css/bootstrap.min.css
new file mode 100644
index 000000000..c814524fe
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/resources/static/css/bootstrap.min.css
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v4.0.0 (https://getbootstrap.com)
+ * Copyright 2011-2018 The Bootstrap Authors
+ * Copyright 2011-2018 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group{width:auto}.form-inline .form-check{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;transition:opacity .15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}.dropdown,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropup .dropdown-menu{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after{margin-left:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file:focus,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::before{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::before{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-webkit-box;display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 5px rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-control{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-control::before{border-color:#80bdff}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.nav{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .dropup .dropdown-menu{top:auto;bottom:100%}}.navbar-expand{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .dropup .dropdown-menu{top:auto;bottom:100%}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-webkit-box;display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-webkit-box;display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;background-color:#007bff;transition:width .6s ease}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.media-body{-webkit-box-flex:1;-ms-flex:1;flex:1}.list-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;-webkit-clip-path:inset(50%);clip-path:inset(50%);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;-webkit-clip-path:none;clip-path:none}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-muted{color:#6c757d!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}
+/*# sourceMappingURL=bootstrap.min.css.map */
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/static/favicon.ico b/2.x/spring-boot-web-thymeleaf/src/main/resources/static/favicon.ico
new file mode 100644
index 000000000..fd306001d
Binary files /dev/null and b/2.x/spring-boot-web-thymeleaf/src/main/resources/static/favicon.ico differ
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/fragments.html b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/fragments.html
new file mode 100644
index 000000000..4aee99234
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/fragments.html
@@ -0,0 +1,18 @@
+
+
+
+ Fragments
+
+
+
+
+
+
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/form.html b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/form.html
new file mode 100644
index 000000000..1d564bfba
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/form.html
@@ -0,0 +1,31 @@
+
+
+
+ Messages : Create
+
+
+
+
+
+
Messages : Create
+
+
+
+
+
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/list.html b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/list.html
new file mode 100644
index 000000000..88f00a8fd
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/list.html
@@ -0,0 +1,36 @@
+
+
+
+ Messages : View all
+
+
+
+
+
+
Messages : View all
+
+
+
+ | ID |
+ Created |
+ Summary |
+
+
+
+
+ | No messages |
+
+
+ | 1 |
+ July 11,
+ 2012 2:17:16 PM CDT |
+ The summary |
+
+
+
+
+
+
diff --git a/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/view.html b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/view.html
new file mode 100644
index 000000000..e32cb74e0
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/main/resources/templates/messages/view.html
@@ -0,0 +1,27 @@
+
+
+
+ Messages : View
+
+
+
+
+
+
Messages : View
+
+
Some Success message
+
+
+
+
123 - A short summary...
+
July 11, 2012 2:17:16 PM CDT
+
A detailed message that is longer than the summary.
+
delete
+
modify
+
+
+
+
+
diff --git a/2.x/spring-boot-web-thymeleaf/src/test/java/com/neo/MessageControllerWebTests.java b/2.x/spring-boot-web-thymeleaf/src/test/java/com/neo/MessageControllerWebTests.java
new file mode 100644
index 000000000..c27555309
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/test/java/com/neo/MessageControllerWebTests.java
@@ -0,0 +1,89 @@
+
+package com.neo;
+
+import java.util.regex.Pattern;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(classes = ThymeleafApplication.class)
+public class MessageControllerWebTests {
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
+ }
+
+ @Test
+ public void testHome() throws Exception {
+ this.mockMvc.perform(get("/")).andExpect(status().isOk())
+ .andExpect(content().string(containsString("Messages")));
+ }
+
+ @Test
+ public void testCreate() throws Exception {
+ this.mockMvc.perform(post("/").param("text", "FOO text").param("summary", "FOO"))
+ .andExpect(status().isFound())
+ .andExpect(header().string("location", RegexMatcher.matches("/[0-9]+")));
+ }
+
+ @Test
+ public void testCreateValidation() throws Exception {
+ this.mockMvc.perform(post("/").param("text", "").param("summary", ""))
+ .andExpect(status().isOk())
+ .andExpect(content().string(containsString("is required")));
+ }
+
+ private static class RegexMatcher extends TypeSafeMatcher {
+ private final String regex;
+
+ public RegexMatcher(String regex) {
+ this.regex = regex;
+ }
+
+ public static org.hamcrest.Matcher matches(String regex) {
+ return new RegexMatcher(regex);
+ }
+
+ @Override
+ public boolean matchesSafely(String item) {
+ return Pattern.compile(this.regex).matcher(item).find();
+ }
+
+ @Override
+ public void describeMismatchSafely(String item, Description mismatchDescription) {
+ mismatchDescription.appendText("was \"").appendText(item).appendText("\"");
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a string that matches regex: ")
+ .appendText(this.regex);
+ }
+ }
+}
diff --git a/2.x/spring-boot-web-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java b/2.x/spring-boot-web-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
new file mode 100644
index 000000000..e97547773
--- /dev/null
+++ b/2.x/spring-boot-web-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
@@ -0,0 +1,57 @@
+
+package com.neo;
+
+import java.net.URI;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class ThymeleafApplicationTests {
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @LocalServerPort
+ private int port;
+
+ @Test
+ public void testHome() {
+ ResponseEntity entity = this.restTemplate.getForEntity("/", String.class);
+ assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
+ assertThat(entity.getBody()).contains("Messages");
+ assertThat(entity.getBody()).doesNotContain("layout:fragment");
+ }
+
+ @Test
+ public void testCreate() {
+ MultiValueMap map = new LinkedMultiValueMap<>();
+ map.set("text", "FOO text");
+ map.set("summary", "FOO");
+ URI location = this.restTemplate.postForLocation("/", map);
+ assertThat(location.toString()).contains("localhost:" + this.port);
+ }
+
+ @Test
+ public void testCss() {
+ ResponseEntity entity = this.restTemplate.getForEntity(
+ "http://localhost:" + this.port + "/css/bootstrap.min.css", String.class);
+ assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
+ assertThat(entity.getBody()).contains("body");
+ }
+
+}
diff --git a/2.x/spring-boot-web/pom.xml b/2.x/spring-boot-web/pom.xml
new file mode 100644
index 000000000..e0a2f96d0
--- /dev/null
+++ b/2.x/spring-boot-web/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-web
+ 1.0.01-SNAPSHOT
+ war
+
+ spring-boot-web
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.3.RELEASE
+
+
+
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.webjars.bower
+ jquery
+ 2.0.3
+
+
+ org.webjars.bower
+ bootstrap
+ 3.0.3
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/WebApplication.java b/2.x/spring-boot-web/src/main/java/com/neo/WebApplication.java
new file mode 100644
index 000000000..ede8e479f
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/WebApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class WebApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(WebApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/WebConfiguration.java b/2.x/spring-boot-web/src/main/java/com/neo/WebConfiguration.java
new file mode 100644
index 000000000..cbf7177fd
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/WebConfiguration.java
@@ -0,0 +1,60 @@
+package com.neo;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.catalina.filters.RemoteIpFilter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class WebConfiguration {
+ @Bean
+ public RemoteIpFilter remoteIpFilter() {
+ return new RemoteIpFilter();
+ }
+
+ @Bean
+ public FilterRegistrationBean testFilterRegistration() {
+
+ FilterRegistrationBean registration = new FilterRegistrationBean();
+ registration.setFilter(new MyFilter());
+ registration.addUrlPatterns("/*");
+ registration.addInitParameter("paramName", "paramValue");
+ registration.setName("MyFilter");
+ registration.setOrder(1);
+ return registration;
+ }
+
+ public class MyFilter implements Filter {
+ @Override
+ public void destroy() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ // TODO Auto-generated method stub
+ HttpServletRequest request = (HttpServletRequest) srequest;
+ System.out.println("this is MyFilter,url :"+request.getRequestURI());
+ filterChain.doFilter(srequest, sresponse);
+ }
+
+ @Override
+ public void init(FilterConfig arg0) throws ServletException {
+ // TODO Auto-generated method stub
+ }
+ }
+}
+
+
+
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/model/User.java b/2.x/spring-boot-web/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..53204112f
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/model/User.java
@@ -0,0 +1,76 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false, unique = true)
+ private String userName;
+ @Column(nullable = false)
+ private String passWord;
+ @Column(nullable = false, unique = true)
+ private String email;
+ @Column(nullable = true, unique = true)
+ private String nickName;
+ @Column(nullable = false)
+ private String regTime;
+
+ public User() {
+ super();
+ }
+ public User(String nickName,String email,String userName, String passWord, String regTime) {
+ super();
+ this.email = email;
+ this.nickName = nickName;
+ this.passWord = passWord;
+ this.userName = userName;
+ this.regTime = regTime;
+ }
+ public Long getId() {
+ return id;
+ }
+ public void setId(Long id) {
+ this.id = id;
+ }
+ public String getUserName() {
+ return userName;
+ }
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+ public String getPassWord() {
+ return passWord;
+ }
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+ public String getEmail() {
+ return email;
+ }
+ public void setEmail(String email) {
+ this.email = email;
+ }
+ public String getNickName() {
+ return nickName;
+ }
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+ public String getRegTime() {
+ return regTime;
+ }
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/repository/UserRepository.java b/2.x/spring-boot-web/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..b5c0c63ec
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,12 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserRepository extends JpaRepository {
+
+ User findByUserName(String userName);
+
+ User findByUserNameOrEmail(String username, String email);
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/util/NeoProperties.java b/2.x/spring-boot-web/src/main/java/com/neo/util/NeoProperties.java
new file mode 100644
index 000000000..ab337bfbd
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/util/NeoProperties.java
@@ -0,0 +1,26 @@
+package com.neo.util;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NeoProperties {
+
+ @Value("${com.neo.title}")
+ private String title;
+ @Value("${com.neo.description}")
+ private String description;
+ public String getTitle() {
+ return title;
+ }
+ public void setTitle(String title) {
+ this.title = title;
+ }
+ public String getDescription() {
+ return description;
+ }
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+}
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/web/HelloController.java b/2.x/spring-boot-web/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..ac3dee8e6
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,21 @@
+package com.neo.web;
+
+import java.util.Locale;
+import java.util.UUID;
+
+import javax.servlet.http.HttpSession;
+
+import com.neo.model.User;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+
+ @RequestMapping("/hello")
+ public String hello(Locale locale, Model model) {
+ return "Hello World";
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/web/ThymeleafController.java b/2.x/spring-boot-web/src/main/java/com/neo/web/ThymeleafController.java
new file mode 100644
index 000000000..c384bd1d8
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/web/ThymeleafController.java
@@ -0,0 +1,26 @@
+package com.neo.web;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class ThymeleafController {
+
+ @RequestMapping("/hi")
+ public String hello(Locale locale, Model model) {
+ model.addAttribute("greeting", "Hello!");
+
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
+ String formattedDate = dateFormat.format(date);
+ model.addAttribute("currentTime", formattedDate);
+
+ return "hello";
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/main/java/com/neo/web/UserController.java b/2.x/spring-boot-web/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..b722a87d5
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,31 @@
+package com.neo.web;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.neo.model.User;
+import com.neo.repository.UserRepository;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @RequestMapping("/getUser")
+ public User getUser() {
+ User user=userRepository.findByUserName("aa");
+ System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
+ return user;
+ }
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=userRepository.findAll();
+ System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
+ return users;
+ }
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/main/resources/application.properties b/2.x/spring-boot-web/src/main/resources/application.properties
new file mode 100644
index 000000000..bf2d2c8a7
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/resources/application.properties
@@ -0,0 +1,14 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.jpa.properties.hibernate.hbm2ddl.auto=create
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+#sql\u8F93\u51FA
+spring.jpa.show-sql=true
+#format\u4E00\u4E0Bsql\u8FDB\u884C\u8F93\u51FA
+spring.jpa.properties.hibernate.format_sql=true
+
+com.neo.title=\u7EAF\u6D01\u7684\u5FAE\u7B11
+com.neo.description=\u5206\u4EAB\u751F\u6D3B\u548C\u6280\u672F
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/main/resources/static/css/starter.css b/2.x/spring-boot-web/src/main/resources/static/css/starter.css
new file mode 100644
index 000000000..e2fc60cd4
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/resources/static/css/starter.css
@@ -0,0 +1,8 @@
+body {
+ padding-top: 50px;
+}
+
+.starter-template {
+ padding: 40px 15px;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/main/resources/static/images/favicon.png b/2.x/spring-boot-web/src/main/resources/static/images/favicon.png
new file mode 100644
index 000000000..890ef0630
Binary files /dev/null and b/2.x/spring-boot-web/src/main/resources/static/images/favicon.png differ
diff --git a/2.x/spring-boot-web/src/main/resources/templates/hello.html b/2.x/spring-boot-web/src/main/resources/templates/hello.html
new file mode 100644
index 000000000..c417054af
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/resources/templates/hello.html
@@ -0,0 +1,18 @@
+
+
+
+
+ (navbar)
+
+
+
+
Spring MVC / Thymeleaf / Bootstrap
+
(greeting)
+
The current time is (time)
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-web/src/main/resources/templates/layout.html b/2.x/spring-boot-web/src/main/resources/templates/layout.html
new file mode 100644
index 000000000..422fbb71e
--- /dev/null
+++ b/2.x/spring-boot-web/src/main/resources/templates/layout.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+ (title)
+
+
+
+
+
+
+
+
+
+
+
Spring MVC/Thymeleaf/Bootstrap
+
(greeting)
+
+
+
+
+
+
+
diff --git a/2.x/spring-boot-web/src/test/java/com/neo/WebApplicationTests.java b/2.x/spring-boot-web/src/test/java/com/neo/WebApplicationTests.java
new file mode 100644
index 000000000..cd4cb770c
--- /dev/null
+++ b/2.x/spring-boot-web/src/test/java/com/neo/WebApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class WebApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello web");
+ }
+
+}
diff --git a/2.x/spring-boot-web/src/test/java/com/neo/model/UserRepositoryTests.java b/2.x/spring-boot-web/src/test/java/com/neo/model/UserRepositoryTests.java
new file mode 100644
index 000000000..3b7d8ea33
--- /dev/null
+++ b/2.x/spring-boot-web/src/test/java/com/neo/model/UserRepositoryTests.java
@@ -0,0 +1,38 @@
+package com.neo.model;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+import com.neo.repository.UserRepository;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import org.springframework.test.context.junit4.SpringRunner;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTests {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Test
+ public void test() throws Exception {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+
+ userRepository.save(new User("aa1", "aa@126.com", "aa", "aa123456",formattedDate));
+ userRepository.save(new User("bb2", "bb@126.com", "bb", "bb123456",formattedDate));
+ userRepository.save(new User("cc3", "cc@126.com", "cc", "cc123456",formattedDate));
+
+// Assert.assertEquals(9, userRepository.findAll().size());
+ Assert.assertEquals("bb2", userRepository.findByUserNameOrEmail("bb", "xxx126.com").getNickName());
+ userRepository.delete(userRepository.findByUserName("aa"));
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/test/java/com/neo/web/HelloControlerTests.java b/2.x/spring-boot-web/src/test/java/com/neo/web/HelloControlerTests.java
new file mode 100644
index 000000000..f0a83c9ae
--- /dev/null
+++ b/2.x/spring-boot-web/src/test/java/com/neo/web/HelloControlerTests.java
@@ -0,0 +1,57 @@
+package com.neo.web;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.neo.web.HelloController;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloControlerTests {
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ }
+
+
+
+ @Test
+ public void testHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java b/2.x/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java
new file mode 100644
index 000000000..93722c9a6
--- /dev/null
+++ b/2.x/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java
@@ -0,0 +1,35 @@
+package com.neo.web;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com.neo.util.NeoProperties;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ProPertiesTest {
+
+ @Autowired
+ private NeoProperties neoProperties;
+
+ @Test
+ public void getHello() throws Exception {
+ System.out.println(neoProperties.getTitle());
+ Assert.assertEquals(neoProperties.getTitle(), "纯洁的微笑");
+ Assert.assertEquals(neoProperties.getDescription(), "分享生活和技术");
+ }
+
+ @Test
+ public void testMap() throws Exception {
+ Map orderMinTime=new HashMap();
+ long xx=orderMinTime.get("123");
+ }
+
+}
\ No newline at end of file
diff --git a/2.x/spring-boot-webflux/pom.xml b/2.x/spring-boot-webflux/pom.xml
new file mode 100644
index 000000000..68a6ca1f2
--- /dev/null
+++ b/2.x/spring-boot-webflux/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-webflux
+ 1.0.0-SNAPSHOT
+ jar
+
+ spring-boot-webflux
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.2.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/2.x/spring-boot-webflux/src/main/java/com/neo/WebFluxApplication.java b/2.x/spring-boot-webflux/src/main/java/com/neo/WebFluxApplication.java
new file mode 100644
index 000000000..b89527d35
--- /dev/null
+++ b/2.x/spring-boot-webflux/src/main/java/com/neo/WebFluxApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class WebFluxApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(WebFluxApplication.class, args);
+ }
+}
diff --git a/2.x/spring-boot-webflux/src/main/java/com/neo/web/HelloController.java b/2.x/spring-boot-webflux/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..681a1542f
--- /dev/null
+++ b/2.x/spring-boot-webflux/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,14 @@
+package com.neo.web;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+@RestController
+public class HelloController {
+
+ @GetMapping("/hello")
+ public Mono hello() {
+ return Mono.just("Welcome to reactive world ~");
+ }
+}
diff --git a/2.x/spring-boot-webflux/src/main/resources/application.properties b/2.x/spring-boot-webflux/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/2.x/spring-boot-webflux/src/test/java/com/neo/HelloTests.java b/2.x/spring-boot-webflux/src/test/java/com/neo/HelloTests.java
new file mode 100644
index 000000000..aa9389c5f
--- /dev/null
+++ b/2.x/spring-boot-webflux/src/test/java/com/neo/HelloTests.java
@@ -0,0 +1,21 @@
+package com.neo;
+
+import com.neo.web.HelloController;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+@RunWith(SpringRunner.class)
+@WebFluxTest(controllers = HelloController.class)
+public class HelloTests {
+ @Autowired
+ WebTestClient client;
+
+ @Test
+ public void getHello() {
+ client.get().uri("/hello").exchange().expectStatus().isOk();
+ }
+}
diff --git a/2.x/spring-boot-webflux/src/test/java/com/neo/WebFluxApplicationTests.java b/2.x/spring-boot-webflux/src/test/java/com/neo/WebFluxApplicationTests.java
new file mode 100644
index 000000000..b7b4ed765
--- /dev/null
+++ b/2.x/spring-boot-webflux/src/test/java/com/neo/WebFluxApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 WebFluxApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/README.md b/README.md
index 026b871e6..de3f8c880 100644
--- a/README.md
+++ b/README.md
@@ -1,95 +1,55 @@
-# Spring Boot Examples
+Spring Boot 学习示例
+=========================
-Spring Boot 使用的各种示例,以最简单、最实用为标准
+
+
+
+
+
+
+Spring Boot 使用的各种示例,以最简单、最实用为标准,此开源项目中的每个示例都以最小依赖,最简单为标准,帮助初学者快速掌握 Spring Boot 各组件的使用。
[Spring Boot 中文索引](https://github.com/ityouknow/awesome-spring-boot) | [Spring Cloud学习示例代码](https://github.com/ityouknow/spring-cloud-examples) | [Spring Boot 精品课程](https://github.com/ityouknow/spring-boot-leaning)
-[English](README_EN.md) | [Github地址](https://github.com/ityouknow/spring-boot-examples) | [码云地址](https://gitee.com/ityouknow/spring-boot-examples) | [Spring Boot 1.0](https://github.com/ityouknow/spring-boot-examples/tree/Spring-Boot-1.0)
+ [Github地址](https://github.com/ityouknow/spring-boot-examples) | [码云地址](https://gitee.com/ityouknow/spring-boot-examples) | [Spring Boot 1.X](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x) | [Spring Boot 2.X](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x)
---
-## Spring Boot 2.0
-**[Spring Boot 2.0 最全使用教程](https://github.com/ityouknow/spring-boot-leaning)**
+**本项目中所有示例均已经更新到 Spring Boot 3.0**
-**[Favorites-web](https://github.com/cloudfavorites/favorites-web):云收藏(Spring Boot 2.0 实战开源项目)**
+- Spring Boot 1.X 系列示例代码请看这里:[Spring Boot 1.X](https://github.com/ityouknow/spring-boot-examples/tree/master/1.x)
+- Spring Boot 2.X 系列示例代码请看这里:[Spring Boot 2.X](https://github.com/ityouknow/spring-boot-examples/tree/master/2.x)
-**示例代码**
-- [spring-boot-hello](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-hello):Spring Boot 2.0 Hello World 示例
-- [spring-boot-banner](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-banner):Spring Boot 定制 Banner 示例
-- [spring-boot-docker](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-banner):使用 Docker 部署 Spring Boot 示例
-- [dockercompose-springboot-mysql-nginx](https://github.com/ityouknow/spring-boot-examples/tree/master/dockercompose-springboot-mysql-nginx) :Docker Compose + Spring Boot + Nginx + Mysql 示例
-- [spring-boot-commandLineRunner](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-commandLineRunner) :Spring Boot 使用 commandLineRunner 实现项目启动时资源初始化示例
-- [spring-boot-web-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-web-thymeleaf) :Spring Boot 使用 thymeleaf 实现布局、验参、增删改查示例
-- [spring-boot-memcache-spymemcached](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-memcache-spymemcached) :Spring Boot 使用 spymemcached 集成 memcache 示例
+## 示例代码
-**参考文章**
+- [spring-boot-hello](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-hello):Spring Boot 3.0 Hello World 示例
+- [spring-boot-banner](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-hello):Spring Boot 3.0 定制 banner 示例
+- [spring-boot-helloworld](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-helloWorld):Spring Boot 3.0 Hello World Test 单元测试示例
+- [spring-boot-scheduler](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-scheduler):Spring Boot 3.0 定时任务 scheduler 使用示例
+- [spring-boot-package](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-package):Spring Boot 3.0 单元测试、集成测试、打 Jar/War 包、定制启动参数使用案例
+- [spring-boot-commandLineRunner](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-commandLineRunner):Spring Boot 3.0 目启动时初始化资源案例
+- [spring-boot-web](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-web):Spring Boot 3.0 web 示例
+- [spring-boot-webflux](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-webflux):Spring Boot 3.0 响应式编程 WebFlux 使用案例
+- [spring-boot-file-upload](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-file-upload):Spring Boot 3.0 上传文件使用案例
+- [spring-boot-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-thymeleaf):Spring Boot 3.0 Thymeleaf 语法、布局使用示例
+- [spring-boot-jpa](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-jpa):Spring Boot 3.0 Jpa 操作、增删、改查多数据源使用示例
+- [spring-boot-mybatis](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis):Spring Boot 3.0 Mybatis 注解、xml 使用、增删改查、多数据源使用示例
+- [spring-boot-web-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-web-thymeleaf):Spring Boot 3.0 thymeleaf 增删该查示例
+- [spring-boot-jpa-thymeleaf-curd](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-jpa-thymeleaf-curd):Spring Boot 3.0 Jpa thymeleaf 列表、增删改查使用案例
+- [spring-boot-mail](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mail):Spring Boot 3.0 邮件发送使用示例
+- [spring-boot-rabbitmq](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-rabbitmq):Spring Boot 3.0 RabbitMQ 各种常见场景使用示例
+- [spring-boot-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mongodb):Spring Boot 3.0 MongoDB 增删改查示例 多数据源使用案例
+- [spring-boot-redis](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-redis):Spring Boot 3.0 Redis 示例
+- [spring-boot-memcache-spymemcached](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-memcache-spymemcached):Spring Boot 3.0 集成 Memcached 使用案例
+- [spring-boot-docker](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-docker):Spring Boot 3.0 Docker 使用案例
+- [dockercompose-springboot-mysql-nginx](https://github.com/ityouknow/spring-boot-examples/tree/master/dockercompose-springboot-mysql-nginx):Spring Boot 3.0 Docker Compose + Spring Boot + Nginx + Mysql 使用案例
-- [Spring Boot 2.0(一):【重磅】Spring Boot 2.0权威发布](http://www.ityouknow.com/springboot/2018/03/01/spring-boot-2.0.html)
-- [Spring Boot 2.0(二):Spring Boot 2.0尝鲜-动态 Banner](http://www.ityouknow.com/springboot/2018/03/03/spring-boot-banner.html)
-- [Spring Boot 2.0(三):Spring Boot 开源软件都有哪些?](http://www.ityouknow.com/springboot/2018/03/05/spring-boot-open-source.html)
-- [Spring Boot 2.0(四):使用 Docker 部署 Spring Boot](http://www.ityouknow.com/springboot/2018/03/19/spring-boot-docker.html)
-- [Spring Boot 2.0(五):Docker Compose + Spring Boot + Nginx + Mysql 实践](http://www.ityouknow.com/springboot/2018/03/28/dockercompose-springboot-mysql-nginx.html)
-- [Spring Boot 2.0(六):使用 Docker 部署 Spring Boot 开源软件云收藏](http://www.ityouknow.com/springboot/2018/04/02/docker-favorites.html)
-- [Spring Boot 2.0(七):Spring Boot 如何解决项目启动时初始化资源](http://www.ityouknow.com/springboot/2018/05/03/spring-boot-commandLineRunner.html)
-- [Spring Boot 2.0(八):Spring Boot 集成 Memcached](http://www.ityouknow.com/springboot/2018/09/01/spring-boot-memcached.html)
----
-
-## Spring Boot 1.0
-
-**示例代码**
-
-- [spring-boot-helloWorld](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-helloWorld):spring-boot的helloWorld版本
-- [spring-boot-mybaits-annotation](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-annotation):注解版本
-- [spring-boot-mybaits-xml](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-xml):xml配置版本
-- [spring-boot-mybatis-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-mulidatasource):springboot+mybatis多数据源最简解决方案
-- [spring-boot-mybatis-annotation-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-annotation-mulidatasource):springboot+mybatis(注解版)多数据源最简解决方案
-- [spring-boot-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-thymeleaf):simple spring boot thymeleaf demo
-- [spring-boot-jpa-thymeleaf-curd](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-jpa-thymeleaf-curd):spring boot + jpa + thymeleaf 增删改查示例
-- [spring-boot-rabbitmq](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-rabbitmq):spring boot和rabbitmq各种消息应用案例
-- [spring-boot-scheduler](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-scheduler):spring boot和定时任务案例
-- [spring-boot-web](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-web):web开发综合使用案例
-- [spring-boot-mail](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mail):spring boot和邮件服务
-- [spring-boot-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mongodb):spring boot和mongodb的使用
-- [spring-boot-multi-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-multi-mongodb):spring boot和mongodb多数据源的使用
-- [spring-boot-package-war](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-package-war):spring-boot打包成war包示例
-- [spring-boot-shiro](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-shiro):springboot 整合shiro rbac示例
-- [spring-boot-file-upload](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-file-upload):使用Spring Boot 上传文件示例
-- [spring-boot-fastDFS](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-fastDFS):Spring Boot 整合FastDFS示例
-- [spring-boot-actuator](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-actuator):Spring Boot Actuator 使用示例
-- [spring-boot-admin-simple](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-admin-simple):Spring Boot Admin 的使用示例
-
-**参考文章**
-
-- [springboot(一):入门篇](http://www.ityouknow.com/springboot/2016/01/06/spring-boot-quick-start.html)
-- [springboot(二):web综合开发](http://www.ityouknow.com/springboot/2016/02/03/spring-boot-web.html)
-- [springboot(三):Spring boot中Redis的使用](http://www.ityouknow.com/springboot/2016/03/06/spring-boot-redis.html)
-- [springboot(四):thymeleaf使用详解](http://www.ityouknow.com/springboot/2016/05/01/spring-boot-thymeleaf.html)
-- [springboot(五):spring data jpa的使用](http://www.ityouknow.com/springboot/2016/08/20/spring-boo-jpa.html)
-- [springboot(六):如何优雅的使用mybatis](http://www.ityouknow.com/springboot/2016/11/06/spring-boo-mybatis.html)
-- [springboot(七):springboot+mybatis多数据源最简解决方案](http://www.ityouknow.com/springboot/2016/11/25/spring-boot-multi-mybatis.html)
-- [springboot(八):RabbitMQ详解](http://www.ityouknow.com/springboot/2016/11/30/spring-boot-rabbitMQ.html)
-- [springboot(九):定时任务](http://www.ityouknow.com/springboot/2016/12/02/spring-boot-scheduler.html)
-- [springboot(十):邮件服务](http://www.ityouknow.com/springboot/2017/05/06/springboot-mail.html)
-- [springboot(十一):Spring boot中mongodb的使用](http://www.ityouknow.com/springboot/2017/05/08/springboot-mongodb.html)
-- [springboot(十二):springboot如何测试打包部署](http://www.ityouknow.com/springboot/2017/05/09/springboot-deploy.html)
-- [springboot(十三):springboot小技巧](http://www.ityouknow.com/springboot/2017/06/22/springboot-tips.html)
-- [springboot(十四):springboot整合shiro-登录认证和权限管理](http://www.ityouknow.com/springboot/2017/06/26/springboot-shiro.html)
-- [springboot(十五):springboot+jpa+thymeleaf增删改查示例](http://www.ityouknow.com/springboot/2017/09/23/spring-boot-jpa-thymeleaf-curd.html)
-- [springboot(十六):使用Jenkins部署Spring Boot](http://www.ityouknow.com/springboot/2017/11/11/springboot-jenkins.html)
-- [springboot(十七):使用Spring Boot上传文件](http://www.ityouknow.com/springboot/2018/01/12/spring-boot-upload-file.html)
-- [springboot(十八):使用Spring Boot集成FastDFS](http://www.ityouknow.com/springboot/2018/01/16/spring-boot-fastdfs.html)
-- [springboot(十九):使用Spring Boot Actuator监控应用](http://www.ityouknow.com/springboot/2018/02/06/spring-boot-actuator.html)
-- [springboot(二十):使用spring-boot-admin对spring-boot服务进行监控](http://www.ityouknow.com/springboot/2018/02/11/spring-boot-admin.html)
-
-**[Spring Boot 实战:我们的第一款开源项目](http://www.ityouknow.com/springboot/2016/09/26/spring-boot-opensource-favorites.html)**
-
----
> 如果大家想了解关于 Spring Boot 的其它方面应用,也可以以[issues](https://github.com/ityouknow/spring-boot-examples/issues)的形式反馈给我,我后续来完善。
-关注公众号:纯洁的微笑,回复"springboot"进群交流
+关注公众号:纯洁的微笑,回复"666"进群交流

\ No newline at end of file
diff --git a/README_EN.md b/README_EN.md
deleted file mode 100644
index 3e465b938..000000000
--- a/README_EN.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Spring Boot Examples
-
-This tutorial is about learning Spring Boot via examples.
-
-
-[Spring Cloud example code](https://github.com/ityouknow/spring-cloud-examples) | [中文](README.md)
-
-Spring Boot examples, using the simplest and the most useful scene demos.
-
----
-
-## Spring Boot 2.0
-
-
-**[Favorites-web](https://github.com/cloudfavorites/favorites-web):Open source projects developed using Spring Boot 2.0**
-
-- [spring-boot-hello](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-hello):Spring Boot 2.0 Hello World Demo
-- [spring-boot-banner](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-banner):Spring Boot Customized Banner
-- [spring-boot-docker](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-banner):Spring Boot with Docker
-- [dockercompose-springboot-mysql-nginx](https://github.com/ityouknow/spring-boot-examples/tree/master/dockercompose-springboot-mysql-nginx) :Docker Compose + Spring Boot + Nginx + Mysql example
-- [spring-boot-commandLineRunner](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-commandLineRunner) :Example of resource initialization at project startup using Spring Boot and commandLineRunner
-- [spring-boot-web-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-web-thymeleaf) :Spring Boot uses thymeleaf to implement layout, check parameters and CURD
-- [spring-boot-memcache-spymemcached](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-memcache-spymemcached) :Spring Boot uses spymemcached to memcache
-
-
----
-
-## Spring Boot 1.0
-
-- [spring-boot-helloWorld](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-helloWorld):Spring Boot helloWorld
-- [spring-boot-mybaits-annotation](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-annotation):Spring Boot use mybatis annotation
-- [spring-boot-mybaits-xml](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-xml):Spring Boot use mybatis xml
-- [spring-boot-mybatis-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-mulidatasource):Spring Boot+mybatis+mulidatasource
-- [spring-boot-mybatis-annotation-mulidatasource](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mybatis-annotation-mulidatasource):Spring Boot+ mybatis annotation + mulidatasource
-- [spring-boot-thymeleaf](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-thymeleaf):simple spring boot thymeleaf demo
-- [spring-boot-jpa-thymeleaf-curd](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-jpa-thymeleaf-curd):spring boot + jpa + thymeleaf curd demo
-- [spring-boot-rabbitmq](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-rabbitmq): using AMQP and RabbitMQ
-- [spring-boot-scheduler](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-scheduler):Timed tasks developed using Spring Boot
-- [spring-boot-web](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-web):Web projects developed using Spring Boot
-- [spring-boot-mail](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mail):Mail system developed using Spring Boot
-- [spring-boot-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-mongodb):Spring Boot + Mongodb
-- [spring-boot-multi-mongodb](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-multi-mongodb):Spring Boot + multiMongodb
-- [spring-boot-package-war](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-package-war):Spring Boot package war
-- [spring-boot-shiro](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-shiro):spring boot shiro rbac demo
-- [spring-boot-file-upload](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-file-upload):Spring Boot upload file demo
-- [spring-boot-fastDFS](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-fastDFS):Spring Boot Integrate FastDFS upload delete and so on
-- [spring-boot-actuator](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-actuator):Spring Boot Actuator demo
-- [spring-boot-admin-simple](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-admin-simple):Spring Boot Admin demo
-- [spring-boot-banner](https://github.com/ityouknow/spring-boot-examples/tree/master/spring-boot-banner):Spring Boot Cumtom Banner
diff --git a/dockercompose-springboot-mysql-nginx/app/Dockerfile b/dockercompose-springboot-mysql-nginx/app/Dockerfile
index 6ae65e4e7..128ca1d00 100644
--- a/dockercompose-springboot-mysql-nginx/app/Dockerfile
+++ b/dockercompose-springboot-mysql-nginx/app/Dockerfile
@@ -1 +1 @@
-FROM maven:3.5-jdk-8
\ No newline at end of file
+FROM maven:3.8.3-openjdk-17
diff --git a/dockercompose-springboot-mysql-nginx/app/pom.xml b/dockercompose-springboot-mysql-nginx/app/pom.xml
index 1dc59f64b..4a8f04b98 100644
--- a/dockercompose-springboot-mysql-nginx/app/pom.xml
+++ b/dockercompose-springboot-mysql-nginx/app/pom.xml
@@ -14,12 +14,13 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.RELEASE
+ 3.0.0
UTF-8
- 1.8
+ UTF-8
+ 17
@@ -38,7 +39,17 @@
org.springframework.boot
spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
diff --git a/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/controller/VisitorController.java b/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/controller/VisitorController.java
index 583be103f..a73a030e0 100644
--- a/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/controller/VisitorController.java
+++ b/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/controller/VisitorController.java
@@ -6,7 +6,7 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
@RestController
public class VisitorController {
diff --git a/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/entity/Visitor.java b/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/entity/Visitor.java
index 43cfa34b0..8db97fe96 100644
--- a/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/entity/Visitor.java
+++ b/dockercompose-springboot-mysql-nginx/app/src/main/java/com/neo/entity/Visitor.java
@@ -1,9 +1,9 @@
package com.neo.entity;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
@Entity
public class Visitor {
diff --git a/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-dev.properties b/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-dev.properties
index 25126f01f..0d8ae3646 100644
--- a/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-dev.properties
+++ b/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-dev.properties
@@ -1,4 +1,4 @@
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
-spring.datasource.driver-class-name=com.mysql.jdbc.Driver
\ No newline at end of file
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-docker.properties b/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-docker.properties
index eacae6203..60acaa93e 100644
--- a/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-docker.properties
+++ b/dockercompose-springboot-mysql-nginx/app/src/main/resources/application-docker.properties
@@ -1,4 +1,4 @@
spring.datasource.url=jdbc:mysql://mysql:3306/test
spring.datasource.username=root
spring.datasource.password=root
-spring.datasource.driver-class-name=com.mysql.jdbc.Driver
\ No newline at end of file
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/dockercompose-springboot-mysql-nginx/app/src/main/resources/application.properties b/dockercompose-springboot-mysql-nginx/app/src/main/resources/application.properties
index 242edfd64..c6c99312c 100644
--- a/dockercompose-springboot-mysql-nginx/app/src/main/resources/application.properties
+++ b/dockercompose-springboot-mysql-nginx/app/src/main/resources/application.properties
@@ -1,5 +1,5 @@
spring.jpa.properties.hibernate.hbm2ddl.auto=update
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.profiles.active=dev
\ No newline at end of file
diff --git a/dockercompose-springboot-mysql-nginx/docker-compose.yaml b/dockercompose-springboot-mysql-nginx/docker-compose.yaml
index 028978f5b..ba38d573f 100644
--- a/dockercompose-springboot-mysql-nginx/docker-compose.yaml
+++ b/dockercompose-springboot-mysql-nginx/docker-compose.yaml
@@ -5,8 +5,8 @@ services:
image: nginx:1.13
restart: always
ports:
- - 80:80
- - 443:443
+ - 81:81
+ - 445:445
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
@@ -18,7 +18,7 @@ services:
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: '%'
ports:
- - "3306:3306"
+ - "3308:3308"
restart: always
app:
diff --git a/spring-boot-banner/pom.xml b/spring-boot-banner/pom.xml
index 763b87317..bb57ab10c 100644
--- a/spring-boot-banner/pom.xml
+++ b/spring-boot-banner/pom.xml
@@ -5,7 +5,7 @@
com.example
spring-boot-banner
- 2.0.0
+ 3.0.0
jar
Spring Boot banner
@@ -14,13 +14,14 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.RELEASE
+ 3.0.0
+
UTF-8
UTF-8
- 1.8
+ 17
diff --git a/spring-boot-commandLineRunner/pom.xml b/spring-boot-commandLineRunner/pom.xml
index 3dd6ee720..651f81439 100644
--- a/spring-boot-commandLineRunner/pom.xml
+++ b/spring-boot-commandLineRunner/pom.xml
@@ -14,13 +14,13 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.RELEASE
+ 3.0.0
UTF-8
UTF-8
- 1.8
+ 17
diff --git a/spring-boot-docker/pom.xml b/spring-boot-docker/pom.xml
index 17946da0c..0854143e9 100644
--- a/spring-boot-docker/pom.xml
+++ b/spring-boot-docker/pom.xml
@@ -14,15 +14,17 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.RELEASE
+ 3.0.0
UTF-8
- 1.8
+ UTF-8
+ 17
springboot
+
org.springframework.boot
@@ -31,7 +33,17 @@
org.springframework.boot
spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
diff --git a/spring-boot-docker/src/main/docker/Dockerfile b/spring-boot-docker/src/main/docker/Dockerfile
index be52a4852..153350ca8 100644
--- a/spring-boot-docker/src/main/docker/Dockerfile
+++ b/spring-boot-docker/src/main/docker/Dockerfile
@@ -1,4 +1,4 @@
-FROM openjdk:8-jdk-alpine
+FROM openjdk:17-jdk-alpine
VOLUME /tmp
ADD spring-boot-docker-1.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
\ No newline at end of file
diff --git a/spring-boot-docker/src/test/java/com/neo/DockerApplicationTests.java b/spring-boot-docker/src/test/java/com/neo/DockerApplicationTests.java
index b08b68913..341a10378 100644
--- a/spring-boot-docker/src/test/java/com/neo/DockerApplicationTests.java
+++ b/spring-boot-docker/src/test/java/com/neo/DockerApplicationTests.java
@@ -3,7 +3,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
diff --git a/spring-boot-file-upload/pom.xml b/spring-boot-file-upload/pom.xml
index 731cfa08c..fd25297d2 100644
--- a/spring-boot-file-upload/pom.xml
+++ b/spring-boot-file-upload/pom.xml
@@ -12,11 +12,13 @@
org.springframework.boot
spring-boot-starter-parent
- 1.5.9.RELEASE
+ 3.0.0
+
- 1.8
+ UTF-8
+ 17
@@ -28,12 +30,6 @@
org.springframework.boot
spring-boot-starter-thymeleaf
-
- org.springframework.boot
- spring-boot-devtools
- true
-
-
diff --git a/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java b/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java
index 6e355e38d..059ae73fc 100644
--- a/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java
+++ b/spring-boot-file-upload/src/main/java/com/neo/FileUploadWebApplication.java
@@ -3,8 +3,8 @@
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
-import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
+import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@@ -16,8 +16,8 @@ public static void main(String[] args) throws Exception {
//Tomcat large file upload connection reset
@Bean
- public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {
- TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
+ public TomcatServletWebServerFactory tomcatEmbedded() {
+ TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol>)) {
//-1 means unlimited
diff --git a/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java b/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java
index 8f5caf6cc..fb39f468e 100644
--- a/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java
+++ b/spring-boot-file-upload/src/main/java/com/neo/controller/GlobalExceptionHandler.java
@@ -12,7 +12,8 @@ public class GlobalExceptionHandler {
//4.3.5 supports RedirectAttributes redirectAttributes
@ExceptionHandler(MultipartException.class)
public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) {
- redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
+ System.out.printf(e.getMessage());
+ redirectAttributes.addFlashAttribute("message", e.getMessage());
return "redirect:/uploadStatus";
}
}
diff --git a/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java b/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java
index 13d3ab467..f72b2026a 100644
--- a/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java
+++ b/spring-boot-file-upload/src/main/java/com/neo/controller/UploadController.java
@@ -24,7 +24,7 @@ public String index() {
@PostMapping("/upload") // //new annotation since 4.3
public String singleFileUpload(@RequestParam("file") MultipartFile file,
- RedirectAttributes redirectAttributes) {
+ RedirectAttributes redirectAttributes) {
if (file.isEmpty()) {
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
return "redirect:uploadStatus";
@@ -33,16 +33,20 @@ public String singleFileUpload(@RequestParam("file") MultipartFile file,
try {
// Get the file and save it somewhere
byte[] bytes = file.getBytes();
+ Path dir = Paths.get(UPLOADED_FOLDER);
Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
+ // Create parent dir if not exists
+ if(!Files.exists(dir)) {
+ Files.createDirectories(dir);
+ }
Files.write(path, bytes);
-
redirectAttributes.addFlashAttribute("message",
- "You successfully uploaded '" + file.getOriginalFilename() + "'");
+ "You successfully uploaded '" + file.getOriginalFilename() + "'");
} catch (IOException e) {
+ redirectAttributes.addFlashAttribute("message", "Server throw IOException");
e.printStackTrace();
}
-
return "redirect:/uploadStatus";
}
diff --git a/spring-boot-file-upload/src/main/resources/application.properties b/spring-boot-file-upload/src/main/resources/application.properties
index 8ec671da4..9df793bc3 100644
--- a/spring-boot-file-upload/src/main/resources/application.properties
+++ b/spring-boot-file-upload/src/main/resources/application.properties
@@ -1,11 +1,4 @@
#http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
#search multipart
-spring.http.multipart.max-file-size=10MB
-spring.http.multipart.max-request-size=10MB
-
-#spring.http.multipart.enabled=true #\u9ED8\u8BA4\u652F\u6301\u6587\u4EF6\u4E0A\u4F20.
-#spring.http.multipart.file-size-threshold=0 #\u652F\u6301\u6587\u4EF6\u5199\u5165\u78C1\u76D8.
-#spring.http.multipart.location= # \u4E0A\u4F20\u6587\u4EF6\u7684\u4E34\u65F6\u76EE\u5F55
-#spring.http.multipart.max-file-size=1Mb # \u6700\u5927\u652F\u6301\u6587\u4EF6\u5927\u5C0F
-#spring.http.multipart.max-request-size=10Mb # \u6700\u5927\u652F\u6301\u8BF7\u6C42\u5927\u5C0F
-
+spring.servlet.multipart.max-file-size=10000MB
+spring.servlet.multipart.max-request-size=10000MB
\ No newline at end of file
diff --git a/spring-boot-hello/pom.xml b/spring-boot-hello/pom.xml
index eba435698..ae54d9067 100644
--- a/spring-boot-hello/pom.xml
+++ b/spring-boot-hello/pom.xml
@@ -14,12 +14,13 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.RELEASE
+ 3.0.0
+
UTF-8
- 1.8
+ 17
@@ -30,7 +31,6 @@
org.springframework.boot
spring-boot-starter-test
- test
diff --git a/spring-boot-hello/src/main/java/com/neo/controller/HelloController.java b/spring-boot-hello/src/main/java/com/neo/controller/HelloController.java
index 2c1c06de1..c6da75a69 100644
--- a/spring-boot-hello/src/main/java/com/neo/controller/HelloController.java
+++ b/spring-boot-hello/src/main/java/com/neo/controller/HelloController.java
@@ -8,6 +8,6 @@ public class HelloController {
@RequestMapping("/")
public String index() {
- return "Hello Spring Boot 2.0!";
+ return "Hello Spring Boot 3.x!";
}
}
\ No newline at end of file
diff --git a/spring-boot-hello/src/test/java/com/neo/HelloApplicationTests.java b/spring-boot-hello/src/test/java/com/neo/HelloApplicationTests.java
index 09ba4ff06..0c8be4b44 100644
--- a/spring-boot-hello/src/test/java/com/neo/HelloApplicationTests.java
+++ b/spring-boot-hello/src/test/java/com/neo/HelloApplicationTests.java
@@ -1,18 +1,16 @@
package com.neo;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.junit4.SpringRunner;
-@RunWith(SpringRunner.class)
+
@SpringBootTest
public class HelloApplicationTests {
+
@Test
- public void contextLoads() {
- System.out.println("Hello Spring Boot 2.0!");
+ void contextLoads() {
+ System.out.println("Hello Spring Boot 2.x!");
}
}
diff --git a/spring-boot-helloWorld/pom.xml b/spring-boot-helloWorld/pom.xml
index c8280ef2e..039ba9688 100644
--- a/spring-boot-helloWorld/pom.xml
+++ b/spring-boot-helloWorld/pom.xml
@@ -5,7 +5,7 @@
com.neo
spring-boot-helloworld
- 0.0.1-SNAPSHOT
+ 1.0.0-SNAPSHOT
jar
spring-boot-helloworld
@@ -14,46 +14,43 @@
org.springframework.boot
spring-boot-starter-parent
- 1.5.6.RELEASE
+ 3.0.0
UTF-8
- 1.8
+ 17
org.springframework.boot
- spring-boot-starter
+ spring-boot-starter-web
-
org.springframework.boot
spring-boot-starter-test
test
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-devtools
- true
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
-
+
org.springframework.boot
spring-boot-maven-plugin
-
- true
-
diff --git a/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java b/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java
index 1faf3f2e7..7fca0a8d3 100644
--- a/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java
+++ b/spring-boot-helloWorld/src/test/java/com/neo/ApplicationTests.java
@@ -1,12 +1,8 @@
package com.neo;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.junit4.SpringRunner;
-@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
diff --git a/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java b/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java
index d42211135..987f9eb7f 100644
--- a/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java
+++ b/spring-boot-helloWorld/src/test/java/com/neo/controller/HelloTests.java
@@ -1,39 +1,37 @@
package com.neo.controller;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
-import org.springframework.mock.web.MockServletContext;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
@RunWith(SpringRunner.class)
-@SpringBootTest
+@WebMvcTest(HelloWorldController.class)
public class HelloTests {
-
+ @Autowired
private MockMvc mvc;
- @Before
- public void setUp() throws Exception {
- mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
- }
-
@Test
public void getHello() throws Exception {
- mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
- .andExpect(status().isOk())
- .andExpect(content().string(equalTo("Hello World")));
+ mvc.perform(MockMvcRequestBuilders
+ .get("/hello")
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andExpect(content()
+ .string(equalTo("Hello World")));
}
}
\ No newline at end of file
diff --git a/spring-boot-jpa-thymeleaf-curd/pom.xml b/spring-boot-jpa-thymeleaf-curd/pom.xml
index caa8ecc56..49c037386 100644
--- a/spring-boot-jpa-thymeleaf-curd/pom.xml
+++ b/spring-boot-jpa-thymeleaf-curd/pom.xml
@@ -7,11 +7,13 @@
org.springframework.boot
spring-boot-starter-parent
- 1.5.6.RELEASE
+ 3.0.0
+
- 1.8
+ UTF-8
+ 17
@@ -31,20 +33,12 @@
mysql
mysql-connector-java
-
- org.springframework.boot
- spring-boot-devtools
- true
-
org.springframework.boot
spring-boot-maven-plugin
-
- true
-
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java
index 92f4c0aec..20dc3f130 100644
--- a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java
+++ b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/JpaThymeleafApplication.java
@@ -3,7 +3,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/model/User.java b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..c8f9f1c59
--- /dev/null
+++ b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/model/User.java
@@ -0,0 +1,55 @@
+package com.neo.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+
+@Entity
+public class User {
+ @Id
+ @GeneratedValue
+ private long id;
+ @Column(nullable = false, unique = true)
+ private String userName;
+ @Column(nullable = false)
+ private String password;
+ @Column(nullable = false)
+ private int age;
+
+ public long getId() {
+ return id;
+ }
+
+ public User setId(long id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public User setUserName(String userName) {
+ this.userName = userName;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public User setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public User setAge(int age) {
+ this.age = age;
+ return this;
+ }
+}
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java
index 14821f515..f6a00c8c3 100644
--- a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java
+++ b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/repository/UserRepository.java
@@ -1,11 +1,11 @@
package com.neo.repository;
-import com.neo.entity.User;
+import com.neo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository {
User findById(long id);
- Long deleteById(Long id);
+ void deleteById(Long id);
}
\ No newline at end of file
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java
index be9becb4e..ba82b95f2 100644
--- a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java
+++ b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/UserService.java
@@ -1,6 +1,6 @@
package com.neo.service;
-import com.neo.entity.User;
+import com.neo.model.User;
import java.util.List;
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java
index 8e66fad24..a8a956174 100644
--- a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java
+++ b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/service/impl/UserServiceImpl.java
@@ -1,12 +1,11 @@
package com.neo.service.impl;
-import com.neo.entity.User;
+import com.neo.model.User;
import com.neo.repository.UserRepository;
import com.neo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.util.ArrayList;
import java.util.List;
@Service
@@ -37,7 +36,7 @@ public void edit(User user) {
@Override
public void delete(long id) {
- userRepository.delete(id);
+ userRepository.deleteById(id);
}
}
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java
index 02eef58ae..c8800eaa7 100644
--- a/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java
+++ b/spring-boot-jpa-thymeleaf-curd/src/main/java/com/neo/web/UserController.java
@@ -1,14 +1,12 @@
package com.neo.web;
-import com.neo.entity.User;
+import com.neo.model.User;
import com.neo.service.UserService;
import org.springframework.stereotype.Controller;
-import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import javax.annotation.Resource;
+import jakarta.annotation.Resource;
import java.util.List;
@Controller
diff --git a/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties b/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties
index 65ff9c384..b01900159 100644
--- a/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties
+++ b/spring-boot-jpa-thymeleaf-curd/src/main/resources/application.properties
@@ -1,10 +1,10 @@
spring.datasource.url=jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
-spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-spring.jpa.properties.hibernate.hbm2ddl.auto=update
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
+spring.jpa.properties.hibernate.hbm2ddl.auto=create
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql= true
-spring.thymeleaf.cache=false
\ No newline at end of file
+spring.thymeleaf.cache=false
diff --git a/spring-boot-jpa/spring-boot-jpa/pom.xml b/spring-boot-jpa/spring-boot-jpa/pom.xml
new file mode 100644
index 000000000..8bf9a79ba
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-Jpa
+ 1.0.0
+ jar
+
+ spring-boot-Jpa
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/JpaApplication.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/JpaApplication.java
new file mode 100644
index 000000000..7df2339ea
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/JpaApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class JpaApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(JpaApplication.class, args);
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/Address.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/Address.java
new file mode 100644
index 000000000..973364706
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/Address.java
@@ -0,0 +1,59 @@
+package com.neo.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+
+@Entity
+public class Address {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false, length = 30)
+ private Long userId;
+ private String province;
+ private String city;
+ private String street;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public String getProvince() {
+ return province;
+ }
+
+ public void setProvince(String province) {
+ this.province = province;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/User.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..d82b98d99
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/User.java
@@ -0,0 +1,83 @@
+package com.neo.model;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+
+@Entity
+public class User {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false, unique = true, length = 30)
+ private String userName;
+ @Column(nullable = false)
+ private String passWord;
+ @Column(nullable = false, unique = true, length = 30)
+ private String email;
+ @Column(nullable = true, unique = true, length = 30)
+ private String nickName;
+ @Column(nullable = false)
+ private String regTime;
+
+ public User() {
+ }
+
+ public User(String userName, String passWord, String email, String nickName, String regTime) {
+ this.userName = userName;
+ this.passWord = passWord;
+ this.email = email;
+ this.nickName = nickName;
+ this.regTime = regTime;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public String getRegTime() {
+ return regTime;
+ }
+
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserDetail.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserDetail.java
new file mode 100644
index 000000000..0f11f0527
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserDetail.java
@@ -0,0 +1,102 @@
+package com.neo.model;
+
+
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import jakarta.persistence.*;
+import java.io.Serializable;
+
+@Entity
+public class UserDetail {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false, unique = true, length = 30)
+ private Long userId;
+ private Integer age;
+ private String realName;
+ private String status;
+ private String hobby;
+ private String introduction;
+ private String lastLoginIp;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getRealName() {
+ return realName;
+ }
+
+ public void setRealName(String realName) {
+ this.realName = realName;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getHobby() {
+ return hobby;
+ }
+
+ public void setHobby(String hobby) {
+ this.hobby = hobby;
+ }
+
+ public String getIntroduction() {
+ return introduction;
+ }
+
+ public void setIntroduction(String introduction) {
+ this.introduction = introduction;
+ }
+
+ public String getLastLoginIp() {
+ return lastLoginIp;
+ }
+
+ public void setLastLoginIp(String lastLoginIp) {
+ this.lastLoginIp = lastLoginIp;
+ }
+
+ @Override
+ public String toString() {
+ return "UserDetail{" +
+ "id=" + id +
+ ", userId=" + userId +
+ ", age=" + age +
+ ", realName='" + realName + '\'' +
+ ", status='" + status + '\'' +
+ ", hobby='" + hobby + '\'' +
+ ", introduction='" + introduction + '\'' +
+ ", lastLoginIp='" + lastLoginIp + '\'' +
+ '}';
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserInfo.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserInfo.java
new file mode 100644
index 000000000..5a5ae5eb3
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/model/UserInfo.java
@@ -0,0 +1,8 @@
+package com.neo.model;
+
+public interface UserInfo {
+ String getUserName();
+ String getEmail();
+ String getHobby();
+ String getIntroduction();
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/param/UserDetailParam.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/param/UserDetailParam.java
new file mode 100644
index 000000000..b87af7fec
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/param/UserDetailParam.java
@@ -0,0 +1,65 @@
+package com.neo.param;
+
+
+import com.neo.model.Address;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchMode;
+
+import jakarta.persistence.*;
+
+public class UserDetailParam {
+ private String userId;
+ private Integer minAge;
+ private Integer maxAge;
+ private String realName;
+ private String introduction;
+ private String city;
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public Integer getMinAge() {
+ return minAge;
+ }
+
+ public void setMinAge(Integer minAge) {
+ this.minAge = minAge;
+ }
+
+ public Integer getMaxAge() {
+ return maxAge;
+ }
+
+ public void setMaxAge(Integer maxAge) {
+ this.maxAge = maxAge;
+ }
+
+ public String getRealName() {
+ return realName;
+ }
+
+ public void setRealName(String realName) {
+ this.realName = realName;
+ }
+
+ public String getIntroduction() {
+ return introduction;
+ }
+
+ public void setIntroduction(String introduction) {
+ this.introduction = introduction;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/AddressRepository.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/AddressRepository.java
new file mode 100644
index 000000000..3bba02753
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/AddressRepository.java
@@ -0,0 +1,7 @@
+package com.neo.repository;
+
+import com.neo.model.Address;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AddressRepository extends JpaRepository {
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserDetailRepository.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserDetailRepository.java
new file mode 100644
index 000000000..e133b0564
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserDetailRepository.java
@@ -0,0 +1,20 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import com.neo.model.UserDetail;
+import com.neo.model.UserInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+
+public interface UserDetailRepository extends JpaSpecificationExecutor,JpaRepository {
+
+ UserDetail findByHobby(String hobby);
+
+ @Query("select u.userName as userName, u.email as email, d.introduction as introduction , d.hobby as hobby from User u , UserDetail d " +
+ "where u.id=d.userId and d.hobby = ?1 ")
+ List findUserInfo(String hobby);
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserRepository.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..8318068a5
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,40 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.transaction.annotation.Transactional;
+
+
+public interface UserRepository extends JpaRepository {
+
+ User findByUserName(String userName);
+
+ User findByUserNameOrEmail(String username, String email);
+
+ @Transactional(timeout = 10)
+ @Modifying
+ @Query("update User set userName = ?1 where id = ?2")
+ int modifyById(String userName, Long id);
+
+ @Transactional
+ @Modifying
+ @Query("delete from User where id = ?1")
+ void deleteById(Long id);
+
+ @Query("select u from User u where u.email = ?1")
+ User findByEmail(String email);
+
+ @Query("select u from User u")
+ Page findALL(Pageable pageable);
+
+ Page findByNickName(String nickName, Pageable pageable);
+
+ Slice findByNickNameAndEmail(String nickName, String email,Pageable pageable);
+
+
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailService.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailService.java
new file mode 100644
index 000000000..a5d14ead7
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailService.java
@@ -0,0 +1,10 @@
+package com.neo.service;
+
+import com.neo.model.UserDetail;
+import com.neo.param.UserDetailParam;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+public interface UserDetailService {
+ public Page findByCondition(UserDetailParam detailParam, Pageable pageable);
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailServiceImpl.java b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailServiceImpl.java
new file mode 100644
index 000000000..bc38ec475
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/java/com/neo/service/UserDetailServiceImpl.java
@@ -0,0 +1,48 @@
+package com.neo.service;
+
+import com.mysql.cj.util.StringUtils;
+import com.neo.model.UserDetail;
+import com.neo.param.UserDetailParam;
+import com.neo.repository.UserDetailRepository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import jakarta.annotation.Resource;
+import jakarta.persistence.criteria.Predicate;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class UserDetailServiceImpl implements UserDetailService{
+
+ @Resource
+ private UserDetailRepository userDetailRepository;
+
+ @Override
+ public Page findByCondition(UserDetailParam detailParam, Pageable pageable){
+
+ return userDetailRepository.findAll((root, query, cb) -> {
+ List predicates = new ArrayList();
+ //equal 示例
+ if (!StringUtils.isNullOrEmpty(detailParam.getIntroduction())){
+ predicates.add(cb.equal(root.get("introduction"),detailParam.getIntroduction()));
+ }
+ //like 示例
+ if (!StringUtils.isNullOrEmpty(detailParam.getRealName())){
+ predicates.add(cb.like(root.get("realName"),"%"+detailParam.getRealName()+"%"));
+ }
+ //between 示例
+ if (detailParam.getMinAge()!=null && detailParam.getMaxAge()!=null) {
+ Predicate agePredicate = cb.between(root.get("age"), detailParam.getMinAge(), detailParam.getMaxAge());
+ predicates.add(agePredicate);
+ }
+ //greaterThan 大于等于示例
+ if (detailParam.getMinAge()!=null){
+ predicates.add(cb.greaterThan(root.get("age"),detailParam.getMinAge()));
+ }
+ return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
+ }, pageable);
+
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/main/resources/application.properties b/spring-boot-jpa/spring-boot-jpa/src/main/resources/application.properties
new file mode 100644
index 000000000..bdde31fb0
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/main/resources/application.properties
@@ -0,0 +1,12 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.hikari.maxLifeTime=600000
+
+spring.jpa.properties.hibernate.hbm2ddl.auto=create
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
+#sql\u8F93\u51FA
+spring.jpa.show-sql=true
+#format\u4E00\u4E0Bsql\u8FDB\u884C\u8F93\u51FA
+spring.jpa.properties.hibernate.format_sql=true
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/JpaApplicationTests.java b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/JpaApplicationTests.java
new file mode 100644
index 000000000..4fe4fdbe0
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/JpaApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 JpaApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/JpaSpecificationTests.java b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/JpaSpecificationTests.java
new file mode 100644
index 000000000..312f78713
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/JpaSpecificationTests.java
@@ -0,0 +1,38 @@
+package com.neo.repository;
+
+import com.neo.model.UserDetail;
+import com.neo.param.UserDetailParam;
+import com.neo.service.UserDetailService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import jakarta.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class JpaSpecificationTests {
+
+ @Resource
+ private UserDetailService userDetailService;
+
+ @Test
+ public void testFindByCondition() {
+ int page=0,size=10;
+ Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending());
+ UserDetailParam param=new UserDetailParam();
+ param.setIntroduction("程序员");
+ param.setMinAge(10);
+ param.setMaxAge(30);
+ Page page1=userDetailService.findByCondition(param,pageable);
+ for (UserDetail userDetail:page1){
+ System.out.println("userDetail: "+userDetail.toString());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserDetailRepositoryTests.java b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserDetailRepositoryTests.java
new file mode 100644
index 000000000..08918cbb7
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserDetailRepositoryTests.java
@@ -0,0 +1,55 @@
+package com.neo.repository;
+
+import com.neo.model.Address;
+import com.neo.model.UserDetail;
+import com.neo.model.UserInfo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import jakarta.annotation.Resource;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserDetailRepositoryTests {
+
+ @Resource
+ private AddressRepository addressRepository;
+ @Resource
+ private UserDetailRepository userDetailRepository;
+
+ @Test
+ public void testSaveAddress() {
+ Address address=new Address();
+ address.setUserId(1L);
+ address.setCity("北京");
+ address.setProvince("北京");
+ address.setStreet("分钟寺");
+ addressRepository.save(address);
+ }
+
+ @Test
+ public void testSaveUserDetail() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+ UserDetail userDetail=new UserDetail();
+ userDetail.setUserId(3L);
+ userDetail.setHobby("吃鸡游戏");
+ userDetail.setAge(28);
+ userDetail.setIntroduction("一个爱玩的人");
+ userDetailRepository.save(userDetail);
+ }
+
+ @Test
+ public void testUserInfo() {
+ List userInfos=userDetailRepository.findUserInfo("钓鱼");
+ for (UserInfo userInfo:userInfos){
+ System.out.println("userInfo: "+userInfo.getUserName()+"-"+userInfo.getEmail()+"-"+userInfo.getHobby()+"-"+userInfo.getIntroduction());
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserRepositoryTests.java b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
new file mode 100644
index 000000000..13bab28a7
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
@@ -0,0 +1,70 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import jakarta.annotation.Resource;
+import java.text.DateFormat;
+import java.util.Date;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTests {
+
+ @Resource
+ private UserRepository userRepository;
+
+ @Test
+ public void testSave() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+
+ userRepository.save(new User("aa", "aa123456","aa@126.com", "aa", formattedDate));
+ userRepository.save(new User("bb", "bb123456","bb@126.com", "bb", formattedDate));
+ userRepository.save(new User("cc", "cc123456","cc@126.com", "cc", formattedDate));
+
+// Assert.assertEquals(3, userRepository.findAll().size());
+// Assert.assertEquals("bb", userRepository.findByUserNameOrEmail("bb", "bb@126.com").getNickName());
+// userRepository.delete(userRepository.findByUserName("aa"));
+ }
+
+
+ @Test
+ public void testBaseQuery() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+ User user=new User("ff", "ff123456","ff@126.com", "ff", formattedDate);
+ userRepository.findAll();
+ userRepository.findById(3L);
+ userRepository.save(user);
+ user.setId(2L);
+ userRepository.delete(user);
+ userRepository.count();
+ userRepository.existsById(3L);
+ }
+
+ @Test
+ public void testCustomSql() {
+ userRepository.modifyById("neo",3L);
+ userRepository.deleteById(3L);
+ userRepository.findByEmail("ff@126.com");
+ }
+
+
+ @Test
+ public void testPageQuery() {
+ int page=1,size=2;
+ Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending());
+ userRepository.findALL(pageable);
+ userRepository.findByNickName("aa", pageable);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/pom.xml b/spring-boot-jpa/spring-boot-multi-Jpa/pom.xml
new file mode 100644
index 000000000..f6a223772
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-multi-Jpa
+ 1.0
+ jar
+
+ spring-boot-multi-Jpa
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/MultiJpaApplication.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/MultiJpaApplication.java
new file mode 100644
index 000000000..2a9a26b17
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/MultiJpaApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MultiJpaApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MultiJpaApplication.class, args);
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/DataSourceConfig.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/DataSourceConfig.java
new file mode 100644
index 000000000..09f2b757d
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/DataSourceConfig.java
@@ -0,0 +1,41 @@
+package com.neo.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import javax.sql.DataSource;
+import java.util.Map;
+
+@Configuration
+public class DataSourceConfig {
+
+ @Autowired
+ private JpaProperties jpaProperties;
+ @Autowired
+ private HibernateProperties hibernateProperties;
+
+ @Bean(name = "primaryDataSource")
+ @Primary
+ @ConfigurationProperties("spring.datasource.primary")
+ public DataSource firstDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "secondaryDataSource")
+ @ConfigurationProperties("spring.datasource.secondary")
+ public DataSource secondDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "vendorProperties")
+ public Map getVendorProperties() {
+ return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/PrimaryConfig.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/PrimaryConfig.java
new file mode 100644
index 000000000..068ac84fd
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/PrimaryConfig.java
@@ -0,0 +1,59 @@
+package com.neo.config;
+
+import java.util.Map;
+
+import jakarta.persistence.EntityManager;
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+ entityManagerFactoryRef="entityManagerFactoryPrimary",
+ transactionManagerRef="transactionManagerPrimary",
+ basePackages= { "com.neo.repository.test1" })//设置dao(repo)所在位置
+public class PrimaryConfig {
+
+ @Autowired
+ @Qualifier("primaryDataSource")
+ private DataSource primaryDataSource;
+
+ @Autowired
+ @Qualifier("vendorProperties")
+ private Map vendorProperties;
+
+ @Bean(name = "entityManagerFactoryPrimary")
+ @Primary
+ public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
+ return builder
+ .dataSource(primaryDataSource)
+ .properties(vendorProperties)
+ .packages("com.neo.model") //设置实体类所在位置
+ .persistenceUnit("primaryPersistenceUnit")
+ .build();
+ }
+
+ @Bean(name = "entityManagerPrimary")
+ @Primary
+ public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
+ return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
+ }
+
+ @Bean(name = "transactionManagerPrimary")
+ @Primary
+ PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
+ return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/SecondaryConfig.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/SecondaryConfig.java
new file mode 100644
index 000000000..81d35be79
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/config/SecondaryConfig.java
@@ -0,0 +1,54 @@
+package com.neo.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import jakarta.persistence.EntityManager;
+import javax.sql.DataSource;
+import java.util.Map;
+
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+ entityManagerFactoryRef="entityManagerFactorySecondary",
+ transactionManagerRef="transactionManagerSecondary",
+ basePackages= { "com.neo.repository.test2" })
+public class SecondaryConfig {
+
+ @Autowired
+ @Qualifier("secondaryDataSource")
+ private DataSource secondaryDataSource;
+
+ @Autowired
+ @Qualifier("vendorProperties")
+ private Map vendorProperties;
+
+ @Bean(name = "entityManagerFactorySecondary")
+ public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
+ return builder
+ .dataSource(secondaryDataSource)
+ .properties(vendorProperties)
+ .packages("com.neo.model")
+ .persistenceUnit("secondaryPersistenceUnit")
+ .build();
+ }
+
+ @Bean(name = "entityManagerSecondary")
+ public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
+ return entityManagerFactorySecondary(builder).getObject().createEntityManager();
+ }
+
+ @Bean(name = "transactionManagerSecondary")
+ PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
+ return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/model/User.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..142e81136
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/model/User.java
@@ -0,0 +1,86 @@
+package com.neo.model;
+
+
+
+import jakarta.persistence.*;
+
+import java.io.Serializable;
+
+@Entity
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+ @Column(nullable = false, unique = true)
+ private String userName;
+ @Column(nullable = false)
+ private String passWord;
+ @Column(nullable = false, unique = true)
+ private String email;
+ @Column(nullable = true, unique = true)
+ private String nickName;
+ @Column(nullable = false)
+ private String regTime;
+
+ public User() {
+ }
+
+ public User(String userName, String passWord, String email, String nickName, String regTime) {
+ this.userName = userName;
+ this.passWord = passWord;
+ this.email = email;
+ this.nickName = nickName;
+ this.regTime = regTime;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public String getRegTime() {
+ return regTime;
+ }
+
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+}
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test1/UserTest1Repository.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test1/UserTest1Repository.java
new file mode 100644
index 000000000..feecceab6
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test1/UserTest1Repository.java
@@ -0,0 +1,10 @@
+package com.neo.repository.test1;
+
+import com.neo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserTest1Repository extends JpaRepository {
+ User findById(long id);
+ User findByUserName(String userName);
+ User findByUserNameOrEmail(String username, String email);
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test2/UserTest2Repository.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test2/UserTest2Repository.java
new file mode 100644
index 000000000..45f8c24fd
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/java/com/neo/repository/test2/UserTest2Repository.java
@@ -0,0 +1,11 @@
+package com.neo.repository.test2;
+
+import com.neo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface UserTest2Repository extends JpaRepository {
+ User findById(long id);
+ User findByUserName(String userName);
+ User findByUserNameOrEmail(String username, String email);
+}
\ No newline at end of file
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/main/resources/application.properties b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/resources/application.properties
new file mode 100644
index 000000000..b7cc3f1e7
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/main/resources/application.properties
@@ -0,0 +1,16 @@
+spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.primary.username=root
+spring.datasource.primary.password=root
+spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.secondary.username=root
+spring.datasource.secondary.password=root
+spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
+
+#sql\u8F93\u51FA
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.hbm2ddl.auto=create
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
+#format\u4E00\u4E0Bsql\u8FDB\u884C\u8F93\u51FA
+spring.jpa.properties.hibernate.format_sql=true
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/MultiJpaApplicationTests.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/MultiJpaApplicationTests.java
new file mode 100644
index 000000000..c87999ccd
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/MultiJpaApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MultiJpaApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("Hello MultiJpa!");
+ }
+
+}
diff --git a/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/repository/UserRepositoryTests.java b/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
new file mode 100644
index 000000000..942a9e46d
--- /dev/null
+++ b/spring-boot-jpa/spring-boot-multi-Jpa/src/test/java/com/neo/repository/UserRepositoryTests.java
@@ -0,0 +1,57 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import com.neo.repository.test1.UserTest1Repository;
+import com.neo.repository.test2.UserTest2Repository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import jakarta.annotation.Resource;
+import java.text.DateFormat;
+import java.util.Date;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTests {
+ @Resource
+ private UserTest1Repository userTest1Repository;
+ @Resource
+ private UserTest2Repository userTest2Repository;
+
+ @Test
+ public void testSave() throws Exception {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+
+ userTest1Repository.save(new User("aa", "aa123456","aa@126.com", "aa", formattedDate));
+ userTest1Repository.save(new User("bb", "bb123456","bb@126.com", "bb", formattedDate));
+ userTest2Repository.save(new User("cc", "cc123456","cc@126.com", "cc", formattedDate));
+ }
+
+
+ @Test
+ public void testDelete() throws Exception {
+ userTest1Repository.deleteAll();
+ userTest2Repository.deleteAll();
+ }
+
+ @Test
+ public void testBaseQuery() {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+ User user=new User("ff", "ff123456","ff@126.com", "ff", formattedDate);
+ userTest1Repository.findAll();
+ userTest2Repository.findById(3l);
+ userTest2Repository.save(user);
+ user.setId(2l);
+ userTest1Repository.delete(user);
+ userTest1Repository.count();
+ userTest2Repository.findById(3l);
+ }
+
+
+}
\ No newline at end of file
diff --git a/spring-boot-mail/pom.xml b/spring-boot-mail/pom.xml
index d22376fce..f98e3ec3a 100644
--- a/spring-boot-mail/pom.xml
+++ b/spring-boot-mail/pom.xml
@@ -14,34 +14,20 @@
org.springframework.boot
spring-boot-starter-parent
- 1.5.3.RELEASE
+ 3.0.0
UTF-8
- 1.8
+ 17
-
- org.springframework.boot
- spring-boot-starter
-
org.springframework.boot
spring-boot-starter-mail
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.boot
- spring-boot-devtools
- true
-
org.springframework
spring-context-support
@@ -57,6 +43,20 @@
org.springframework.boot
spring-boot-starter-thymeleaf
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
diff --git a/spring-boot-mail/src/main/java/com/neo/MailApplication.java b/spring-boot-mail/src/main/java/com/neo/MailApplication.java
new file mode 100644
index 000000000..c0aee4155
--- /dev/null
+++ b/spring-boot-mail/src/main/java/com/neo/MailApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MailApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MailApplication.class, args);
+ }
+}
diff --git a/spring-boot-mail/src/main/java/com/neo/service/MailService.java b/spring-boot-mail/src/main/java/com/neo/service/MailService.java
index a2948541c..41df35605 100644
--- a/spring-boot-mail/src/main/java/com/neo/service/MailService.java
+++ b/spring-boot-mail/src/main/java/com/neo/service/MailService.java
@@ -5,12 +5,12 @@
*/
public interface MailService {
- public void sendSimpleMail(String to, String subject, String content);
+ void sendSimpleMail(String to, String subject, String content);
- public void sendHtmlMail(String to, String subject, String content);
+ void sendHtmlMail(String to, String subject, String content);
- public void sendAttachmentsMail(String to, String subject, String content, String filePath);
+ void sendAttachmentsMail(String to, String subject, String content, String filePath);
- public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);
+ void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);
}
diff --git a/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java b/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java
index 9053e6fb7..5e9c5d574 100644
--- a/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java
+++ b/spring-boot-mail/src/main/java/com/neo/service/impl/MailServiceImpl.java
@@ -11,8 +11,8 @@
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeMessage;
+import jakarta.mail.MessagingException;
+import jakarta.mail.internet.MimeMessage;
import java.io.File;
/**
@@ -85,6 +85,7 @@ public void sendHtmlMail(String to, String subject, String content) {
* @param content
* @param filePath
*/
+ @Override
public void sendAttachmentsMail(String to, String subject, String content, String filePath){
MimeMessage message = mailSender.createMimeMessage();
@@ -116,6 +117,7 @@ public void sendAttachmentsMail(String to, String subject, String content, Strin
* @param rscPath
* @param rscId
*/
+ @Override
public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
MimeMessage message = mailSender.createMimeMessage();
diff --git a/spring-boot-mail/src/main/resources/application.properties b/spring-boot-mail/src/main/resources/application.properties
index dcbb52168..f7610b3c5 100644
--- a/spring-boot-mail/src/main/resources/application.properties
+++ b/spring-boot-mail/src/main/resources/application.properties
@@ -1,9 +1,10 @@
spring.application.name=spirng-boot-mail
-spring.mail.host=smtp.163.com
-spring.mail.username=xxoo@xxoo.com
-spring.mail.password=xxoo
+spring.mail.host=smtp.126.com
+spring.mail.username=xxxx@126.com
+spring.mail.password=Zxxxxxxx
+
spring.mail.default-encoding=UTF-8
-mail.fromMail.addr=xxoo@xxoo.com
+mail.fromMail.addr=ixxxxw@126.com
diff --git a/spring-boot-mail/src/test/java/com/neo/MailApplicationTests.java b/spring-boot-mail/src/test/java/com/neo/MailApplicationTests.java
new file mode 100644
index 000000000..7a9e7a09b
--- /dev/null
+++ b/spring-boot-mail/src/test/java/com/neo/MailApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MailApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java b/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java
index 91c4bbfd2..4f49737d5 100644
--- a/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java
+++ b/spring-boot-mail/src/test/java/com/neo/service/MailServiceTest.java
@@ -38,7 +38,7 @@ public void testHtmlMail() throws Exception {
@Test
public void sendAttachmentsMail() {
- String filePath="e:\\tmp\\application.log";
+ String filePath="D:\\Log\\TaxCard.log";
mailService.sendAttachmentsMail("ityouknow@126.com", "主题:带附件的邮件", "有附件,请查收!", filePath);
}
@@ -47,7 +47,7 @@ public void sendAttachmentsMail() {
public void sendInlineResourceMail() {
String rscId = "neo006";
String content="这是有图片的邮件:
";
- String imgPath = "C:\\Users\\summer\\Pictures\\favicon.png";
+ String imgPath = "C:\\Users\\ityou\\Pictures\\logo\\smilef.png";
mailService.sendInlineResourceMail("ityouknow@126.com", "主题:这是有图片的邮件", content, imgPath, rscId);
}
diff --git a/spring-boot-memcache-spymemcached/pom.xml b/spring-boot-memcache-spymemcached/pom.xml
index 307afdb75..ae6f0c52c 100644
--- a/spring-boot-memcache-spymemcached/pom.xml
+++ b/spring-boot-memcache-spymemcached/pom.xml
@@ -14,14 +14,13 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.4.RELEASE
+ 3.0.0
UTF-8
- UTF-8
- 1.8
+ 17
@@ -37,7 +36,17 @@
org.springframework.boot
spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
diff --git a/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcachedRunner.java b/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcachedRunner.java
index e1175b654..07b0b8839 100644
--- a/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcachedRunner.java
+++ b/spring-boot-memcache-spymemcached/src/main/java/com/neo/config/MemcachedRunner.java
@@ -6,7 +6,7 @@
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
-import javax.annotation.Resource;
+import jakarta.annotation.Resource;
import java.io.IOException;
import java.net.InetSocketAddress;
diff --git a/spring-boot-memcache-spymemcached/src/main/resources/application.properties b/spring-boot-memcache-spymemcached/src/main/resources/application.properties
index 4d0269621..3102bdade 100644
--- a/spring-boot-memcache-spymemcached/src/main/resources/application.properties
+++ b/spring-boot-memcache-spymemcached/src/main/resources/application.properties
@@ -1,2 +1,2 @@
-memcache.ip=192.168.0.161
+memcache.ip=localhost
memcache.port=11211
\ No newline at end of file
diff --git a/spring-boot-memcache-spymemcached/src/test/java/com/neo/RepositoryTests.java b/spring-boot-memcache-spymemcached/src/test/java/com/neo/RepositoryTests.java
index ceaef2205..cdeea20e2 100644
--- a/spring-boot-memcache-spymemcached/src/test/java/com/neo/RepositoryTests.java
+++ b/spring-boot-memcache-spymemcached/src/test/java/com/neo/RepositoryTests.java
@@ -7,7 +7,7 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
-import javax.annotation.Resource;
+import jakarta.annotation.Resource;
@RunWith(SpringRunner.class)
@SpringBootTest
diff --git a/spring-boot-mongodb/spring-boot-mongodb/pom.xml b/spring-boot-mongodb/spring-boot-mongodb/pom.xml
new file mode 100644
index 000000000..ed9d7c5c0
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mongodb
+ 1.0.0
+ jar
+
+ spring-boot-mongodb
+ Demo project for Spring Boot and mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/MongoDBApplication.java b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/MongoDBApplication.java
new file mode 100644
index 000000000..b8c63d563
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/MongoDBApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MongoDBApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MongoDBApplication.class, args);
+ }
+}
diff --git a/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/model/User.java b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..c15340ae7
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/model/User.java
@@ -0,0 +1,46 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+public class User implements Serializable {
+ private static final long serialVersionUID = -3258839839160856613L;
+ private Long id;
+ private String userName;
+ private String passWord;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ @Override
+ public String toString() {
+ return "UserEntity{" +
+ "id=" + id +
+ ", userName='" + userName + '\'' +
+ ", passWord='" + passWord + '\'' +
+ '}';
+ }
+}
diff --git a/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/UserRepository.java b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..e1a3d4134
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,18 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+public interface UserRepository {
+
+ public void saveUser(User user);
+
+ public User findUserByUserName(String userName);
+
+ public long updateUser(User user);
+
+ public void deleteUserById(Long id);
+
+}
diff --git a/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/impl/UserRepositoryImpl.java b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/impl/UserRepositoryImpl.java
new file mode 100644
index 000000000..8c96f5a42
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/src/main/java/com/neo/repository/impl/UserRepositoryImpl.java
@@ -0,0 +1,70 @@
+package com.neo.repository.impl;
+
+import com.mongodb.client.result.UpdateResult;
+import com.neo.repository.UserRepository;
+import com.neo.model.User;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+@Component
+public class UserRepositoryImpl implements UserRepository {
+
+ @Autowired
+ private MongoTemplate mongoTemplate;
+
+ /**
+ * 创建对象
+ * @param user
+ */
+ @Override
+ public void saveUser(User user) {
+ mongoTemplate.save(user);
+ }
+
+ /**
+ * 根据用户名查询对象
+ * @param userName
+ * @return
+ */
+ @Override
+ public User findUserByUserName(String userName) {
+ Query query=new Query(Criteria.where("userName").is(userName));
+ User user = mongoTemplate.findOne(query , User.class);
+ return user;
+ }
+
+ /**
+ * 更新对象
+ * @param user
+ */
+ @Override
+ public long updateUser(User user) {
+ Query query=new Query(Criteria.where("id").is(user.getId()));
+ Update update= new Update().set("userName", user.getUserName()).set("passWord", user.getPassWord());
+ //更新查询返回结果集的第一条
+ UpdateResult result =mongoTemplate.updateFirst(query,update,User.class);
+ //更新查询返回结果集的所有
+ // mongoTemplate.updateMulti(query,update,UserEntity.class);
+ if(result!=null)
+ return result.getMatchedCount();
+ else
+ return 0;
+ }
+
+ /**
+ * 删除对象
+ * @param id
+ */
+ @Override
+ public void deleteUserById(Long id) {
+ Query query=new Query(Criteria.where("id").is(id));
+ mongoTemplate.remove(query,User.class);
+ }
+}
diff --git a/spring-boot-mongodb/spring-boot-mongodb/src/main/resources/application.properties b/spring-boot-mongodb/spring-boot-mongodb/src/main/resources/application.properties
new file mode 100644
index 000000000..d2c101751
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+spring.application.name=spring-boot-mongodb
+
+spring.data.mongodb.uri=mongodb://119.0.0.6:27017/test
+
+
diff --git a/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/MongoDBApplicationTests.java b/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/MongoDBApplicationTests.java
new file mode 100644
index 000000000..cd30276df
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/MongoDBApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MongoDBApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/repository/UserRepositoryTest.java b/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/repository/UserRepositoryTest.java
new file mode 100644
index 000000000..cb6372f02
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-mongodb/src/test/java/com/neo/repository/UserRepositoryTest.java
@@ -0,0 +1,49 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * Created by summer on 2017/5/5.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTest {
+
+ @Autowired
+ private UserRepository userDao;
+
+ @Test
+ public void testSaveUser() throws Exception {
+ User user=new User();
+ user.setId(2l);
+ user.setUserName("小明");
+ user.setPassWord("fffooo123");
+ userDao.saveUser(user);
+ }
+
+ @Test
+ public void findUserByUserName(){
+ User user= userDao.findUserByUserName("小明");
+ System.out.println("user is "+user);
+ }
+
+ @Test
+ public void updateUser(){
+ User user=new User();
+ user.setId(2l);
+ user.setUserName("天空");
+ user.setPassWord("fffxxxx");
+ userDao.updateUser(user);
+ }
+
+ @Test
+ public void deleteUserById(){
+ userDao.deleteUserById(1l);
+ }
+
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/pom.xml b/spring-boot-mongodb/spring-boot-multi-mongodb/pom.xml
new file mode 100644
index 000000000..2c9b73c78
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-multi-mongodb
+ 1.0.0
+ jar
+
+ spring-boot-multi-mongodb
+ Demo project for Spring Boot and multi mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/MultiMongodbApplication.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/MultiMongodbApplication.java
new file mode 100644
index 000000000..e33c97dae
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/MultiMongodbApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MultiMongodbApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MultiMongodbApplication.class, args);
+ }
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java
new file mode 100644
index 000000000..d047711eb
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/MultipleMongoConfig.java
@@ -0,0 +1,48 @@
+package com.neo.config;
+
+
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import com.neo.config.props.MultipleMongoProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.mongo.MongoProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.mongodb.MongoDatabaseFactory;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
+
+
+@Configuration
+public class MultipleMongoConfig {
+
+ @Autowired
+ private MultipleMongoProperties mongoProperties;
+
+ @Primary
+ @Bean(name = "primaryMongoTemplate")
+ public MongoTemplate primaryMongoTemplate() throws Exception {
+ return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
+ }
+
+ @Bean
+ @Qualifier("secondaryMongoTemplate")
+ public MongoTemplate secondaryMongoTemplate() throws Exception {
+ return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
+ }
+
+ @Bean
+ @Primary
+ public MongoDatabaseFactory primaryFactory(MongoProperties mongo) throws Exception {
+ MongoClient client = MongoClients.create(mongo.getUri());
+ return new SimpleMongoClientDatabaseFactory(client, mongoProperties.getPrimary().getDatabase());
+ }
+
+ @Bean
+ public MongoDatabaseFactory secondaryFactory(MongoProperties mongo) throws Exception {
+ MongoClient client = MongoClients.create(mongo.getUri());
+ return new SimpleMongoClientDatabaseFactory(client, mongoProperties.getSecondary().getDatabase());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java
new file mode 100644
index 000000000..076bc33d9
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/PrimaryMongoConfig.java
@@ -0,0 +1,14 @@
+package com.neo.config;
+
+import com.neo.config.props.MultipleMongoProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+
+@Configuration
+@EnableConfigurationProperties(MultipleMongoProperties.class)
+@EnableMongoRepositories(basePackages = "com.neo.repository.primary",
+ mongoTemplateRef = "primaryMongoTemplate")
+public class PrimaryMongoConfig {
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java
new file mode 100644
index 000000000..f07149bf0
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/SecondaryMongoConfig.java
@@ -0,0 +1,15 @@
+package com.neo.config;
+
+import com.neo.config.props.MultipleMongoProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+
+@Configuration
+@EnableConfigurationProperties(MultipleMongoProperties.class)
+@EnableMongoRepositories(basePackages = "com.neo.repository.secondary",
+ mongoTemplateRef = "secondaryMongoTemplate")
+public class SecondaryMongoConfig {
+
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java
new file mode 100644
index 000000000..5bf4ff66a
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/config/props/MultipleMongoProperties.java
@@ -0,0 +1,27 @@
+package com.neo.config.props;
+
+import org.springframework.boot.autoconfigure.mongo.MongoProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "mongodb")
+public class MultipleMongoProperties {
+
+ private MongoProperties primary = new MongoProperties();
+ private MongoProperties secondary = new MongoProperties();
+
+ public MongoProperties getPrimary() {
+ return primary;
+ }
+
+ public void setPrimary(MongoProperties primary) {
+ this.primary = primary;
+ }
+
+ public MongoProperties getSecondary() {
+ return secondary;
+ }
+
+ public void setSecondary(MongoProperties secondary) {
+ this.secondary = secondary;
+ }
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/model/User.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..b5cd0a861
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/model/User.java
@@ -0,0 +1,49 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+
+public class User implements Serializable {
+ private static final long serialVersionUID = -3258839839160856613L;
+ private String id;
+ private String userName;
+ private String passWord;
+
+ public User(String userName, String passWord) {
+ this.userName = userName;
+ this.passWord = passWord;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "id='" + id + '\'' +
+ ", userName='" + userName + '\'' +
+ ", passWord='" + passWord + '\'' +
+ '}';
+ }
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/primary/PrimaryRepository.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/primary/PrimaryRepository.java
new file mode 100644
index 000000000..50877eb1c
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/primary/PrimaryRepository.java
@@ -0,0 +1,10 @@
+package com.neo.repository.primary;
+
+import com.neo.model.User;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+/**
+ * @author neo
+ */
+public interface PrimaryRepository extends MongoRepository {
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/secondary/SecondaryRepository.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/secondary/SecondaryRepository.java
new file mode 100644
index 000000000..11df9153a
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/java/com/neo/repository/secondary/SecondaryRepository.java
@@ -0,0 +1,10 @@
+package com.neo.repository.secondary;
+
+import com.neo.model.User;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+/**
+ * @author neo
+ */
+public interface SecondaryRepository extends MongoRepository {
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/resources/application.properties b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/resources/application.properties
new file mode 100644
index 000000000..5884b49ca
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/main/resources/application.properties
@@ -0,0 +1,8 @@
+spring.application.name=spring-boot-multi-mongodb
+
+mongodb.primary.uri=mongodb://119.0.0.6:27017
+mongodb.primary.database=primary
+mongodb.secondary.uri=mongodb://119.0.0.6:27017
+mongodb.secondary.database=secondary
+
+
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/MultiMongodbApplicationTests.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/MultiMongodbApplicationTests.java
new file mode 100644
index 000000000..8f59e588d
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/MultiMongodbApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MultiMongodbApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/repository/MuliDatabaseTest.java b/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/repository/MuliDatabaseTest.java
new file mode 100644
index 000000000..42bf1b447
--- /dev/null
+++ b/spring-boot-mongodb/spring-boot-multi-mongodb/src/test/java/com/neo/repository/MuliDatabaseTest.java
@@ -0,0 +1,45 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import com.neo.repository.primary.PrimaryRepository;
+import com.neo.repository.secondary.SecondaryRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MuliDatabaseTest {
+
+ @Autowired
+ private PrimaryRepository primaryRepository;
+
+ @Autowired
+ private SecondaryRepository secondaryRepository;
+
+ @Test
+ public void TestSave() {
+ System.out.println("************************************************************");
+ System.out.println("测试开始");
+ System.out.println("************************************************************");
+ this.primaryRepository.save(new User("小张", "123456"));
+ this.secondaryRepository.save(new User("小王", "654321"));
+ List primaries = this.primaryRepository.findAll();
+ for (User primary : primaries) {
+ System.out.println(primary.toString());
+ }
+ List secondaries = this.secondaryRepository.findAll();
+ for (User secondary : secondaries) {
+ System.out.println(secondary.toString());
+ }
+ System.out.println("************************************************************");
+ System.out.println("测试完成");
+ System.out.println("************************************************************");
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/pom.xml b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/pom.xml
new file mode 100644
index 000000000..bc725bc84
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-annotation-mulidatasource
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-annotation-mulidatasource
+ Demo project for Spring Boot and mybatis with annotation
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 3.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/MAMApplication.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/MAMApplication.java
new file mode 100644
index 000000000..a77fe795e
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/MAMApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MAMApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MAMApplication.class, args);
+ }
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
new file mode 100644
index 000000000..2db7d6533
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
@@ -0,0 +1,51 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
+public class DataSource1Config {
+
+ @Bean(name = "test1DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test1")
+ @Primary
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test1SqlSessionFactory")
+ @Primary
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ return bean.getObject();
+ }
+
+ @Bean(name = "test1TransactionManager")
+ @Primary
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test1SqlSessionTemplate")
+ @Primary
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
new file mode 100644
index 000000000..e52928c43
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
@@ -0,0 +1,46 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
+public class DataSource2Config {
+
+ @Bean(name = "test2DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test2")
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test2SqlSessionFactory")
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ return bean.getObject();
+ }
+
+ @Bean(name = "test2TransactionManager")
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test2SqlSessionTemplate")
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
new file mode 100644
index 000000000..6ab2e6a09
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
@@ -0,0 +1,35 @@
+package com.neo.mapper.test1;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+
+public interface User1Mapper {
+
+
+ @Select("SELECT * FROM users")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ List getAll();
+
+ @Select("SELECT * FROM users WHERE id = #{id}")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ User getOne(Long id);
+
+ @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
+ void insert(User user);
+
+ @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
+ void update(User user);
+
+ @Delete("DELETE FROM users WHERE id =#{id}")
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
new file mode 100644
index 000000000..50c5c855d
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
@@ -0,0 +1,35 @@
+package com.neo.mapper.test2;
+
+import java.util.List;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import org.apache.ibatis.annotations.*;
+
+public interface User2Mapper {
+
+
+ @Select("SELECT * FROM users")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ List getAll();
+
+ @Select("SELECT * FROM users WHERE id = #{id}")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ User getOne(Long id);
+
+ @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
+ void insert(User user);
+
+ @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
+ void update(User user);
+
+ @Delete("DELETE FROM users WHERE id =#{id}")
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/model/User.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..c92c15d66
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,50 @@
+package com.neo.web;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+import com.neo.model.User;
+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 com.neo.mapper.test2.User2Mapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private User1Mapper user1Mapper;
+
+ @Autowired
+ private User2Mapper user2Mapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=user1Mapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=user2Mapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ user2Mapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ user2Mapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ user1Mapper.delete(id);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties
new file mode 100644
index 000000000..819d06c92
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/main/resources/application.properties
@@ -0,0 +1,12 @@
+mybatis.type-aliases-package=com.neo.model
+
+spring.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test1.username=root
+spring.datasource.test1.password=root
+spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test2.username=root
+spring.datasource.test2.password=root
+spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/MAMApplicationTests.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/MAMApplicationTests.java
new file mode 100644
index 000000000..8b7bbef35
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/MAMApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MAMApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
new file mode 100644
index 000000000..a20004939
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
@@ -0,0 +1,51 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+import com.neo.model.User;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User1MapperTest {
+
+ @Autowired
+ private User1Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.size());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(30l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(30l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
new file mode 100644
index 000000000..af610f6b6
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
@@ -0,0 +1,50 @@
+package com.neo.mapper;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import com.neo.mapper.test2.User2Mapper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User2MapperTest {
+
+ @Autowired
+ private User2Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+ System.out.println(userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.toString());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(30l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(30l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/users.sql b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation-mulidatasource/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/pom.xml b/spring-boot-mybatis/spring-boot-mybatis-annotation/pom.xml
new file mode 100644
index 000000000..052042284
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-annotation
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-annotation
+ Demo project for Spring Boot and mybatis
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 3.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/MybatisAnnotationApplication.java b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/MybatisAnnotationApplication.java
new file mode 100644
index 000000000..ebac358ad
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/MybatisAnnotationApplication.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("com.neo.mapper")
+public class MybatisAnnotationApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MybatisAnnotationApplication.class, args);
+ }
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java
new file mode 100644
index 000000000..0189ea95c
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/mapper/UserMapper.java
@@ -0,0 +1,40 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.model.User;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Result;
+import org.apache.ibatis.annotations.Results;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import com.neo.enums.UserSexEnum;
+
+public interface UserMapper {
+
+ @Select("SELECT * FROM users")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ List getAll();
+
+ @Select("SELECT * FROM users WHERE id = #{id}")
+ @Results({
+ @Result(property = "userSex", column = "user_sex", javaType = UserSexEnum.class),
+ @Result(property = "nickName", column = "nick_name")
+ })
+ User getOne(Long id);
+
+ @Insert("INSERT INTO users(userName,passWord,user_sex) VALUES(#{userName}, #{passWord}, #{userSex})")
+ void insert(User user);
+
+ @Update("UPDATE users SET userName=#{userName},nick_name=#{nickName} WHERE id =#{id}")
+ void update(User user);
+
+ @Delete("DELETE FROM users WHERE id =#{id}")
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/model/User.java b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..25144b362
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,47 @@
+package com.neo.web;
+
+import java.util.List;
+
+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 com.neo.model.User;
+import com.neo.mapper.UserMapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=userMapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=userMapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ userMapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ userMapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ userMapper.delete(id);
+ }
+
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/resources/application.properties b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/resources/application.properties
new file mode 100644
index 000000000..06400e91a
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+mybatis.type-aliases-package=com.neo.model
+
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/MybatisAnnotationApplicationTests.java b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/MybatisAnnotationApplicationTests.java
new file mode 100644
index 000000000..9a9777482
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/MybatisAnnotationApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MybatisAnnotationApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java
new file mode 100644
index 000000000..0e12f6fd3
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/src/test/java/com/neo/mapper/UserMapperTest.java
@@ -0,0 +1,47 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.model.User;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserMapperTest {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa1", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb1", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc1", "b123456", UserSexEnum.WOMAN));
+
+ Assert.assertEquals(3, userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ System.out.println(users.toString());
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ User user = userMapper.getOne(30l);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(30l).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-annotation/users.sql b/spring-boot-mybatis/spring-boot-mybatis-annotation/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-annotation/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/pom.xml b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/pom.xml
new file mode 100644
index 000000000..a371ebb89
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-xml-mulidatasource
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-xml-mulidatasource
+ Demo project for Spring Boot and mybatis
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 3.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/MXMApplication.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/MXMApplication.java
new file mode 100644
index 000000000..ad7b9d9d7
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/MXMApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MXMApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MXMApplication.class, args);
+ }
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
new file mode 100644
index 000000000..40bcf28d5
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource1Config.java
@@ -0,0 +1,53 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
+public class DataSource1Config {
+
+ @Bean(name = "test1DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test1")
+ @Primary
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test1SqlSessionFactory")
+ @Primary
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
+ return bean.getObject();
+ }
+
+ @Bean(name = "test1TransactionManager")
+ @Primary
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test1SqlSessionTemplate")
+ @Primary
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
new file mode 100644
index 000000000..67864089a
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/datasource/DataSource2Config.java
@@ -0,0 +1,48 @@
+package com.neo.datasource;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.sql.DataSource;
+
+/**
+ * Created by summer on 2016/11/25.
+ */
+@Configuration
+@MapperScan(basePackages = "com.neo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
+public class DataSource2Config {
+
+ @Bean(name = "test2DataSource")
+ @ConfigurationProperties(prefix = "spring.datasource.test2")
+ public DataSource testDataSource() {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean(name = "test2SqlSessionFactory")
+ public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
+ SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+ bean.setDataSource(dataSource);
+ bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
+ return bean.getObject();
+ }
+
+ @Bean(name = "test2TransactionManager")
+ public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
+ return new DataSourceTransactionManager(dataSource);
+ }
+
+ @Bean(name = "test2SqlSessionTemplate")
+ public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
+ return new SqlSessionTemplate(sqlSessionFactory);
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
new file mode 100644
index 000000000..d9502822f
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test1/User1Mapper.java
@@ -0,0 +1,19 @@
+package com.neo.mapper.test1;
+
+import com.neo.model.User;
+
+import java.util.List;
+
+public interface User1Mapper {
+
+ List getAll();
+
+ User getOne(Long id);
+
+ void insert(User user);
+
+ void update(User user);
+
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
new file mode 100644
index 000000000..d5c91ebf1
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/mapper/test2/User2Mapper.java
@@ -0,0 +1,19 @@
+package com.neo.mapper.test2;
+
+import java.util.List;
+
+import com.neo.model.User;
+
+public interface User2Mapper {
+
+ List getAll();
+
+ User getOne(Long id);
+
+ void insert(User user);
+
+ void update(User user);
+
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/model/User.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/web/UserController.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..a608500f1
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,51 @@
+package com.neo.web;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+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 com.neo.model.User;
+import com.neo.mapper.test2.User2Mapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private User1Mapper user1Mapper;
+
+ @Autowired
+ private User2Mapper user2Mapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=user1Mapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=user2Mapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ user2Mapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ user2Mapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ user1Mapper.delete(id);
+ }
+
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/application.properties b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/application.properties
new file mode 100644
index 000000000..e2e0f4a74
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/application.properties
@@ -0,0 +1,11 @@
+mybatis.config-location=classpath:mybatis/mybatis-config.xml
+
+spring.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test1.username=root
+spring.datasource.test1.password=root
+spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.test2.username=root
+spring.datasource.test2.password=root
+spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml
new file mode 100644
index 000000000..0a2ced2ce
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test1/UserMapper.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ id, userName, passWord, user_sex, nick_name
+
+
+
+
+
+
+
+ INSERT INTO
+ users
+ (userName,passWord,user_sex)
+ VALUES
+ (#{userName}, #{passWord}, #{userSex})
+
+
+
+ UPDATE
+ users
+ SET
+ userName = #{userName},
+ passWord = #{passWord},
+ nick_name = #{nickName}
+ WHERE
+ id = #{id}
+
+
+
+ DELETE FROM
+ users
+ WHERE
+ id =#{id}
+
+
+
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml
new file mode 100644
index 000000000..da3dc2e7c
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mapper/test2/UserMapper.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ id, userName, passWord, user_sex, nick_name
+
+
+
+
+
+
+
+ INSERT INTO
+ users
+ (userName,passWord,user_sex)
+ VALUES
+ (#{userName}, #{passWord}, #{userSex})
+
+
+
+ UPDATE
+ users
+ SET
+ userName = #{userName},
+ passWord = #{passWord},
+ nick_name = #{nickName}
+ WHERE
+ id = #{id}
+
+
+
+ DELETE FROM
+ users
+ WHERE
+ id =#{id}
+
+
+
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mybatis-config.xml b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mybatis-config.xml
new file mode 100644
index 000000000..56097ffb9
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/main/resources/mybatis/mybatis-config.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/MXMApplicationTests.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/MXMApplicationTests.java
new file mode 100644
index 000000000..422edba96
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/MXMApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MXMApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
new file mode 100644
index 000000000..77d2accdf
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User1MapperTest.java
@@ -0,0 +1,53 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.mapper.test1.User1Mapper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User1MapperTest {
+
+ @Autowired
+ private User1Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ System.out.println(userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.size());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ Long id =30l;
+ User user = userMapper.getOne(id);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(id).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
new file mode 100644
index 000000000..32a5da0a2
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/src/test/java/com/neo/mapper/User2MapperTest.java
@@ -0,0 +1,52 @@
+package com.neo.mapper;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+import com.neo.mapper.test2.User2Mapper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class User2MapperTest {
+
+ @Autowired
+ private User2Mapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ System.out.println(userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.toString());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+ Long id =30l;
+ User user = userMapper.getOne(id);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(id).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/users.sql b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml-mulidatasource/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/pom.xml b/spring-boot-mybatis/spring-boot-mybatis-xml/pom.xml
new file mode 100644
index 000000000..c78823202
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-mybatis-xml
+ 1.0.0
+ jar
+
+ spring-boot-mybatis-xml
+ Demo project for Spring Boot and mybatis
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 3.0.0
+
+
+ mysql
+ mysql-connector-java
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/MybatisXmlApplication.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/MybatisXmlApplication.java
new file mode 100644
index 000000000..863b95aba
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/MybatisXmlApplication.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("com.neo.mapper")
+public class MybatisXmlApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MybatisXmlApplication.class, args);
+ }
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java
new file mode 100644
index 000000000..0b8be4453
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/enums/UserSexEnum.java
@@ -0,0 +1,5 @@
+package com.neo.enums;
+
+public enum UserSexEnum {
+ MAN, WOMAN
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java
new file mode 100644
index 000000000..f08f70bf3
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/mapper/UserMapper.java
@@ -0,0 +1,19 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import com.neo.model.User;
+
+public interface UserMapper {
+
+ List getAll();
+
+ User getOne(Long id);
+
+ void insert(User user);
+
+ void update(User user);
+
+ void delete(Long id);
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/model/User.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..de501655b
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/model/User.java
@@ -0,0 +1,73 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+import com.neo.enums.UserSexEnum;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String passWord;
+ private UserSexEnum userSex;
+ private String nickName;
+
+ public User() {
+ super();
+ }
+
+ public User(String userName, String passWord, UserSexEnum userSex) {
+ super();
+ this.passWord = passWord;
+ this.userName = userName;
+ this.userSex = userSex;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassWord() {
+ return passWord;
+ }
+
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+
+ public UserSexEnum getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(UserSexEnum userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "userName " + this.userName + ", pasword " + this.passWord + "sex " + userSex.name();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..25144b362
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,47 @@
+package com.neo.web;
+
+import java.util.List;
+
+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 com.neo.model.User;
+import com.neo.mapper.UserMapper;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @RequestMapping("/getUsers")
+ public List getUsers() {
+ List users=userMapper.getAll();
+ return users;
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser(Long id) {
+ User user=userMapper.getOne(id);
+ return user;
+ }
+
+ @RequestMapping("/add")
+ public void save(User user) {
+ userMapper.insert(user);
+ }
+
+ @RequestMapping(value="update")
+ public void update(User user) {
+ userMapper.update(user);
+ }
+
+ @RequestMapping(value="/delete/{id}")
+ public void delete(@PathVariable("id") Long id) {
+ userMapper.delete(id);
+ }
+
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/application.properties b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/application.properties
new file mode 100644
index 000000000..0e2bea577
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/application.properties
@@ -0,0 +1,8 @@
+mybatis.config-location=classpath:mybatis/mybatis-config.xml
+mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
+mybatis.type-aliases-package=com.neo.model
+
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
new file mode 100644
index 000000000..b84731b11
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mapper/UserMapper.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ id, userName, passWord, user_sex, nick_name
+
+
+
+
+
+
+
+ INSERT INTO
+ users
+ (userName,passWord,user_sex)
+ VALUES
+ (#{userName}, #{passWord}, #{userSex})
+
+
+
+ UPDATE
+ users
+ SET
+ userName = #{userName},
+ passWord = #{passWord},
+ nick_name = #{nickName}
+ WHERE
+ id = #{id}
+
+
+
+ DELETE FROM
+ users
+ WHERE
+ id =#{id}
+
+
+
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml
new file mode 100644
index 000000000..56097ffb9
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/main/resources/mybatis/mybatis-config.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/MybatisXmlApplicationTests.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/MybatisXmlApplicationTests.java
new file mode 100644
index 000000000..3938dfde3
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/MybatisXmlApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 MybatisXmlApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java
new file mode 100644
index 000000000..689ee9374
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/mapper/UserMapperTest.java
@@ -0,0 +1,53 @@
+package com.neo.mapper;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.neo.model.User;
+import com.neo.enums.UserSexEnum;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserMapperTest {
+
+ @Autowired
+ private UserMapper userMapper;
+
+ @Test
+ public void testInsert() throws Exception {
+ userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN));
+ userMapper.insert(new User("bb", "b123456", UserSexEnum.WOMAN));
+ userMapper.insert(new User("cc", "b123456", UserSexEnum.WOMAN));
+
+ System.out.println(userMapper.getAll().size());
+ }
+
+ @Test
+ public void testQuery() throws Exception {
+ List users = userMapper.getAll();
+ if(users==null || users.size()==0){
+ System.out.println("is null");
+ }else{
+ System.out.println(users.toString());
+ }
+ }
+
+
+ @Test
+ public void testUpdate() throws Exception {
+
+ Long id =30l;
+ User user = userMapper.getOne(id);
+ System.out.println(user.toString());
+ user.setNickName("neo");
+ userMapper.update(user);
+ Assert.assertTrue(("neo".equals(userMapper.getOne(id).getNickName())));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java b/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java
new file mode 100644
index 000000000..2fd5fa943
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/src/test/java/com/neo/web/UserControllerTest.java
@@ -0,0 +1,37 @@
+package com.neo.web;
+
+
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserControllerTest {
+ @Autowired
+ private WebApplicationContext wac;
+ private MockMvc mockMvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); //初始化MockMvc对象
+ }
+
+ @Test
+ public void getUsers() throws Exception {
+ mockMvc.perform(MockMvcRequestBuilders.post("/getUsers")
+ .accept(MediaType.APPLICATION_JSON_UTF8)).andDo(print());
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-mybatis/spring-boot-mybatis-xml/users.sql b/spring-boot-mybatis/spring-boot-mybatis-xml/users.sql
new file mode 100644
index 000000000..c8a2769d5
--- /dev/null
+++ b/spring-boot-mybatis/spring-boot-mybatis-xml/users.sql
@@ -0,0 +1,30 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server : 本地
+Source Server Version : 50505
+Source Host : localhost:3306
+Source Database : test1
+
+Target Server Type : MYSQL
+Target Server Version : 50505
+File Encoding : 65001
+
+Date: 2016-11-05 21:17:33
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for `users`
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
+ `userName` varchar(32) DEFAULT NULL COMMENT '用户名',
+ `passWord` varchar(32) DEFAULT NULL COMMENT '密码',
+ `user_sex` varchar(32) DEFAULT NULL,
+ `nick_name` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
+
diff --git a/spring-boot-package/spring-boot-package-war/pom.xml b/spring-boot-package/spring-boot-package-war/pom.xml
new file mode 100644
index 000000000..208250094
--- /dev/null
+++ b/spring-boot-package/spring-boot-package-war/pom.xml
@@ -0,0 +1,72 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-package-war
+ 0.0.1-SNAPSHOT
+ war
+
+ spring-boot-package-war
+ Demo project for Spring Boot package war
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/Application.java b/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/Application.java
new file mode 100644
index 000000000..6cda50c81
--- /dev/null
+++ b/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/Application.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java b/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java
new file mode 100644
index 000000000..8becd385d
--- /dev/null
+++ b/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/ServletInitializer.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * Created by summer on 2017/5/8.
+ */
+public class ServletInitializer extends SpringBootServletInitializer {
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(Application.class);
+ }
+}
diff --git a/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java b/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java
new file mode 100644
index 000000000..7d0256b4a
--- /dev/null
+++ b/spring-boot-package/spring-boot-package-war/src/main/java/com/neo/controller/HelloWorldController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloWorldController {
+
+ @RequestMapping("/hello")
+ public String index() {
+ return "Hello World";
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package-war/src/main/resources/application.properties b/spring-boot-package/spring-boot-package-war/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java b/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java
new file mode 100644
index 000000000..457f6d8ad
--- /dev/null
+++ b/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/ApplicationTests.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java b/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java
new file mode 100644
index 000000000..582eade98
--- /dev/null
+++ b/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/controller/HelloTests.java
@@ -0,0 +1,36 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+public class HelloTests {
+
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java
new file mode 100644
index 000000000..46457724b
--- /dev/null
+++ b/spring-boot-package/spring-boot-package-war/src/test/java/com/neo/controller/HelloWorldControlerTests.java
@@ -0,0 +1,35 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+public class HelloWorldControlerTests {
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package/pom.xml b/spring-boot-package/spring-boot-package/pom.xml
new file mode 100644
index 000000000..0b26e52a0
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-package
+ 1.0.0
+ jar
+
+ spring-boot-package
+ Demo project for Spring Boot package war
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-package/spring-boot-package/src/main/java/com/neo/PackageApplication.java b/spring-boot-package/spring-boot-package/src/main/java/com/neo/PackageApplication.java
new file mode 100644
index 000000000..6611164fa
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/main/java/com/neo/PackageApplication.java
@@ -0,0 +1,19 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class PackageApplication extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(PackageApplication.class);
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(PackageApplication.class, args);
+ }
+}
diff --git a/spring-boot-package/spring-boot-package/src/main/java/com/neo/controller/HelloController.java b/spring-boot-package/spring-boot-package/src/main/java/com/neo/controller/HelloController.java
new file mode 100644
index 000000000..5e93f0dda
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/main/java/com/neo/controller/HelloController.java
@@ -0,0 +1,13 @@
+package com.neo.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+
+ @RequestMapping("/hello")
+ public String index() {
+ return "Hello World";
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package/src/main/resources/application-dev.properties b/spring-boot-package/spring-boot-package/src/main/resources/application-dev.properties
new file mode 100644
index 000000000..c83a6aaa9
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/main/resources/application-dev.properties
@@ -0,0 +1,2 @@
+info.app.name=spring-boot-test
+info.app.version= 1.0.0
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package/src/main/resources/application-pro.properties b/spring-boot-package/spring-boot-package/src/main/resources/application-pro.properties
new file mode 100644
index 000000000..5bc6c5ce3
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/main/resources/application-pro.properties
@@ -0,0 +1,2 @@
+info.app.name=spring-boot-pro
+info.app.version= 1.0.0
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package/src/main/resources/application-test.properties b/spring-boot-package/spring-boot-package/src/main/resources/application-test.properties
new file mode 100644
index 000000000..995c6d213
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/main/resources/application-test.properties
@@ -0,0 +1,2 @@
+info.app.name=spring-boot-uat
+info.app.version= 1.0.0
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package/src/main/resources/application.properties b/spring-boot-package/spring-boot-package/src/main/resources/application.properties
new file mode 100644
index 000000000..bba9dfd9a
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/main/resources/application.properties
@@ -0,0 +1,26 @@
+# \u9879\u76EEcontextPath\uFF0C\u4E00\u822C\u4E0D\u914D\u7F6E
+#server.servlet.context-path=/myspringboot
+# \u9519\u8BEF\u9875\uFF0C\u6307\u5B9A\u53D1\u751F\u9519\u8BEF\u65F6\uFF0C\u8DF3\u8F6C\u7684URL\u3002
+server.error.path=/error
+# \u670D\u52A1\u7AEF\u53E3
+server.port=8080
+# session\u6700\u5927\u8D85\u65F6\u65F6\u95F4(\u5206\u949F)\uFF0C\u9ED8\u8BA4\u4E3A30
+server.session-timeout=60
+# \u8BE5\u670D\u52A1\u7ED1\u5B9AIP\u5730\u5740\uFF0C\u542F\u52A8\u670D\u52A1\u5668\u65F6\u5982\u672C\u673A\u4E0D\u662F\u8BE5IP\u5730\u5740\u5219\u629B\u51FA\u5F02\u5E38\u542F\u52A8\u5931\u8D25\uFF0C\u53EA\u6709\u7279\u6B8A\u9700\u6C42\u7684\u60C5\u51B5\u4E0B\u624D\u914D\u7F6E
+#server.address=192.168.0.6
+
+# tomcat \u6700\u5927\u7EBF\u7A0B\u6570\uFF0C\u9ED8\u8BA4\u4E3A200
+server.tomcat.max-threads=600
+# tomcat\u7684URI\u7F16\u7801
+server.tomcat.uri-encoding=UTF-8
+# \u5B58\u653ETomcat\u7684\u65E5\u5FD7\u3001Dump\u7B49\u6587\u4EF6\u7684\u4E34\u65F6\u6587\u4EF6\u5939\uFF0C\u9ED8\u8BA4\u4E3A\u7CFB\u7EDF\u7684tmp\u6587\u4EF6\u5939
+server.tomcat.basedir=/tmp/log
+# \u6253\u5F00Tomcat\u7684Access\u65E5\u5FD7\uFF0C\u5E76\u53EF\u4EE5\u8BBE\u7F6E\u65E5\u5FD7\u683C\u5F0F
+#server.tomcat.access-log-enabled=true
+#server.tomcat.access-log-pattern=
+# accesslog\u76EE\u5F55\uFF0C\u9ED8\u8BA4\u5728basedir/logs
+#server.tomcat.accesslog.directory=
+# \u65E5\u5FD7\u6587\u4EF6\u76EE\u5F55
+logging.path=/tmp/log
+# \u65E5\u5FD7\u6587\u4EF6\u540D\u79F0\uFF0C\u9ED8\u8BA4\u4E3Aspring.log
+logging.file=myapp.log
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package/src/test/java/com/neo/PackageApplicationTests.java b/spring-boot-package/spring-boot-package/src/test/java/com/neo/PackageApplicationTests.java
new file mode 100644
index 000000000..ff737b922
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/test/java/com/neo/PackageApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 PackageApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-boot-package/spring-boot-package/src/test/java/com/neo/controller/HelloTests.java b/spring-boot-package/spring-boot-package/src/test/java/com/neo/controller/HelloTests.java
new file mode 100644
index 000000000..149543930
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/test/java/com/neo/controller/HelloTests.java
@@ -0,0 +1,36 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloTests {
+
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Hello World")));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-package/spring-boot-package/src/test/java/com/neo/controller/HelloWorldControlerTests.java b/spring-boot-package/spring-boot-package/src/test/java/com/neo/controller/HelloWorldControlerTests.java
new file mode 100644
index 000000000..d8b01a50d
--- /dev/null
+++ b/spring-boot-package/spring-boot-package/src/test/java/com/neo/controller/HelloWorldControlerTests.java
@@ -0,0 +1,34 @@
+package com.neo.controller;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class HelloWorldControlerTests {
+
+ private MockMvc mvc;
+
+ @Before
+ public void setUp() throws Exception {
+ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
+ }
+
+ @Test
+ public void getHello() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-rabbitmq/pom.xml b/spring-boot-rabbitmq/pom.xml
index b4de1e355..4a472c465 100644
--- a/spring-boot-rabbitmq/pom.xml
+++ b/spring-boot-rabbitmq/pom.xml
@@ -14,33 +14,34 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 3.0.0
UTF-8
- 1.8
+ 17
org.springframework.boot
- spring-boot-starter
+ spring-boot-starter-amqp
org.springframework.boot
spring-boot-starter-test
- test
- org.springframework.boot
- spring-boot-starter-amqp
-
-
- org.springframework.boot
- spring-boot-devtools
- true
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
@@ -49,9 +50,6 @@
org.springframework.boot
spring-boot-maven-plugin
-
- true
-
diff --git a/spring-boot-rabbitmq/src/main/java/com/neo/RabbitMQApplication.java b/spring-boot-rabbitmq/src/main/java/com/neo/RabbitMQApplication.java
new file mode 100644
index 000000000..15d177f39
--- /dev/null
+++ b/spring-boot-rabbitmq/src/main/java/com/neo/RabbitMQApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class RabbitMQApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(RabbitMQApplication.class, args);
+ }
+}
diff --git a/spring-boot-rabbitmq/src/main/resources/application.properties b/spring-boot-rabbitmq/src/main/resources/application.properties
index da5cc5ed0..dcaf54273 100644
--- a/spring-boot-rabbitmq/src/main/resources/application.properties
+++ b/spring-boot-rabbitmq/src/main/resources/application.properties
@@ -1,6 +1,7 @@
-spring.application.name=spirng-boot-rabbitmq-example
+spring.application.name=spring-boot-rabbitmq
-spring.rabbitmq.host=192.168.0.86
+spring.rabbitmq.host=192.0.0.6
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
-spring.rabbitmq.password=123456
+spring.rabbitmq.password=admin
+
diff --git a/spring-boot-rabbitmq/src/test/java/com/neo/RabbitMQApplicationTests.java b/spring-boot-rabbitmq/src/test/java/com/neo/RabbitMQApplicationTests.java
new file mode 100644
index 000000000..2bec30988
--- /dev/null
+++ b/spring-boot-rabbitmq/src/test/java/com/neo/RabbitMQApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 RabbitMQApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-redis/pom.xml b/spring-boot-redis/pom.xml
new file mode 100644
index 000000000..a358286ae
--- /dev/null
+++ b/spring-boot-redis/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-redis
+ 3.0.0-SNAPSHOT
+ jar
+
+ spring-boot-redis
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ org.apache.commons
+ commons-pool2
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.session
+ spring-session-data-redis
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-redis/src/main/java/com/neo/RedisApplication.java b/spring-boot-redis/src/main/java/com/neo/RedisApplication.java
new file mode 100644
index 000000000..9c41bedc0
--- /dev/null
+++ b/spring-boot-redis/src/main/java/com/neo/RedisApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class RedisApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(RedisApplication.class, args);
+ }
+}
diff --git a/spring-boot-redis/src/main/java/com/neo/config/RedisConfig.java b/spring-boot-redis/src/main/java/com/neo/config/RedisConfig.java
new file mode 100644
index 000000000..f26748985
--- /dev/null
+++ b/spring-boot-redis/src/main/java/com/neo/config/RedisConfig.java
@@ -0,0 +1,34 @@
+package com.neo.config;
+
+import java.lang.reflect.Method;
+
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.core.RedisTemplate;
+
+
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport{
+
+ @Bean
+ public KeyGenerator keyGenerator() {
+ return new KeyGenerator() {
+ @Override
+ public Object generate(Object target, Method method, Object... params) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(target.getClass().getName());
+ sb.append(method.getName());
+ for (Object obj : params) {
+ sb.append(obj.toString());
+ }
+ return sb.toString();
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-redis/src/main/java/com/neo/config/SessionConfig.java b/spring-boot-redis/src/main/java/com/neo/config/SessionConfig.java
new file mode 100644
index 000000000..400f03fd7
--- /dev/null
+++ b/spring-boot-redis/src/main/java/com/neo/config/SessionConfig.java
@@ -0,0 +1,9 @@
+package com.neo.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+@Configuration
+@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
+public class SessionConfig {
+}
\ No newline at end of file
diff --git a/spring-boot-redis/src/main/java/com/neo/model/User.java b/spring-boot-redis/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..045748877
--- /dev/null
+++ b/spring-boot-redis/src/main/java/com/neo/model/User.java
@@ -0,0 +1,88 @@
+package com.neo.model;
+
+import java.io.Serializable;
+
+
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private Long id;
+ private String userName;
+ private String password;
+ private String email;
+ private String nickname;
+ private String regTime;
+
+ public User() {
+ super();
+ }
+ public User(String email, String nickname, String password, String userName, String regTime) {
+ super();
+ this.email = email;
+ this.nickname = nickname;
+ this.password = password;
+ this.userName = userName;
+ this.regTime = regTime;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public String getRegTime() {
+ return regTime;
+ }
+
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "id=" + id +
+ ", userName='" + userName + '\'' +
+ ", password='" + password + '\'' +
+ ", email='" + email + '\'' +
+ ", nickname='" + nickname + '\'' +
+ ", regTime='" + regTime + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-redis/src/main/java/com/neo/web/UserController.java b/spring-boot-redis/src/main/java/com/neo/web/UserController.java
new file mode 100644
index 000000000..99166a0df
--- /dev/null
+++ b/spring-boot-redis/src/main/java/com/neo/web/UserController.java
@@ -0,0 +1,33 @@
+package com.neo.web;
+
+import jakarta.servlet.http.HttpSession;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.neo.model.User;
+
+import java.util.UUID;
+
+@RestController
+public class UserController {
+
+ @RequestMapping("/getUser")
+ @Cacheable(value="user-key")
+ public User getUser() {
+ User user=new User("aa@126.com", "aa", "aa123456", "aa","123");
+ System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
+ return user;
+ }
+
+
+ @RequestMapping("/uid")
+ String uid(HttpSession session) {
+ UUID uid = (UUID) session.getAttribute("uid");
+ if (uid == null) {
+ uid = UUID.randomUUID();
+ }
+ session.setAttribute("uid", uid);
+ return session.getId();
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-redis/src/main/resources/application.properties b/spring-boot-redis/src/main/resources/application.properties
new file mode 100644
index 000000000..2d4d7e89b
--- /dev/null
+++ b/spring-boot-redis/src/main/resources/application.properties
@@ -0,0 +1,17 @@
+# REDIS
+# Redis\u6570\u636E\u5E93\u7D22\u5F15\uFF08\u9ED8\u8BA4\u4E3A0\uFF09
+spring.redis.database=0
+# Redis\u670D\u52A1\u5668\u5730\u5740
+spring.redis.host=localhost
+# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u7AEF\u53E3
+spring.redis.port=6379
+# Redis\u670D\u52A1\u5668\u8FDE\u63A5\u5BC6\u7801\uFF08\u9ED8\u8BA4\u4E3A\u7A7A\uFF09
+spring.redis.password=
+# \u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09 \u9ED8\u8BA4 8
+spring.redis.lettuce.pool.max-active=8
+# \u8FDE\u63A5\u6C60\u6700\u5927\u963B\u585E\u7B49\u5F85\u65F6\u95F4\uFF08\u4F7F\u7528\u8D1F\u503C\u8868\u793A\u6CA1\u6709\u9650\u5236\uFF09 \u9ED8\u8BA4 -1
+spring.redis.lettuce.pool.max-wait=-1
+# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5 \u9ED8\u8BA4 8
+spring.redis.lettuce.pool.max-idle=8
+# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5 \u9ED8\u8BA4 0
+spring.redis.lettuce.pool.min-idle=0
diff --git a/spring-boot-redis/src/test/java/com/neo/RedisApplicationTests.java b/spring-boot-redis/src/test/java/com/neo/RedisApplicationTests.java
new file mode 100644
index 000000000..c92da71f7
--- /dev/null
+++ b/spring-boot-redis/src/test/java/com/neo/RedisApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class RedisApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello web");
+ }
+
+}
diff --git a/spring-boot-redis/src/test/java/com/neo/TestRedis.java b/spring-boot-redis/src/test/java/com/neo/TestRedis.java
new file mode 100644
index 000000000..fe8f86e5f
--- /dev/null
+++ b/spring-boot-redis/src/test/java/com/neo/TestRedis.java
@@ -0,0 +1,49 @@
+package com.neo;
+
+import com.neo.model.User;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.concurrent.TimeUnit;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class TestRedis {
+
+ @Autowired
+ private StringRedisTemplate stringRedisTemplate;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ @Test
+ public void test() throws Exception {
+ stringRedisTemplate.opsForValue().set("aaa", "111");
+ Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa"));
+ }
+
+ @Test
+ public void testObj() throws Exception {
+ User user=new User("aa@126.com", "aa", "aa123456", "aa","123");
+ ValueOperations operations=redisTemplate.opsForValue();
+ operations.set("com.neox", user);
+ operations.set("com.neo.f", user,1, TimeUnit.SECONDS);
+ Thread.sleep(1000);
+ //redisTemplate.delete("com.neo.f");
+ boolean exists=redisTemplate.hasKey("com.neo.f");
+ if(exists){
+ System.out.println("exists is true");
+ }else{
+ System.out.println("exists is false");
+ }
+ // Assert.assertEquals("aa", operations.get("com.neo.f").getUserName());
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-scheduler/pom.xml b/spring-boot-scheduler/pom.xml
index b3d18365d..e956d21ab 100644
--- a/spring-boot-scheduler/pom.xml
+++ b/spring-boot-scheduler/pom.xml
@@ -14,13 +14,13 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 3.0.0
UTF-8
- 1.8
+ 17
@@ -31,12 +31,17 @@
org.springframework.boot
spring-boot-starter-test
- test
-
- org.springframework.boot
- spring-boot-devtools
- true
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
@@ -45,9 +50,6 @@
org.springframework.boot
spring-boot-maven-plugin
-
- true
-
diff --git a/spring-boot-scheduler/src/main/java/com/neo/SchedulerApplication.java b/spring-boot-scheduler/src/main/java/com/neo/SchedulerApplication.java
new file mode 100644
index 000000000..1fd012d24
--- /dev/null
+++ b/spring-boot-scheduler/src/main/java/com/neo/SchedulerApplication.java
@@ -0,0 +1,14 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableScheduling
+public class SchedulerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SchedulerApplication.class, args);
+ }
+}
diff --git a/spring-boot-scheduler/src/test/java/com/neo/SchedulerApplicationTests.java b/spring-boot-scheduler/src/test/java/com/neo/SchedulerApplicationTests.java
new file mode 100644
index 000000000..9a627ba57
--- /dev/null
+++ b/spring-boot-scheduler/src/test/java/com/neo/SchedulerApplicationTests.java
@@ -0,0 +1,17 @@
+package com.neo;
+
+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 SchedulerApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/pom.xml b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/pom.xml
new file mode 100644
index 000000000..6677f5207
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/pom.xml
@@ -0,0 +1,76 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-thymeleaf-layout
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-thymeleaf-layout
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ nz.net.ultraq.thymeleaf
+ thymeleaf-layout-dialect
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/TLayoutApplication.java b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/TLayoutApplication.java
new file mode 100644
index 000000000..0e4e29af2
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/TLayoutApplication.java
@@ -0,0 +1,13 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class TLayoutApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TLayoutApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/web/IndexController.java b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/web/IndexController.java
new file mode 100644
index 000000000..3b2554172
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/java/com/neo/web/IndexController.java
@@ -0,0 +1,31 @@
+package com.neo.web;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class IndexController {
+
+ @RequestMapping("/index")
+ public String index() {
+ return "index";
+ }
+
+ @RequestMapping("/fragment")
+ public String fragment() {
+ return "fragment";
+ }
+
+ @RequestMapping("/layout")
+ public String layout() {
+ return "layout";
+ }
+
+ @RequestMapping("/home")
+ public String home() {
+ return "home";
+ }
+
+
+}
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/application.properties b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/application.properties
new file mode 100644
index 000000000..975a5172a
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+com.neo.title=\u7EAF\u6D01\u7684\u5FAE\u7B11
+com.neo.description=\u5206\u4EAB\u751F\u6D3B\u548C\u6280\u672F
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/base.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/base.html
new file mode 100644
index 000000000..6a491191e
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/base.html
@@ -0,0 +1,15 @@
+
+
+
+ comm title
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/fragment.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/fragment.html
new file mode 100644
index 000000000..bb65abe2e
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/fragment.html
@@ -0,0 +1,11 @@
+
+
+
+ Fragment - Page
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/home.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/home.html
new file mode 100644
index 000000000..bd0de8076
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/home.html
@@ -0,0 +1,11 @@
+
+
+
+ Home
+
+
+
+
个性化的内容
+
+
+
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/index.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/index.html
new file mode 100644
index 000000000..40d36573a
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Index
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout.html
new file mode 100644
index 000000000..4bc09f3c9
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Layout
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/copyright.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/copyright.html
new file mode 100644
index 000000000..223de9f3e
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/copyright.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Title
+
+
+
+ © 2018
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/footer.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/footer.html
new file mode 100644
index 000000000..48a9c7def
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/footer.html
@@ -0,0 +1,12 @@
+
+
+
+
+ footer
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/header.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/header.html
new file mode 100644
index 000000000..adc6b8c67
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/header.html
@@ -0,0 +1,12 @@
+
+
+
+
+ header
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/left.html b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/left.html
new file mode 100644
index 000000000..04d887574
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/main/resources/templates/layout/left.html
@@ -0,0 +1,12 @@
+
+
+
+
+ left
+
+
+
+ 我是 左侧
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/test/java/com/neo/TLayoutApplicationTests.java b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/test/java/com/neo/TLayoutApplicationTests.java
new file mode 100644
index 000000000..3e1b0ab0c
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf-layout/src/test/java/com/neo/TLayoutApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 TLayoutApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/pom.xml b/spring-boot-thymeleaf/spring-boot-thymeleaf/pom.xml
new file mode 100644
index 000000000..03aea7c39
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-thymeleaf
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-thymeleaf
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java
new file mode 100644
index 000000000..e194e8686
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/ThymeleafApplication.java
@@ -0,0 +1,13 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ThymeleafApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ThymeleafApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/model/User.java b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..55fabd5eb
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/model/User.java
@@ -0,0 +1,44 @@
+package com.neo.model;
+
+
+
+public class User {
+ private String name;
+ private int age;
+ private String pass;
+
+ public User(String name, int age, String pass) {
+ this.name = name;
+ this.age = age;
+ this.pass = pass;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getPass() {
+ return pass;
+ }
+
+ public void setPass(String pass) {
+ this.pass = pass;
+ }
+
+ @Override
+ public String toString() {
+ return ("name=" + this.name + ",age=" + this.age + ",pass=" + this.pass);
+ }
+}
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/ExampleController.java b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/ExampleController.java
new file mode 100644
index 000000000..112760366
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/ExampleController.java
@@ -0,0 +1,66 @@
+package com.neo.web;
+
+import com.neo.model.User;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Controller
+public class ExampleController {
+
+ @RequestMapping("/string")
+ public String string(ModelMap map) {
+ map.addAttribute("userName", "ityouknow");
+ return "string";
+ }
+
+ @RequestMapping("/if")
+ public String ifunless(ModelMap map) {
+ map.addAttribute("flag", "yes");
+ return "if";
+ }
+
+ @RequestMapping("/list")
+ public String list(ModelMap map) {
+ map.addAttribute("users", getUserList());
+ return "list";
+ }
+
+ @RequestMapping("/url")
+ public String url(ModelMap map) {
+ map.addAttribute("type", "link");
+ map.addAttribute("pageId", "springcloud/2017/09/11/");
+ map.addAttribute("img", "http://www.ityouknow.com/assets/images/neo.jpg");
+ return "url";
+ }
+
+ @RequestMapping("/eq")
+ public String eq(ModelMap map) {
+ map.addAttribute("name", "neo");
+ map.addAttribute("age", 30);
+ map.addAttribute("flag", "yes");
+ return "eq";
+ }
+
+ @RequestMapping("/switch")
+ public String switchcase(ModelMap map) {
+ map.addAttribute("sex", "woman");
+ return "switch";
+ }
+
+ private List getUserList(){
+ List list=new ArrayList();
+ User user1=new User("大牛",12,"123456");
+ User user2=new User("小牛",6,"123563");
+ User user3=new User("纯洁的微笑",66,"666666");
+ list.add(user1);
+ list.add(user2);
+ list.add(user3);
+ return list;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/HelloController.java b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..2eac4e8a9
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,16 @@
+package com.neo.web;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class HelloController {
+
+ @RequestMapping("/")
+ public String index(ModelMap map) {
+ map.addAttribute("message", "http://www.ityouknow.com");
+ return "hello";
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/application.properties b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/application.properties
new file mode 100644
index 000000000..4b9333aa3
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.thymeleaf.cache=false
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/eq.html b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/eq.html
new file mode 100644
index 000000000..70e65a9fa
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/eq.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Example gt eq
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/hello.html b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/hello.html
new file mode 100644
index 000000000..28c51163e
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/hello.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Hello
+
+
+Hello World
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/if.html b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/if.html
new file mode 100644
index 000000000..9127c233c
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/if.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Example If/Unless
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/list.html b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/list.html
new file mode 100644
index 000000000..017c65e96
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/list.html
@@ -0,0 +1,20 @@
+
+
+
+
+ Example If/Unless
+
+
+
+
for 循环
+
+
+ | neo |
+ 6 |
+ 213 |
+ index |
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/string.html b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/string.html
new file mode 100644
index 000000000..7a2e3f66d
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/string.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Example String
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/switch.html b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/switch.html
new file mode 100644
index 000000000..aef5a3031
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/switch.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Example switch
+
+
+
+
+
她是一个姑娘...
+
这是一个爷们!
+
+
未知性别的一个家伙。
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/url.html b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/url.html
new file mode 100644
index 000000000..ded52686f
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/main/resources/templates/url.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Example If/Unless
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-thymeleaf/spring-boot-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
new file mode 100644
index 000000000..3ccf7f4b9
--- /dev/null
+++ b/spring-boot-thymeleaf/spring-boot-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 ThymeleafApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-boot-web-thymeleaf/pom.xml b/spring-boot-web-thymeleaf/pom.xml
index 29d75f28c..503ce5495 100644
--- a/spring-boot-web-thymeleaf/pom.xml
+++ b/spring-boot-web-thymeleaf/pom.xml
@@ -6,12 +6,18 @@
Spring Boot Web thymeleaf Sample
Spring Boot Web thymeleaf Sample
-
+
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.RELEASE
+ 3.0.0
+
+
+ UTF-8
+ 17
+
+
@@ -22,11 +28,24 @@
org.springframework.boot
spring-boot-starter-thymeleaf
-
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
org.springframework.boot
spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
diff --git a/spring-boot-web-thymeleaf/src/main/java/com/neo/controller/MessageController.java b/spring-boot-web-thymeleaf/src/main/java/com/neo/controller/MessageController.java
index 0f5b33d0b..e9d09b4a4 100644
--- a/spring-boot-web-thymeleaf/src/main/java/com/neo/controller/MessageController.java
+++ b/spring-boot-web-thymeleaf/src/main/java/com/neo/controller/MessageController.java
@@ -1,7 +1,7 @@
package com.neo.controller;
-import javax.validation.Valid;
+import jakarta.validation.Valid;
import com.neo.model.Message;
import com.neo.repository.MessageRepository;
diff --git a/spring-boot-web-thymeleaf/src/main/java/com/neo/model/Message.java b/spring-boot-web-thymeleaf/src/main/java/com/neo/model/Message.java
index d4f09e648..c3a36113b 100644
--- a/spring-boot-web-thymeleaf/src/main/java/com/neo/model/Message.java
+++ b/spring-boot-web-thymeleaf/src/main/java/com/neo/model/Message.java
@@ -1,9 +1,8 @@
package com.neo.model;
-import java.util.Calendar;
-
-import javax.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.Calendar;
public class Message {
diff --git a/spring-boot-web-thymeleaf/src/main/resources/templates/messages/form.html b/spring-boot-web-thymeleaf/src/main/resources/templates/messages/form.html
index 1d564bfba..80f8adea0 100644
--- a/spring-boot-web-thymeleaf/src/main/resources/templates/messages/form.html
+++ b/spring-boot-web-thymeleaf/src/main/resources/templates/messages/form.html
@@ -1,11 +1,11 @@
-
+
Messages : Create
-
+
diff --git a/spring-boot-web-thymeleaf/src/main/resources/templates/messages/list.html b/spring-boot-web-thymeleaf/src/main/resources/templates/messages/list.html
index 88f00a8fd..a1aef8ad0 100644
--- a/spring-boot-web-thymeleaf/src/main/resources/templates/messages/list.html
+++ b/spring-boot-web-thymeleaf/src/main/resources/templates/messages/list.html
@@ -1,11 +1,11 @@
-
+
Messages : View all
-
+
diff --git a/spring-boot-web-thymeleaf/src/main/resources/templates/messages/view.html b/spring-boot-web-thymeleaf/src/main/resources/templates/messages/view.html
index e32cb74e0..0181b9afb 100644
--- a/spring-boot-web-thymeleaf/src/main/resources/templates/messages/view.html
+++ b/spring-boot-web-thymeleaf/src/main/resources/templates/messages/view.html
@@ -1,11 +1,11 @@
-
+
Messages : View
-
+
diff --git a/spring-boot-web-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java b/spring-boot-web-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
index e97547773..5bb188086 100644
--- a/spring-boot-web-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
+++ b/spring-boot-web-thymeleaf/src/test/java/com/neo/ThymeleafApplicationTests.java
@@ -10,7 +10,7 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
@@ -26,8 +26,7 @@ public class ThymeleafApplicationTests {
@Autowired
private TestRestTemplate restTemplate;
- @LocalServerPort
- private int port;
+ private int port=8080;
@Test
public void testHome() {
@@ -50,8 +49,16 @@ public void testCreate() {
public void testCss() {
ResponseEntity
entity = this.restTemplate.getForEntity(
"http://localhost:" + this.port + "/css/bootstrap.min.css", String.class);
+
+ ResponseEntity response = restTemplate.exchange(
+ createURLWithPort("/students/Student1/courses"),
+ HttpMethod.POST, entity, String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("body");
}
+ private String createURLWithPort(String uri) {
+ return "http://localhost:" + port + uri;
+ }
+
}
diff --git a/spring-boot-web/pom.xml b/spring-boot-web/pom.xml
index ebeec70a0..d09cd4a99 100644
--- a/spring-boot-web/pom.xml
+++ b/spring-boot-web/pom.xml
@@ -5,8 +5,8 @@
com.neo
spring-boot-web
- 0.0.1-SNAPSHOT
- jar
+ 3.0.0-SNAPSHOT
+ war
spring-boot-web
Demo project for Spring Boot
@@ -14,63 +14,57 @@
org.springframework.boot
spring-boot-starter-parent
- 1.5.6.RELEASE
+ 3.0.0
UTF-8
- 1.8
+ 17
org.springframework.boot
- spring-boot-starter
+ spring-boot-starter-web
org.springframework.boot
- spring-boot-starter-test
- test
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ mysql
+ mysql-connector-java
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- mysql
- mysql-connector-java
-
-
- org.springframework.boot
- spring-boot-devtools
- true
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
-
- org.springframework.boot
- spring-boot-starter-thymeleaf
-
- org.webjars.bower
- jquery
- 2.0.3
-
+ org.webjars.bower
+ jquery
+ 3.6.2
+
- org.webjars.bower
- bootstrap
- 3.0.3
+ org.webjars.bowergithub.twbs
+ bootstrap
+ 5.2.3
-
- org.springframework.boot
- spring-boot-starter-redis
-
- org.springframework.session
- spring-session-data-redis
+ org.springframework.boot
+ spring-boot-starter-test
+ test
@@ -79,9 +73,6 @@
org.springframework.boot
spring-boot-maven-plugin
-
- true
-
diff --git a/spring-boot-web/src/main/java/com/neo/WebApplication.java b/spring-boot-web/src/main/java/com/neo/WebApplication.java
new file mode 100644
index 000000000..ede8e479f
--- /dev/null
+++ b/spring-boot-web/src/main/java/com/neo/WebApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class WebApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(WebApplication.class, args);
+ }
+}
diff --git a/spring-boot-web/src/main/java/com/neo/WebConfiguration.java b/spring-boot-web/src/main/java/com/neo/WebConfiguration.java
index cbf7177fd..604679b1c 100644
--- a/spring-boot-web/src/main/java/com/neo/WebConfiguration.java
+++ b/spring-boot-web/src/main/java/com/neo/WebConfiguration.java
@@ -2,13 +2,13 @@
import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.FilterConfig;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
diff --git a/spring-boot-web/src/main/java/com/neo/model/User.java b/spring-boot-web/src/main/java/com/neo/model/User.java
new file mode 100644
index 000000000..9914cd6e1
--- /dev/null
+++ b/spring-boot-web/src/main/java/com/neo/model/User.java
@@ -0,0 +1,72 @@
+package com.neo.model;
+
+import java.io.Serializable;
+import jakarta.persistence.*;
+
+@Entity
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ @Id
+ @GeneratedValue
+ private Long id;
+ @Column(nullable = false, unique = true, length = 20)
+ private String userName;
+ @Column(nullable = false)
+ private String passWord;
+ @Column(nullable = false, unique = true, length = 30)
+ private String email;
+ @Column(nullable = true, unique = true, length = 30)
+ private String nickName;
+ @Column(nullable = false)
+ private String regTime;
+
+ public User() {
+ super();
+ }
+ public User(String nickName,String email,String userName, String passWord, String regTime) {
+ super();
+ this.email = email;
+ this.nickName = nickName;
+ this.passWord = passWord;
+ this.userName = userName;
+ this.regTime = regTime;
+ }
+ public Long getId() {
+ return id;
+ }
+ public void setId(Long id) {
+ this.id = id;
+ }
+ public String getUserName() {
+ return userName;
+ }
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+ public String getPassWord() {
+ return passWord;
+ }
+ public void setPassWord(String passWord) {
+ this.passWord = passWord;
+ }
+ public String getEmail() {
+ return email;
+ }
+ public void setEmail(String email) {
+ this.email = email;
+ }
+ public String getNickName() {
+ return nickName;
+ }
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+ public String getRegTime() {
+ return regTime;
+ }
+ public void setRegTime(String regTime) {
+ this.regTime = regTime;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-web/src/main/java/com/neo/repository/UserRepository.java b/spring-boot-web/src/main/java/com/neo/repository/UserRepository.java
new file mode 100644
index 000000000..b5c0c63ec
--- /dev/null
+++ b/spring-boot-web/src/main/java/com/neo/repository/UserRepository.java
@@ -0,0 +1,12 @@
+package com.neo.repository;
+
+import com.neo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserRepository extends JpaRepository {
+
+ User findByUserName(String userName);
+
+ User findByUserNameOrEmail(String username, String email);
+
+}
\ No newline at end of file
diff --git a/spring-boot-web/src/main/java/com/neo/web/HelloController.java b/spring-boot-web/src/main/java/com/neo/web/HelloController.java
index 5fd95a062..a24d50706 100644
--- a/spring-boot-web/src/main/java/com/neo/web/HelloController.java
+++ b/spring-boot-web/src/main/java/com/neo/web/HelloController.java
@@ -3,8 +3,9 @@
import java.util.Locale;
import java.util.UUID;
-import javax.servlet.http.HttpSession;
+import jakarta.servlet.http.HttpSession;
+import com.neo.model.User;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -14,17 +15,15 @@ public class HelloController {
@RequestMapping("/hello")
public String hello(Locale locale, Model model) {
- return "hello world";
+ return "Hello World";
+ }
+
+ @RequestMapping("/getUser")
+ public User getUser() {
+ User user=new User();
+ user.setUserName("小明");
+ user.setPassWord("xxxx");
+ return user;
}
-
- @RequestMapping("/uid")
- String uid(HttpSession session) {
- UUID uid = (UUID) session.getAttribute("uid");
- if (uid == null) {
- uid = UUID.randomUUID();
- }
- session.setAttribute("uid", uid);
- return session.getId();
- }
}
\ No newline at end of file
diff --git a/spring-boot-web/src/main/java/com/neo/web/UserController.java b/spring-boot-web/src/main/java/com/neo/web/UserController.java
index 983617cce..92ff3323b 100644
--- a/spring-boot-web/src/main/java/com/neo/web/UserController.java
+++ b/spring-boot-web/src/main/java/com/neo/web/UserController.java
@@ -3,29 +3,38 @@
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import com.neo.domain.User;
-import com.neo.domain.UserRepository;
+import com.neo.model.User;
+import com.neo.repository.UserRepository;
@RestController
public class UserController {
@Autowired
private UserRepository userRepository;
+
+ @RequestMapping("/add")
+ public User saveUser(String key) {
+ User user=new User();
+ user.setUserName("aa"+key);
+ user.setEmail("ityouknow@126.com"+key);
+ user.setNickName("微笑"+key);
+ user.setPassWord("123456"+key);
+ user.setRegTime("2022-12-20"+key);
+ userRepository.save(user);
+ return user;
+ }
- @RequestMapping("/getUser")
- @Cacheable(value="user-key")
- public User getUser() {
+ @RequestMapping("/getUserByName")
+ public User getUserByName() {
User user=userRepository.findByUserName("aa");
System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
return user;
}
@RequestMapping("/getUsers")
- @Cacheable(value="key-Users")
public List getUsers() {
List users=userRepository.findAll();
System.out.println("若下面没出现“无缓存的时候调用”字样且能打印出数据表示测试成功");
diff --git a/spring-boot-web/src/main/resources/application.properties b/spring-boot-web/src/main/resources/application.properties
index 16fed3698..d9a963273 100644
--- a/spring-boot-web/src/main/resources/application.properties
+++ b/spring-boot-web/src/main/resources/application.properties
@@ -1,32 +1,16 @@
-spring.datasource.url=jdbc:mysql://localhost:3306/test
-spring.datasource.username=root
-spring.datasource.password=root
-spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url=jdbc:mysql://1.1.4.3:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
+spring.datasource.username=xx
+spring.datasource.password=exxx
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.hikari.maxLifeTime=600000
spring.jpa.properties.hibernate.hbm2ddl.auto=update
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
-spring.jpa.show-sql= true
-
-com.neo.title=\u7eaf\u6d01\u7684\u5fae\u7b11
-com.neo.description=\u5206\u4eab\u751f\u6d3b\u548c\u6280\u672f
-
-# REDIS (RedisProperties)
-# Redis\u6570\u636e\u5e93\u7d22\u5f15\uff08\u9ed8\u8ba4\u4e3a0\uff09
-spring.redis.database=0
-# Redis\u670d\u52a1\u5668\u5730\u5740
-spring.redis.host=192.168.0.71
-# Redis\u670d\u52a1\u5668\u8fde\u63a5\u7aef\u53e3
-spring.redis.port=6379
-# Redis\u670d\u52a1\u5668\u8fde\u63a5\u5bc6\u7801\uff08\u9ed8\u8ba4\u4e3a\u7a7a\uff09
-spring.redis.password=
-# \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=8
-# \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\u5927\u7a7a\u95f2\u8fde\u63a5
-spring.redis.pool.max-idle=8
-# \u8fde\u63a5\u6c60\u4e2d\u7684\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5
-spring.redis.pool.min-idle=0
-# \u8fde\u63a5\u8d85\u65f6\u65f6\u95f4\uff08\u6beb\u79d2\uff09
-spring.redis.timeout=0
+#sql\u8F93\u51FA
+spring.jpa.show-sql=true
+#format\u4E00\u4E0Bsql\u8FDB\u884C\u8F93\u51FA
+spring.jpa.properties.hibernate.format_sql=true
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
+spring.jpa.open-in-view=true
+com.neo.title=\u7EAF\u6D01\u7684\u5FAE\u7B11
+com.neo.description=\u5206\u4EAB\u751F\u6D3B\u548C\u6280\u672F
\ No newline at end of file
diff --git a/spring-boot-web/src/test/java/com/neo/WebApplicationTests.java b/spring-boot-web/src/test/java/com/neo/WebApplicationTests.java
new file mode 100644
index 000000000..cd4cb770c
--- /dev/null
+++ b/spring-boot-web/src/test/java/com/neo/WebApplicationTests.java
@@ -0,0 +1,18 @@
+package com.neo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class WebApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ System.out.println("hello web");
+ }
+
+}
diff --git a/spring-boot-web/src/test/java/com/neo/model/UserRepositoryTests.java b/spring-boot-web/src/test/java/com/neo/model/UserRepositoryTests.java
new file mode 100644
index 000000000..3b7d8ea33
--- /dev/null
+++ b/spring-boot-web/src/test/java/com/neo/model/UserRepositoryTests.java
@@ -0,0 +1,38 @@
+package com.neo.model;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+import com.neo.repository.UserRepository;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import org.springframework.test.context.junit4.SpringRunner;
+
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserRepositoryTests {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Test
+ public void test() throws Exception {
+ Date date = new Date();
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+ String formattedDate = dateFormat.format(date);
+
+ userRepository.save(new User("aa1", "aa@126.com", "aa", "aa123456",formattedDate));
+ userRepository.save(new User("bb2", "bb@126.com", "bb", "bb123456",formattedDate));
+ userRepository.save(new User("cc3", "cc@126.com", "cc", "cc123456",formattedDate));
+
+// Assert.assertEquals(9, userRepository.findAll().size());
+ Assert.assertEquals("bb2", userRepository.findByUserNameOrEmail("bb", "xxx126.com").getNickName());
+ userRepository.delete(userRepository.findByUserName("aa"));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java b/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java
index ae0b39960..2d76b350a 100644
--- a/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java
+++ b/spring-boot-web/src/test/java/com/neo/web/ProPertiesTest.java
@@ -8,9 +8,7 @@
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import com.neo.Application;
import com.neo.util.NeoProperties;
import org.springframework.test.context.junit4.SpringRunner;
@@ -18,11 +16,9 @@
@SpringBootTest
public class ProPertiesTest {
-
@Autowired
private NeoProperties neoProperties;
-
@Test
public void getHello() throws Exception {
System.out.println(neoProperties.getTitle());
@@ -30,11 +26,10 @@ public void getHello() throws Exception {
Assert.assertEquals(neoProperties.getDescription(), "分享生活和技术");
}
-
@Test
public void testMap() throws Exception {
Map orderMinTime=new HashMap();
- long xx=orderMinTime.get("123");
+ orderMinTime.get("123");
}
}
\ No newline at end of file
diff --git a/spring-boot-webflux/pom.xml b/spring-boot-webflux/pom.xml
new file mode 100644
index 000000000..16b66ab36
--- /dev/null
+++ b/spring-boot-webflux/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ com.neo
+ spring-boot-webflux
+ 1.0.0-SNAPSHOT
+ jar
+
+ spring-boot-webflux
+ Demo project for Spring Boot
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.0
+
+
+
+
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/spring-boot-webflux/src/main/java/com/neo/WebFluxApplication.java b/spring-boot-webflux/src/main/java/com/neo/WebFluxApplication.java
new file mode 100644
index 000000000..b89527d35
--- /dev/null
+++ b/spring-boot-webflux/src/main/java/com/neo/WebFluxApplication.java
@@ -0,0 +1,12 @@
+package com.neo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class WebFluxApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(WebFluxApplication.class, args);
+ }
+}
diff --git a/spring-boot-webflux/src/main/java/com/neo/web/HelloController.java b/spring-boot-webflux/src/main/java/com/neo/web/HelloController.java
new file mode 100644
index 000000000..681a1542f
--- /dev/null
+++ b/spring-boot-webflux/src/main/java/com/neo/web/HelloController.java
@@ -0,0 +1,14 @@
+package com.neo.web;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+@RestController
+public class HelloController {
+
+ @GetMapping("/hello")
+ public Mono hello() {
+ return Mono.just("Welcome to reactive world ~");
+ }
+}
diff --git a/spring-boot-webflux/src/main/resources/application.properties b/spring-boot-webflux/src/main/resources/application.properties
new file mode 100644
index 000000000..e69de29bb
diff --git a/spring-boot-webflux/src/test/java/com/neo/HelloTests.java b/spring-boot-webflux/src/test/java/com/neo/HelloTests.java
new file mode 100644
index 000000000..aa9389c5f
--- /dev/null
+++ b/spring-boot-webflux/src/test/java/com/neo/HelloTests.java
@@ -0,0 +1,21 @@
+package com.neo;
+
+import com.neo.web.HelloController;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+@RunWith(SpringRunner.class)
+@WebFluxTest(controllers = HelloController.class)
+public class HelloTests {
+ @Autowired
+ WebTestClient client;
+
+ @Test
+ public void getHello() {
+ client.get().uri("/hello").exchange().expectStatus().isOk();
+ }
+}
diff --git a/spring-boot-webflux/src/test/java/com/neo/WebFluxApplicationTests.java b/spring-boot-webflux/src/test/java/com/neo/WebFluxApplicationTests.java
new file mode 100644
index 000000000..b7b4ed765
--- /dev/null
+++ b/spring-boot-webflux/src/test/java/com/neo/WebFluxApplicationTests.java
@@ -0,0 +1,16 @@
+package com.neo;
+
+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 WebFluxApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}