diff --git a/README.md b/README.md
index 21a0576..7371704 100644
--- a/README.md
+++ b/README.md
@@ -45,9 +45,9 @@ spring-cloud:Finchley.SR2
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| [spring-boot-base](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-base) | spring-boot 基础 | [spring boot 官方文档](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/)
[spring boot 中文官方文档](https://www.breakyizhan.com/springboot/3028.html) |
| [spring-boot-yml-profile](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-yml-profile) | yml 语法和多配置切换 | [Using YAML Instead of Properties](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-external-config-yaml) |
-| [spring-boot-servlet](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-servlet) | 整合servlet 3.0 | [Embedded Servlet Container Support](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-embedded-container) |
| [spring-boot-tomcat](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-tomcat) | spring-boot 整合外部容器(tomcat) | [Use Another Web Server](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#howto-use-another-web-server) |
-| [spring-boot-jsp](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-jsp) | spring-boot 整合 jsp | [JSP Limitations](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-jsp-limitations) |
+| [spring-boot-servlet](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-servlet) | 整合servlet 3.0 | [Embedded Servlet Container Support](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-embedded-container) |
+| [spring-boot-jsp](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-jsp) | spring-boot 内置容器整合 jsp | [JSP Limitations](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-jsp-limitations) |
| [spring-boot-data-jpa](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-jsp) | spring-boot data jpa 的使用 | [Spring Data JPA](https://docs.spring.io/spring-data/jpa/docs/2.1.3.RELEASE/reference/html/) |
| [spring-boot-mybatis](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-mybatis) | spring-boot 整合 mybatis
boot 2.x 内置HikariDataSources数据源的配置 | [Mybatis-Spring](http://www.mybatis.org/spring/zh/index.html)
[Mybatis-Spring-Boot-Autoconfigure](http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/) |
| [spring-boot-druid-mybtais](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-druid-mybatis) | spring-boot 整合druid、mybatis | [Alibaba druid](https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
[druid-spring-boot-starter](https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter) |
diff --git a/pictures/boot-dubbo-common.png b/pictures/boot-dubbo-common.png
new file mode 100644
index 0000000..6907238
Binary files /dev/null and b/pictures/boot-dubbo-common.png differ
diff --git a/pictures/boot-dubbo-consumer1.png b/pictures/boot-dubbo-consumer1.png
new file mode 100644
index 0000000..79513a9
Binary files /dev/null and b/pictures/boot-dubbo-consumer1.png differ
diff --git a/pictures/boot-dubbo-provider.png b/pictures/boot-dubbo-provider.png
new file mode 100644
index 0000000..30d5963
Binary files /dev/null and b/pictures/boot-dubbo-provider.png differ
diff --git a/pictures/druid-status.png b/pictures/druid-status.png
new file mode 100644
index 0000000..44bd7f9
Binary files /dev/null and b/pictures/druid-status.png differ
diff --git a/pictures/rabbitmq-common.png b/pictures/rabbitmq-common.png
new file mode 100644
index 0000000..7535c19
Binary files /dev/null and b/pictures/rabbitmq-common.png differ
diff --git a/pictures/rabbitmq-consumer.png b/pictures/rabbitmq-consumer.png
new file mode 100644
index 0000000..c7e2738
Binary files /dev/null and b/pictures/rabbitmq-consumer.png differ
diff --git a/pictures/rabbitmq-producer.png b/pictures/rabbitmq-producer.png
new file mode 100644
index 0000000..9d72d2a
Binary files /dev/null and b/pictures/rabbitmq-producer.png differ
diff --git a/pictures/spring-boot-base.png b/pictures/spring-boot-base.png
new file mode 100644
index 0000000..a09ae93
Binary files /dev/null and b/pictures/spring-boot-base.png differ
diff --git a/pictures/spring-boot-data-jpa.png b/pictures/spring-boot-data-jpa.png
new file mode 100644
index 0000000..8d41d0a
Binary files /dev/null and b/pictures/spring-boot-data-jpa.png differ
diff --git a/pictures/spring-boot-dependencies.png b/pictures/spring-boot-dependencies.png
new file mode 100644
index 0000000..b764548
Binary files /dev/null and b/pictures/spring-boot-dependencies.png differ
diff --git a/pictures/spring-boot-druid 控制台.png b/pictures/spring-boot-druid 控制台.png
new file mode 100644
index 0000000..ef5d83c
Binary files /dev/null and b/pictures/spring-boot-druid 控制台.png differ
diff --git a/pictures/spring-boot-druid-mybatis.png b/pictures/spring-boot-druid-mybatis.png
new file mode 100644
index 0000000..5846607
Binary files /dev/null and b/pictures/spring-boot-druid-mybatis.png differ
diff --git a/pictures/spring-boot-dubbo.png b/pictures/spring-boot-dubbo.png
new file mode 100644
index 0000000..9992f1c
Binary files /dev/null and b/pictures/spring-boot-dubbo.png differ
diff --git a/pictures/spring-boot-jsp.png b/pictures/spring-boot-jsp.png
new file mode 100644
index 0000000..93f6a67
Binary files /dev/null and b/pictures/spring-boot-jsp.png differ
diff --git a/pictures/spring-boot-memcached.png b/pictures/spring-boot-memcached.png
new file mode 100644
index 0000000..9838e54
Binary files /dev/null and b/pictures/spring-boot-memcached.png differ
diff --git a/pictures/spring-boot-mongodb.png b/pictures/spring-boot-mongodb.png
new file mode 100644
index 0000000..dcb91b5
Binary files /dev/null and b/pictures/spring-boot-mongodb.png differ
diff --git a/pictures/spring-boot-mybatis.png b/pictures/spring-boot-mybatis.png
new file mode 100644
index 0000000..2c20680
Binary files /dev/null and b/pictures/spring-boot-mybatis.png differ
diff --git a/pictures/spring-boot-rabbitmq.png b/pictures/spring-boot-rabbitmq.png
new file mode 100644
index 0000000..c5751a0
Binary files /dev/null and b/pictures/spring-boot-rabbitmq.png differ
diff --git a/pictures/spring-boot-redis.png b/pictures/spring-boot-redis.png
new file mode 100644
index 0000000..89621cb
Binary files /dev/null and b/pictures/spring-boot-redis.png differ
diff --git a/pictures/spring-boot-servlet.png b/pictures/spring-boot-servlet.png
new file mode 100644
index 0000000..81f9c31
Binary files /dev/null and b/pictures/spring-boot-servlet.png differ
diff --git a/pictures/spring-boot-tomcat.png b/pictures/spring-boot-tomcat.png
new file mode 100644
index 0000000..0b867ed
Binary files /dev/null and b/pictures/spring-boot-tomcat.png differ
diff --git a/pictures/spring-boot-websocket.png b/pictures/spring-boot-websocket.png
new file mode 100644
index 0000000..bea2c9d
Binary files /dev/null and b/pictures/spring-boot-websocket.png differ
diff --git a/spring-boot/spring-boot-base/README.md b/spring-boot/spring-boot-base/README.md
new file mode 100644
index 0000000..840cd42
--- /dev/null
+++ b/spring-boot/spring-boot-base/README.md
@@ -0,0 +1,247 @@
+# spring-boot 基础
+
+## 一、说明
+
+#### 1.1 项目结构说明
+
+1. 本项目搭建一个简单的hello spring 的 web工程,简单说明spring-boot 的开箱即用的特性;
+2. 模板引擎采用freemaker 和 thymeleaf 作为示例,分别对应模板文件makershow.ftl 和 leafShow.html;
+3. spring boot 2.x 默认是不支持jsp的,需要额外的配置,关于使用jsp的整合可以参考[spring-boot-jsp](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-jsp)项目。
+
+
+
+#### 1.2 项目依赖
+
+导入相关的starter(启动器)
+
+```xml
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.1.RELEASE
+
+
+ com.heibaiying
+ spring-boot-base
+ 0.0.1-SNAPSHOT
+ spring-boot-base
+ Demo project for Spring Boot
+
+
+ 1.8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-freemarker
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+```
+
+1. spring boot 项目默认继承自spring-boot-starter-parent,而spring-boot-starter-parent继承自spring-boot-dependencies, spring-boot-dependencies中定义了关于spring boot 依赖的各种jar包的版本,是spring boot 的版本管理中心。
+
+
+
+2. 关于spring boot 2.x官方支持的所有starter 可以参见官方文档 [Table 13.1. Spring Boot application starters](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#using-boot-starter)
+
+
+
+## 二、spring boot 主启动类
+
+ 如果采用IDEA 或者 Spring Tool Suite (STS) 等开发工具创建的spring boot 工程,会默认创建启动类,如果没有创建,需要手动创建启动类
+
+```java
+package com.heibaiying.springbootbase;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootBaseApplication {
+
+ // 启动类默认开启包扫描,扫描与主程序所在包及其子包,对于本工程而言 默认扫描 com.heibaiying.springbootbase
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootBaseApplication.class, args);
+ }
+
+}
+```
+
+@SpringBootApplication 注解是一个复合注解,里面包含了@ComponentScan注解,默认开启包扫描,扫描与主程序所在包及其子包,对于本工程而言 默认扫描 com.heibaiying.springbootbase
+
+```java
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@SpringBootConfiguration
+@EnableAutoConfiguration
+@ComponentScan(excludeFilters = {
+ @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
+ @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
+public @interface SpringBootApplication {
+ ...
+}
+```
+
+
+
+## 三、开箱即用的web工程
+
+在springbootBaseApplication.java 的同级目录创建controller文件夹,并在其中创建RestfulController.java,启动项目访问localhost:8080/restful/programmers 即可看到项目搭建成功。
+
+```java
+/**
+ * @author : heibaiying
+ * @description : restful 控制器
+ */
+@RestController
+@RequestMapping("restful")
+public class RestfulController {
+
+ @GetMapping("programmers")
+ private List getProgrammers() {
+ List programmers = new ArrayList<>();
+ programmers.add(new Programmer("xiaoming", 12, 100000.00f, LocalDate.of(2019, Month.AUGUST, 2)));
+ programmers.add(new Programmer("xiaohong", 23, 900000.00f, LocalDate.of(2013, Month.FEBRUARY, 2)));
+ return programmers;
+ }
+}
+```
+
+这里之所以能够开箱即用,是因为我们在项目中导入spring-boot-starter-web启动器,而@SpringBootApplication 复合注解中默认开启了@EnableAutoConfiguration注解允许开启自动化配置,spring在检查导入starter-web的依赖后就会开启web的自动化配置。
+
+
+
+## 四、模板引擎
+
+这里我们在一个项目中同时导入了freemaker 和 thymeleaf的starter(虽然并不推荐,但是在同一个项目中是可以混用这两种模板引擎的)。
+
+#### 4.1 freemarker
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 跳转渲染模板引擎 默认模板的存放位置为classpath:templates
+ */
+@Controller
+@RequestMapping("freemarker")
+public class FreeMarkerController {
+
+ @RequestMapping("show")
+ private String programmerShow(ModelMap modelMap){
+ List programmerList=new ArrayList<>();
+ programmerList.add(new Programmer("xiaoming",12,100000.00f,LocalDate.of(2019,Month.AUGUST,2)));
+ programmerList.add(new Programmer("xiaohong",23,900000.00f,LocalDate.of(2013,Month.FEBRUARY,2)));
+ modelMap.addAttribute("programmers",programmerList);
+ return "markerShow";
+ }
+}
+
+```
+
+```html
+
+
+
+
+ freemarker模板引擎
+
+
+
+ <#list programmers as programmer>
+ - 姓名: ${programmer.name} 年龄: ${programmer.age}
+ #list>
+
+
+
+```
+
+#### 4.2 thymeleaf
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 跳转渲染模板引擎 默认模板的存放位置为classpath:templates
+ */
+@Controller
+@RequestMapping("thymeleaf")
+public class ThymeleafController {
+
+ @RequestMapping("show")
+ private String programmerShow(ModelMap modelMap) {
+ List programmerList = new ArrayList<>();
+ programmerList.add(new Programmer("xiaoming", 12, 100000.00f, LocalDate.of(2019, Month.AUGUST, 2)));
+ programmerList.add(new Programmer("xiaohong", 23, 900000.00f, LocalDate.of(2013, Month.FEBRUARY, 2)));
+ modelMap.addAttribute("programmers", programmerList);
+ return "leafShow";
+ }
+}
+
+```
+
+```html
+
+
+
+
+ thymeleaf模板引擎
+
+
+
+
+
+```
+
+#### 4.3 文档说明
+
+freemarker:提供了完善的中文文档,地址 http://freemarker.foofun.cn/
+
+thymeleaf:官方英文文档地址:[thymeleaf 3.0.11RELEASE](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.pdf)
+
+注:我在本仓库中也上传了一份[thymeleaf中文文档(gangzi828(刘明刚 译)](https://github.com/heibaiying/spring-samples-for-all/tree/master/referenced%20documents),翻译的版本为3.0.5RELEASE
\ No newline at end of file
diff --git a/spring-boot/spring-boot-base/pom.xml b/spring-boot/spring-boot-base/pom.xml
index 9c2aaa8..c8137e9 100644
--- a/spring-boot/spring-boot-base/pom.xml
+++ b/spring-boot/spring-boot-base/pom.xml
@@ -47,6 +47,7 @@
+
diff --git a/spring-boot/spring-boot-base/src/main/java/com/heibaiying/springbootbase/SpringBootBaseApplication.java b/spring-boot/spring-boot-base/src/main/java/com/heibaiying/springbootbase/SpringBootBaseApplication.java
index 547f498..ac395d7 100644
--- a/spring-boot/spring-boot-base/src/main/java/com/heibaiying/springbootbase/SpringBootBaseApplication.java
+++ b/spring-boot/spring-boot-base/src/main/java/com/heibaiying/springbootbase/SpringBootBaseApplication.java
@@ -6,7 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootBaseApplication {
- // 启动器默认开启包扫描,扫描与主程序所在包及其子包,对于本工程而言 默认扫描 com.heibaiying.springbootbase
+ /*@SpringBootApplication 注解是一个复合注解,里面包含了@ComponentScan注解
+ 默认开启包扫描,扫描与主程序所在包及其子包,对于本工程而言 默认扫描 com.heibaiying.springbootbase*/
public static void main(String[] args) {
SpringApplication.run(SpringBootBaseApplication.class, args);
}
diff --git a/spring-boot/spring-boot-data-jpa/README.md b/spring-boot/spring-boot-data-jpa/README.md
new file mode 100644
index 0000000..2239e05
--- /dev/null
+++ b/spring-boot/spring-boot-data-jpa/README.md
@@ -0,0 +1,193 @@
+# spring boot data jpa
+
+## 一、说明
+
+#### 1.1 项目结构
+
+
+
+#### 1.2 项目主要依赖
+
+```xml
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.13
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+```
+
+## 二、data jpa 的使用
+
+#### 2.1 在application.yml 中配置数据源
+
+```yaml
+spring:
+ datasource:
+ url: jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
+ username: root
+ password: root
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ jpa:
+ hibernate:
+ ddl-auto: update
+ #Hibernate默认创建的表是myisam引擎,可以用以下方式指定为使用innodb创建表
+ database-platform: org.hibernate.dialect.MySQL57Dialect
+ show-sql: true
+```
+
+#### 2.2 新建查询接口
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 查询接口继承自CrudRepository,CrudRepository 默认定义了部分增删改查方法
+ */
+public interface ProgRepository extends CrudRepository {
+
+ /*
+ * 方法名遵循命名规范的查询 更多命名规范可以参考官方文档所列出的这张表格
+ */
+ List findAllByName(String name);
+
+ /*
+ *分页排序查询
+ */
+ Page findAll(Pageable pageable);
+
+
+ /*
+ * 占位符查询
+ */
+ @Query(value = "select u from Programmer u where u.name = ?1 or u.salary = ?2")
+ List findByConditionAndOrder(String name, float salary, Sort.Order order);
+
+
+ /*
+ * 传入参数名称
+ */
+ @Query("select u from Programmer u where u.name = :name or u.age = :age")
+ Programmer findByParam(@Param("name") String name,
+ @Param("age") int age);
+}
+
+```
+
+关于查询方法遵循的命名规范和关键词见下表:
+
+| Keyword | Sample | JPQL snippet |
+| ------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| `And` | `findByLastnameAndFirstname` | `… where x.lastname = ?1 and x.firstname = ?2` |
+| `Or` | `findByLastnameOrFirstname` | `… where x.lastname = ?1 or x.firstname = ?2` |
+| `Is,Equals` | `findByFirstname`,`findByFirstnameIs`,
`findByFirstnameEquals` | `… where x.firstname = ?1` |
+| `Between` | `findByStartDateBetween` | `… where x.startDate between ?1 and ?2` |
+| `LessThan` | `findByAgeLessThan` | `… where x.age < ?1` |
+| `LessThanEqual` | `findByAgeLessThanEqual` | `… where x.age <= ?1` |
+| `GreaterThan` | `findByAgeGreaterThan` | `… where x.age > ?1` |
+| `GreaterThanEqual` | `findByAgeGreaterThanEqual` | `… where x.age >= ?1` |
+| `After` | `findByStartDateAfter` | `… where x.startDate > ?1` |
+| `Before` | `findByStartDateBefore` | `… where x.startDate < ?1` |
+| `IsNull` | `findByAgeIsNull` | `… where x.age is null` |
+| `IsNotNull,NotNull` | `findByAge(Is)NotNull` | `… where x.age not null` |
+| `Like` | `findByFirstnameLike` | `… where x.firstname like ?1` |
+| `NotLike` | `findByFirstnameNotLike` | `… where x.firstname not like ?1` |
+| `StartingWith` | `findByFirstnameStartingWith` | `… where x.firstname like ?1`(parameter bound with appended `%`) |
+| `EndingWith` | `findByFirstnameEndingWith` | `… where x.firstname like ?1`(parameter bound with prepended `%`) |
+| `Containing` | `findByFirstnameContaining` | `… where x.firstname like ?1`(parameter bound wrapped in `%`) |
+| `OrderBy` | `findByAgeOrderByLastnameDesc` | `… where x.age = ?1 order by x.lastname desc` |
+| `Not` | `findByLastnameNot` | `… where x.lastname <> ?1` |
+| `In` | `findByAgeIn(Collection ages)` | `… where x.age in ?1` |
+| `NotIn` | `findByAgeNotIn(Collection ages)` | `… where x.age not in ?1` |
+| `True` | `findByActiveTrue()` | `… where x.active = true` |
+| `False` | `findByActiveFalse()` | `… where x.active = false` |
+| `IgnoreCase` | `findByFirstnameIgnoreCase` | `… where UPPER(x.firstame) = UPPER(?1)` |
+
+#### 2.3 测试类
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class DataJPATests {
+
+ @Autowired
+ private ProgRepository repository;
+
+ /**
+ * 保存数据测试
+ */
+ @Test
+ public void save() {
+ // 保存单条数据
+ repository.save(new Programmer("pro01", 12, 2121.34f, new Date()));
+ // 保存多条数据
+ List programmers = new ArrayList<>();
+ programmers.add(new Programmer("pro02", 22, 3221.34f, new Date()));
+ programmers.add(new Programmer("pro03", 32, 3321.34f, new Date()));
+ programmers.add(new Programmer("pro04", 44, 4561.34f, new Date()));
+ programmers.add(new Programmer("pro01", 44, 4561.34f, new Date()));
+ repository.saveAll(programmers);
+ }
+
+
+ /**
+ * 查询数据测试
+ */
+ @Test
+ public void get() {
+
+ // 遵循命名规范的查询
+ List programmers = repository.findAllByName("pro01");
+ programmers.forEach(System.out::println);
+
+ // 传入参数名称
+ Programmer param = repository.findByParam("pro02", 22);
+ System.out.println("findByParam:" + param);
+
+ // 占位符查询
+ List byCondition = repository.findByConditionAndOrder("pro03", 3321.34f, Sort.Order.asc("salary"));
+ System.out.println("byCondition:" + byCondition);
+
+ //条件与分页查询 需要注意的是这里的页数是从第0页开始计算的
+ Page page = repository.findAll(PageRequest.of(0, 10, Sort.Direction.DESC, "salary"));
+ page.get().forEach(System.out::println);
+ }
+
+
+ /**
+ * 更新数据测试
+ */
+ @Test
+ public void update() {
+ // 保存主键相同的数据就认为是更新操作
+ repository.save(new Programmer(1, "updatePro01", 12, 2121.34f, new Date()));
+ Optional programmer = repository.findById(1);
+ Assert.assertEquals(programmer.get().getName(), "updatePro01");
+ }
+
+ /**
+ * 删除数据测试
+ */
+ @Test
+ public void delete() {
+ Optional programmer = repository.findById(2);
+ if (programmer.isPresent()) {
+ repository.deleteById(2);
+ }
+ Assert.assertFalse(programmer.isPresent());
+ }
+}
+```
+
diff --git a/spring-boot/spring-boot-data-jpa/src/main/resources/application.yml b/spring-boot/spring-boot-data-jpa/src/main/resources/application.yml
index 504d2a7..e044e55 100644
--- a/spring-boot/spring-boot-data-jpa/src/main/resources/application.yml
+++ b/spring-boot/spring-boot-data-jpa/src/main/resources/application.yml
@@ -1,6 +1,6 @@
spring:
datasource:
- url: jdbc:mysql://127.0.0.1:3306/mysql?useUnicode=true&characterEncoding=utf-8
+ url: jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
diff --git a/spring-boot/spring-boot-druid-mybatis/README.md b/spring-boot/spring-boot-druid-mybatis/README.md
new file mode 100644
index 0000000..3435f70
--- /dev/null
+++ b/spring-boot/spring-boot-druid-mybatis/README.md
@@ -0,0 +1,196 @@
+# spring boot 整合 druid+mybatis
+
+## 一、说明
+
+#### 1.1 项目结构
+
+1. 项目查询用的表对应的建表语句放置在resources的sql文件夹下;
+
+2. 为了使用druid控制台的功能,项目以web的方式构建。
+
+
+
+#### 1.2 项目主要依赖
+
+需要说明的是按照spring 官方对应自定义的starter 命名规范的推荐:
+
+- 官方的starter命名:spring-boot-starter-XXXX
+- 其他第三方starter命名:XXXX-spring-boot-starte
+
+所以mybatis的starter命名为mybatis-spring-boot-starter,如果有自定义starter需求,也需要按照此命名规则进行命名。
+
+```xml
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.3.2
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.13
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ 1.1.10
+
+```
+
+spring boot 与 mybatis 版本的对应关系:
+
+| MyBatis-Spring-Boot-Starter | [MyBatis-Spring](http://www.mybatis.org/spring/index.html#Requirements) | Spring Boot |
+| --------------------------- | ------------------------------------------------------------ | ------------- |
+| **1.3.x (1.3.1)** | 1.3 or higher | 1.5 or higher |
+| **1.2.x (1.2.1)** | 1.3 or higher | 1.4 or higher |
+| **1.1.x (1.1.1)** | 1.3 or higher | 1.3 or higher |
+| **1.0.x (1.0.2)** | 1.2 or higher | 1.3 or higher |
+
+
+
+## 二、整合 druid + mybatis
+
+#### 2.1 在application.yml 中配置数据源
+
+本用例采用druid作为数据库连接池,虽然druid性能略逊于Hikari,但是提供了更为全面的监控管理,可以按照实际需求选用druid或者Hikari。(关于Hikari数据源的配置可以参考[spring-boot-mbatis项目](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-mybatis))
+
+```yaml
+spring:
+ datasource:
+ url: jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
+ username: root
+ password: root
+ driver-class-name: com.mysql.cj.jdbc.Driver
+
+ # 使用 druid 作为连接池 更多配置的说明可以参见 druid starter 中文文档 https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
+ type: com.alibaba.druid.pool.DruidDataSource
+ druid:
+ # 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
+ initialSize: 5
+ # 最小连接池数量
+ minIdle: 5
+ # 最大连接池数量
+ maxActive: 10
+ # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
+ maxWait: 60000
+ # Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
+ timeBetweenEvictionRunsMillis: 60000
+ # 连接保持空闲而不被驱逐的最小时间
+ minEvictableIdleTimeMillis: 300000
+ # 用来检测连接是否有效的sql 因数据库方言而差, 例如 oracle 应该写成 SELECT 1 FROM DUAL
+ validationQuery: SELECT 1
+ # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
+ testWhileIdle: true
+ # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
+ testOnBorrow: false
+ # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
+ testOnReturn: false
+ # 是否自动回收超时连接
+ removeAbandoned: true
+ # 超时时间(以秒数为单位)
+ remove-abandoned-timeout: 180
+
+ # druid 监控的配置 如果不使用 druid 的监控功能的话 以下配置就不是必须的
+ # 本项目监控台访问地址: http://localhost:8080/druid/login.html
+
+ # WebStatFilter用于采集web-jdbc关联监控的数据。
+ # 更多配置可参见: https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter
+ web-stat-filter:
+ # 是否开启 WebStatFilter 默认是true
+ enabled: true
+ # 需要拦截的url
+ url-pattern: /*
+ # 排除静态资源的请求
+ exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
+
+ # Druid内置提供了一个StatViewServlet用于展示Druid的统计信息。
+ # 更多配置可参见:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
+ stat-view-servlet:
+ #是否启用StatViewServlet 默认值true
+ enabled: true
+ # 需要拦截的url
+ url-pattern: /druid/*
+ # 允许清空统计数据
+ reset-enable: true
+ login-username: druid
+ login-password: druid
+
+
+
+# mybatis 相关配置
+mybatis:
+ configuration:
+ # 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。
+ # oracle数据库建议配置为JdbcType.NULL, 默认是Other
+ jdbc-type-for-null: 'null'
+ # 是否打印sql语句 调试的时候可以开启
+log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+```
+
+#### 2.2 新建查询接口和controller
+
+```java
+@Mapper
+public interface ProgrammerDao {
+
+
+ @Select("select * from programmer")
+ List selectAll();
+
+ @Insert("insert into programmer (name, age, salary, birthday) VALUES (#{name}, #{age}, #{salary}, #{birthday})")
+ void save(Programmer programmer);
+
+ @Select("select * from programmer where name = #{id}")
+ Programmer selectById(int id);
+
+ @Update("update programmer set name=#{name},age=#{age},salary=#{salary},birthday=#{birthday} where id=#{id}")
+ int modify(Programmer programmer);
+
+ @Delete(" delete from programmer where id = #{id}")
+ void delete(int id);
+}
+```
+
+```xml
+@RestController
+public class ProgrammerController {
+
+ @Autowired
+ private ProgrammerDao programmerDao;
+
+ @GetMapping("/programmers")
+ public List get() {
+ return programmerDao.selectAll();
+ }
+}
+```
+
+#### 2.3 关于druid监控数据的外部化调用
+
+```java
+/**
+ * @author : heibaiying
+ * @description :在 Spring Boot 中可以通过 HTTP 接口将 Druid 监控数据以JSON 的形式暴露出去,
+ * 实际使用中你可以根据你的需要自由地对监控数据、暴露方式进行扩展。
+ */
+
+@RestController
+public class DruidStatController {
+
+ @GetMapping("/stat")
+ public Object druidStat() {
+ // DruidStatManagerFacade#getDataSourceStatDataList 该方法可以获取所有数据源的监控数据
+ return DruidStatManagerFacade.getInstance().getDataSourceStatDataList();
+ }
+}
+```
+
+
+
+
+
+#### 2.4 druid 控制台的使用,默认访问地址 http://localhost:8080/druid/login.html
+
+
\ No newline at end of file
diff --git a/spring-boot/spring-boot-druid-mybatis/src/main/resources/application.yml b/spring-boot/spring-boot-druid-mybatis/src/main/resources/application.yml
index 47d3129..4356fc8 100644
--- a/spring-boot/spring-boot-druid-mybatis/src/main/resources/application.yml
+++ b/spring-boot/spring-boot-druid-mybatis/src/main/resources/application.yml
@@ -1,71 +1,70 @@
spring:
datasource:
- url: jdbc:mysql://127.0.0.1:3306/mysql?useUnicode=true&characterEncoding=utf-8
+ url: jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
- # ʹ druid Ϊӳ õ˵Բμ druid starter ĵ https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
+ # 使用 druid 作为连接池 更多配置的说明可以参见 druid starter 中文文档 https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
type: com.alibaba.druid.pool.DruidDataSource
druid:
- # ʼʱӵĸʼʾinitߵһgetConnectionʱ
+ # 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
initialSize: 5
- # Сӳ
+ # 最小连接池数量
minIdle: 5
- # ӳ
+ # 最大连接池数量
maxActive: 10
- # ȡʱȴʱ䣬λ롣maxWait֮ȱʡùƽЧʻ½ҪͨuseUnfairLockΪtrueʹ÷ǹƽ
+ # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
maxWait: 60000
- # Destroy̻߳ӵļʱ䣬ӿʱڵminEvictableIdleTimeMillisرӡ
+ # Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
timeBetweenEvictionRunsMillis: 60000
- # ӱֿжСʱ
+ # 连接保持空闲而不被驱逐的最小时间
minEvictableIdleTimeMillis: 300000
- # ǷЧsql ݿⷽԶ, oracle Ӧд SELECT 1 FROM DUAL
+ # 用来检测连接是否有效的sql 因数据库方言而差, 例如 oracle 应该写成 SELECT 1 FROM DUAL
validationQuery: SELECT 1
- # ΪtrueӰܣұ֤ȫԡӵʱ⣬ʱtimeBetweenEvictionRunsMillisִvalidationQueryǷЧ
+ # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
testWhileIdle: true
- # ʱִvalidationQueryǷЧûήܡ
+ # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnBorrow: false
- # 黹ʱִvalidationQueryǷЧûήܡ
+ # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturn: false
- # ǷԶճʱ
+ # 是否自动回收超时连接
removeAbandoned: true
- # ʱʱ(Ϊλ)
+ # 超时时间(以秒数为单位)
remove-abandoned-timeout: 180
- # druid ص ʹ druid ļعܵĻ þͲDZ
- # Ŀ̨ʵַ: http://localhost:8080/druid/login.html
+ # druid 监控的配置 如果不使用 druid 的监控功能的话 以下配置就不是必须的
+ # 本项目监控台访问地址: http://localhost:8080/druid/login.html
- # WebStatFilterڲɼweb-jdbcصݡ
- # ÿɲμ: https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter
+ # WebStatFilter用于采集web-jdbc关联监控的数据。
+ # 更多配置可参见: https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter
web-stat-filter:
- # Ƿ WebStatFilter Ĭtrue
+ # 是否开启 WebStatFilter 默认是true
enabled: true
- # Ҫصurl
+ # 需要拦截的url
url-pattern: /*
- # ų̬Դ
+ # 排除静态资源的请求
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
- # DruidṩһStatViewServletչʾDruidͳϢ
- # ÿɲμ:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
+ # Druid内置提供了一个StatViewServlet用于展示Druid的统计信息。
+ # 更多配置可参见:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
stat-view-servlet:
- #ǷStatViewServlet Ĭֵtrue
+ #是否启用StatViewServlet 默认值true
enabled: true
- # Ҫصurl
+ # 需要拦截的url
url-pattern: /druid/*
- # ͳ
+ # 允许清空统计数据
reset-enable: true
login-username: druid
login-password: druid
-# mybatis
+# mybatis 相关配置
mybatis:
configuration:
- # ûΪṩض JDBC ʱΪֵָ JDBC ͡
- # oracleݿ⽨ΪJdbcType.NULL, ĬOther
+ # 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。
+ # oracle数据库建议配置为JdbcType.NULL, 默认是Other
jdbc-type-for-null: 'null'
- # Ƿӡsql ԵʱԿ
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-
+ # 是否打印sql语句 调试的时候可以开启
+log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
\ No newline at end of file
diff --git a/spring-boot/spring-boot-dubbo/README.md b/spring-boot/spring-boot-dubbo/README.md
new file mode 100644
index 0000000..9116d9c
--- /dev/null
+++ b/spring-boot/spring-boot-dubbo/README.md
@@ -0,0 +1,348 @@
+# spring boot 整合 dubbo
+
+## 一、 项目结构说明
+
+1.1 按照dubbo 文档推荐的服务最佳实践,建议将服务接口、服务模型、服务异常等均放在 API 包中,所以项目采用maven多模块的构建方式,在spring-boot-dubbo下构建三个子模块:
+
+1. boot-dubbo-common 是公共模块,用于存放公共的接口和bean,被boot-dubbo-provider和boot-dubbo-consumer在pom.xml中引用;
+2. boot-dubbo-provider 是服务的提供者,提供商品的查询服务;
+3. boot-dubbo-consumer是服务的消费者,调用provider提供的查询服务。
+
+1.2 本项目dubbo的搭建采用zookeeper作为注册中心, 关于zookeeper的安装和基本操作可以参见我的手记 [Zookeeper 基础命令与Java客户端](https://github.com/heibaiying/LearningNotes/blob/master/notes/%E4%B8%AD%E9%97%B4%E4%BB%B6/ZooKeeper/ZooKeeper%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA%E4%B8%8EJava%E5%AE%A2%E6%88%B7%E7%AB%AF.md)
+
+
+
+
+
+## 二、关键依赖
+
+在父工程的项目中统一导入依赖dubbo的starter,父工程的pom.xml如下
+
+```xml
+
+
+ 4.0.0
+ pom
+
+
+ boot-dubbo-common
+ boot-dubbo-consumer
+ boot-dubbo-provider
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.1.RELEASE
+
+
+ com.heibaiying
+ spring-boot-dubbo
+ 0.0.1-SNAPSHOT
+ spring-boot-dubbo
+ Demo project for Spring Boot
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-freemarker
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ com.alibaba.boot
+ dubbo-spring-boot-starter
+ 0.2.0
+
+
+
+
+```
+
+
+
+## 三、公共模块(boot-dubbo-common)
+
+- api 下为公共的调用接口;
+- bean 下为公共的实体类。
+
+
+
+## 四、 服务提供者(boot-dubbo-provider)
+
+
+
+#### 4.1 提供方配置
+
+```yaml
+dubbo:
+ application:
+ name: boot-duboo-provider
+ # 指定注册协议和注册地址 dubbo推荐使用zookeeper作为注册中心,并且在start依赖中引入了zookeeper的java客户端Curator
+ registry:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocol.name: dubbo
+```
+
+#### 4.2 使用注解@Service暴露服务
+
+需要注意的是这里的@Service注解不是spring的注解,而是dubbo的注解 com.alibaba.dubbo.config.annotation.Service
+
+```java
+package com.heibaiying.dubboprovider.service;
+
+import com.alibaba.dubbo.config.annotation.Service;
+import com.heibaiying.api.IProductService;
+import com.heibaiying.bean.Product;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author : heibaiying
+ * @description : 产品提供接口实现类
+ */
+@Service(timeout = 5000)
+public class ProductService implements IProductService {
+
+ private static List productList = new ArrayList<>();
+
+ static {
+ for (int i = 0; i < 20; i++) {
+ productList.add(new Product(i, "产品" + i, i / 2 == 0, new Date(), 66.66f * i));
+ }
+ }
+
+ public Product queryProductById(int id) {
+ for (Product product : productList) {
+ if (product.getId() == id) {
+ return product;
+ }
+ }
+ return null;
+ }
+
+
+ public List queryAllProducts() {
+ return productList;
+ }
+}
+
+```
+
+## 五、服务消费者(boot-dubbo-consumer)
+
+
+
+#### 1.消费方的配置
+
+```yaml
+dubbo:
+ application:
+ name: boot-duboo-provider
+ # 指定注册协议和注册地址 dubbo推荐使用zookeeper作为注册中心,并且在start依赖中引入了zookeeper的java客户端Curator
+ registry:
+ protocol: zookeeper
+ address: 127.0.0.1:2181
+ protocol.name: dubbo
+ # 关闭所有服务的启动时检查 (没有提供者时报错)视实际情况设置
+ consumer:
+ check: false
+server:
+port: 8090
+```
+
+#### 2.使用注解@Reference引用远程服务
+
+```java
+package com.heibaiying.dubboconsumer.controller;
+
+import com.alibaba.dubbo.config.annotation.Reference;
+import com.heibaiying.api.IProductService;
+import com.heibaiying.bean.Product;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.List;
+
+@Controller
+@RequestMapping("sell")
+public class SellController {
+
+ // dubbo远程引用注解
+ @Reference
+ private IProductService productService;
+
+ @RequestMapping
+ public String productList(Model model) {
+ List products = productService.queryAllProducts();
+ model.addAttribute("products", products);
+ return "products";
+ }
+
+ @RequestMapping("product/{id}")
+ public String productDetail(@PathVariable int id, Model model) {
+ Product product = productService.queryProductById(id);
+ model.addAttribute("product", product);
+ return "product";
+ }
+}
+```
+
+## 六、项目构建的说明
+
+因为在项目中,consumer和provider模块均依赖公共模块,所以在构建consumer和provider项目前需要将common 模块安装到本地仓库,**依次**对**父工程**和**common模块**执行:
+
+```shell
+mvn install -Dmaven.test.skip = true
+```
+
+consumer中 pom.xml如下
+
+```xml
+
+
+ 4.0.0
+
+
+ spring-boot-dubbo
+ com.heibaiying
+ 0.0.1-SNAPSHOT
+
+
+ boot-dubbo-consumer
+ 0.0.1-SNAPSHOT
+ boot-dubbo-consumer
+ dubbo project for Spring Boot
+
+
+ 1.8
+
+
+
+
+
+ com.heibaiying
+ boot-dubbo-common
+ 0.0.1-SNAPSHOT
+ compile
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+```
+
+provider中 pom.xml如下
+
+```xml
+
+
+ 4.0.0
+
+
+ spring-boot-dubbo
+ com.heibaiying
+ 0.0.1-SNAPSHOT
+
+
+
+ boot-dubbo-provider
+ 0.0.1-SNAPSHOT
+ boot-dubbo-provider
+ dubbo project for Spring Boot
+
+
+ 1.8
+
+
+
+
+
+ com.heibaiying
+ boot-dubbo-common
+ 0.0.1-SNAPSHOT
+ compile
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+```
+
+## 七、关于dubbo新版本管理控制台的安装说明
+
+安装:
+
+```sh
+git clone https://github.com/apache/incubator-dubbo-ops.git /var/tmp/dubbo-ops
+cd /var/tmp/dubbo-ops
+mvn clean package
+```
+
+配置:
+
+```sh
+配置文件为:
+dubbo-admin-backend/src/main/resources/application.properties
+主要的配置有 默认的配置就是127.0.0.1:2181:
+dubbo.registry.address=zookeeper://127.0.0.1:2181
+```
+
+启动:
+
+```sh
+mvn --projects dubbo-admin-backend spring-boot:run
+```
+
+访问:
+
+```
+http://127.0.0.1:8080
+```
\ No newline at end of file
diff --git a/spring-boot/spring-boot-dubbo/boot-dubbo-consumer/src/main/resources/application.yml b/spring-boot/spring-boot-dubbo/boot-dubbo-consumer/src/main/resources/application.yml
index 023f3f1..f1e417e 100644
--- a/spring-boot/spring-boot-dubbo/boot-dubbo-consumer/src/main/resources/application.yml
+++ b/spring-boot/spring-boot-dubbo/boot-dubbo-consumer/src/main/resources/application.yml
@@ -1,14 +1,13 @@
dubbo:
application:
name: boot-duboo-provider
- # ָעЭעַ dubboƼʹzookeeperΪעģstartzookeeperjavaͻCurator
+ # 指定注册协议和注册地址 dubbo推荐使用zookeeper作为注册中心,并且在start依赖中引入了zookeeper的java客户端Curator
registry:
protocol: zookeeper
address: 127.0.0.1:2181
protocol.name: dubbo
- # رзʱ (ûṩʱʵ
+ # 关闭所有服务的启动时检查 (没有提供者时报错)视实际情况设置
consumer:
check: false
server:
- port: 8090
-
+port: 8090
\ No newline at end of file
diff --git a/spring-boot/spring-boot-dubbo/boot-dubbo-provider/src/main/resources/application.yml b/spring-boot/spring-boot-dubbo/boot-dubbo-provider/src/main/resources/application.yml
index 464875f..d4e5972 100644
--- a/spring-boot/spring-boot-dubbo/boot-dubbo-provider/src/main/resources/application.yml
+++ b/spring-boot/spring-boot-dubbo/boot-dubbo-provider/src/main/resources/application.yml
@@ -1,8 +1,8 @@
dubbo:
application:
name: boot-duboo-provider
- # ָעЭעַ dubboƼʹzookeeperΪעģstartzookeeperjavaͻCurator
+ # 指定注册协议和注册地址 dubbo推荐使用zookeeper作为注册中心,并且在start依赖中引入了zookeeper的java客户端Curator
registry:
protocol: zookeeper
address: 127.0.0.1:2181
- protocol.name: dubbo
+ protocol.name: dubbo
\ No newline at end of file
diff --git a/spring-boot/spring-boot-jsp/README.md b/spring-boot/spring-boot-jsp/README.md
new file mode 100644
index 0000000..be18f2e
--- /dev/null
+++ b/spring-boot/spring-boot-jsp/README.md
@@ -0,0 +1,84 @@
+# spring boot 内置容器 整合 jsp
+
+## 一、说明
+
+#### 1.1 项目结构
+
+
+
+#### 1.2 项目主要依赖
+
+```xml
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-jasper
+ provided
+
+
+
+ javax.servlet
+ jstl
+
+```
+
+## 二、整合 jsp
+
+#### 2.1 导入整合的依赖
+
+```xml
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-jasper
+ provided
+
+
+
+ javax.servlet
+ jstl
+
+```
+
+#### 2.2 在application.yml 中指定访问视图文件的前缀和后缀
+
+```yml
+spring:
+ mvc:
+ view:
+ prefix: /WEB-INF/jsp/
+ suffix: .jsp
+```
+
+#### 2.3 新建controller和show.jsp 测试整合是否成功
+
+```java
+@Controller
+@RequestMapping("index")
+public class JspController {
+
+ @RequestMapping
+ public String jsp(Model model){
+ Programmer programmer = new Programmer("heibai", 21, 1298.31f, LocalDate.now());
+ model.addAttribute("programmer",programmer);
+ return "show";
+ }
+}
+```
+
+```jsp
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+ programmer
+
+
+
+
+ - 姓名: ${programmer.name}
+ - 年龄: ${programmer.age}
+
+
+
+```
+
diff --git a/spring-boot/spring-boot-jsp/pom.xml b/spring-boot/spring-boot-jsp/pom.xml
index 07b7ad7..615c274 100644
--- a/spring-boot/spring-boot-jsp/pom.xml
+++ b/spring-boot/spring-boot-jsp/pom.xml
@@ -40,6 +40,7 @@
tomcat-embed-jasper
provided
+
javax.servlet
jstl
diff --git a/spring-boot/spring-boot-memcached/README.md b/spring-boot/spring-boot-memcached/README.md
new file mode 100644
index 0000000..725a1a8
--- /dev/null
+++ b/spring-boot/spring-boot-memcached/README.md
@@ -0,0 +1,148 @@
+# spring boot 整合 mecached
+
+## 一、说明
+
+### 1.1 XMemcached客户端说明
+
+spring boot 官方并没有提供关于 memcached 的starter,所以我们这里还是采用XMemcached作为客户端进行整合。 XMemcached是基于java nio的memcached高性能客户端,支持完整的memcached协议,支持客户端分布并且提供了一致性哈希(consistent hash)算法的实现。
+
+### 1.2 项目结构说明
+
+memcached的整合配置位于config文件夹下。
+
+
+
+### 1.3 主要依赖
+
+```xml
+
+
+ com.googlecode.xmemcached
+ xmemcached
+ 2.4.5
+
+```
+
+
+
+## 二、spring boot 整合 memcached
+
+#### 2.1 单机配置
+
+```java
+@Bean
+public MemcachedClient memcachedClient() {
+ XMemcachedClientBuilder builder = new XMemcachedClientBuilder("192.168.200.201:11211");
+ MemcachedClient memcachedClient = null;
+try {
+ memcachedClient = builder.build();
+ } catch (IOException e) {
+ e.printStackTrace();
+}
+ return memcachedClient;
+}
+```
+
+#### 2.2 集群配置
+
+```java
+@Bean
+public MemcachedClient memcachedClientForCluster() {
+
+ List addressList = new ArrayList();
+ addressList.add(new InetSocketAddress("192.168.200.201", 11211));
+ addressList.add(new InetSocketAddress("192.168.200.201", 11212));
+ // 赋予权重
+ int[] weights = {1, 2};
+ XMemcachedClientBuilder builder = new XMemcachedClientBuilder(addressList, weights);
+ // 设置连接池大小
+ builder.setConnectionPoolSize(10);
+ // 协议工厂
+ builder.setCommandFactory(new TextCommandFactory());
+ // 分布策略,一致性哈希KetamaMemcachedSessionLocator或者ArraySessionLocator(默认)
+ builder.setSessionLocator(new KetamaMemcachedSessionLocator());
+ // 设置序列化器
+ builder.setTranscoder(new SerializingTranscoder());
+ MemcachedClient memcachedClient = null;
+ try {
+ memcachedClient = builder.build();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return memcachedClient;
+}
+```
+
+#### 2.3 存储基本类型测试用例
+
+xmemcached单机版本和集群版本注入的实例是相同的。
+
+```java
+/**
+ * @author : heibaiying
+ * @description : Memcached 操作基本对象
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MemSamples {
+
+ @Autowired
+ private MemcachedClient memcachedClient;
+
+ @Test
+ public void operate() throws InterruptedException, MemcachedException, TimeoutException {
+ memcachedClient.set("hello", 0, "Hello,cluster xmemcached");
+ String value = memcachedClient.get("hello");
+ System.out.println("hello=" + value);
+ memcachedClient.delete("hello");
+ value = memcachedClient.get("hello");
+ System.out.println("hello=" + value);
+ }
+}
+```
+
+#### 2.5 存储实体对象测试用例
+
+```java
+/**
+ * @author : heibaiying
+ * @description :Memcached 序列化与反序列化
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MemObjectSamples {
+
+ @Autowired
+ private MemcachedClient memcachedClient;
+
+ @Test
+ public void operate() throws InterruptedException, MemcachedException, TimeoutException {
+ memcachedClient.set("programmer", 0, new Programmer("xiaoming", 12, 5000.21f, new Date()));
+ Programmer programmer = memcachedClient.get("programmer");
+ System.out.println("hello ," + programmer.getName());
+ memcachedClient.delete("programmer");
+ programmer = memcachedClient.get("programmer");
+ Assert.assertNull(programmer);
+ }
+}
+
+```
+
+
+
+## 附:memcached 基本命令
+
+| 命令 | 格式 | 说明 |
+| --------------- | -------------------------------------------------- | ------------------------------------- |
+| 新增 set | set key flags exTime length -> value | 无论什么情况,都可以插入 |
+| 新增 add | add key flags exTime length -> value | 只有当key不存在的情况下,才可以插入 |
+| 替换 replace | replace key flags exTime length -> value | 只修改已存在key的value值 |
+| 追加内容append | append key flags exTime length -> value | length表示追加的长度而不是总长度 |
+| 前面追加prepend | prepend key flags exTime length -> value | length表示追加的长度而不是总长度 |
+| 查询操作 get | get key | |
+| 检查更新 cas | cas key flags exTime length version -> value | 版本正确才更新 |
+| 详细获取 gets | gets key | 返回的最后一个数代表 key 的 CAS 令牌 |
+| 删除 delete | delete key | 将数据打一个删除标记 |
+| 自增 incr | incr key 增加偏移量 | incr和decr只能操作能转换为数字的Value |
+| 自减 decr | decr key 减少偏移量 | desr不能将数字减少至0以下 |
+| 清库 | flush_all | |
\ No newline at end of file
diff --git a/spring-boot/spring-boot-memcached/pom.xml b/spring-boot/spring-boot-memcached/pom.xml
index 8dff5fc..0535c5e 100644
--- a/spring-boot/spring-boot-memcached/pom.xml
+++ b/spring-boot/spring-boot-memcached/pom.xml
@@ -35,7 +35,7 @@
true
-
+
com.googlecode.xmemcached
xmemcached
diff --git a/spring-boot/spring-boot-mongodb/README.md b/spring-boot/spring-boot-mongodb/README.md
new file mode 100644
index 0000000..dfa0d09
--- /dev/null
+++ b/spring-boot/spring-boot-mongodb/README.md
@@ -0,0 +1,182 @@
+# spring boot 整合 mongodb
+
+## 一、说明
+
+#### 1.1 用例结构
+
+1. 本用例提供mongdb的简单整合用例;
+2. 提供用MongoTemplate的方式操作mongdb,见测试用例MongoOriginalTests.java
+3. 提供基于spring data jpa 的方式操作mongodb(推荐),见测试用例MongoJPATests.java
+
+
+
+#### 1.2 项目主要依赖
+
+```xml
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+```
+
+
+
+## 二、整合 mongodb
+
+#### 2.1 在application.yml 中配置mongodb数据源
+
+```yaml
+spring:
+ data:
+ mongodb:
+ database: spring
+ uri: mongodb://192.168.0.108:27017
+```
+
+#### 2.2 基于MongoTemplate实现对mongodb的操作
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MongoOriginalTests {
+
+ @Autowired
+ private MongoTemplate mongoTemplate;
+
+ @Test
+ public void insert() {
+ // 单条插入
+ mongoTemplate.insert(new Programmer("xiaoming", 12, 5000.21f, new Date()));
+ List programmers = new ArrayList();
+ // 批量插入
+ programmers.add(new Programmer("xiaohong", 21, 52200.21f, new Date()));
+ programmers.add(new Programmer("xiaolan", 34, 500.21f, new Date()));
+ mongoTemplate.insert(programmers, Programmer.class);
+ }
+
+ // 条件查询
+ @Test
+ public void select() {
+ Criteria criteria = new Criteria();
+ criteria.andOperator(where("name").is("xiaohong"), where("age").is(21));
+ Query query = new Query(criteria);
+ Programmer one = mongoTemplate.findOne(query, Programmer.class);
+ System.out.println(one);
+ }
+
+
+ // 更新数据
+ @Test
+ public void MUpdate() {
+ UpdateResult updateResult = mongoTemplate.updateMulti(query(where("name").is("xiaoming")), update("age", 35), Programmer.class);
+ System.out.println("更新记录数:" + updateResult.getModifiedCount());
+ }
+
+ // 删除指定数据
+ @Test
+ public void delete() {
+ DeleteResult result = mongoTemplate.remove(query(where("name").is("xiaolan")), Programmer.class);
+ System.out.println("影响记录数:" + result.getDeletedCount());
+ System.out.println("是否成功:" + result.wasAcknowledged());
+ }
+
+}
+```
+
+#### 2.3 使用 data jpa 方式操作mongodb (推荐使用)
+
+1.新建查询结构,查询方法按照支持的关键字命名
+
+```java
+public interface ProgrammerRepository extends MongoRepository {
+
+ void deleteAllByName(String name);
+
+ Programmer findAllByName(String names);
+
+ Programmer findByNameAndAge(String name, int age);
+
+}
+```
+
+2.测试
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MongoJPATests {
+
+ @Autowired
+ private ProgrammerRepository repository;
+
+ @Test
+ public void insert() {
+ // 单条插入
+ repository.save(new Programmer("python", 23, 21832.34f, new Date()));
+ // 批量插入
+ List programmers = new ArrayList();
+ programmers.add(new Programmer("java", 21, 52200.21f, new Date()));
+ programmers.add(new Programmer("Go", 34, 500.21f, new Date()));
+ repository.saveAll(programmers);
+ }
+
+ // 条件查询
+ @Test
+ public void select() {
+ Programmer java = repository.findByNameAndAge("java", 21);
+ Assert.assertEquals(java.getSalary(), 52200.21f, 0.01);
+ }
+
+
+ // 更新数据
+ @Test
+ public void MUpdate() {
+ repository.save(new Programmer("Go", 8, 500.21f, new Date()));
+ Programmer go = repository.findAllByName("Go");
+ Assert.assertEquals(go.getAge(), 8);
+ }
+
+ // 删除指定数据
+ @Test
+ public void delete() {
+ repository.deleteAllByName("python");
+ Optional python = repository.findById("python");
+ Assert.assertFalse(python.isPresent());
+ }
+
+}
+```
+
+查询方法支持的关键字如下,更多命名规范可以参见Spring Data MongoDB官方文档[Query Methods](https://docs.spring.io/spring-data/mongodb/docs/2.1.3.RELEASE/reference/html/#mongodb.repositories.queries):
+
+| Keyword | Sample | Logical result |
+| ------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| `After` | `findByBirthdateAfter(Date date)` | `{"birthdate" : {"$gt" : date}}` |
+| `GreaterThan` | `findByAgeGreaterThan(int age)` | `{"age" : {"$gt" : age}}` |
+| `GreaterThanEqual` | `findByAgeGreaterThanEqual(int age)` | `{"age" : {"$gte" : age}}` |
+| `Before` | `findByBirthdateBefore(Date date)` | `{"birthdate" : {"$lt" : date}}` |
+| `LessThan` | `findByAgeLessThan(int age)` | `{"age" : {"$lt" : age}}` |
+| `LessThanEqual` | `findByAgeLessThanEqual(int age)` | `{"age" : {"$lte" : age}}` |
+| `Between` | `findByAgeBetween(int from, int to)` | `{"age" : {"$gt" : from, "$lt" : to}}` |
+| `In` | `findByAgeIn(Collection ages)` | `{"age" : {"$in" : [ages…]}}` |
+| `NotIn` | `findByAgeNotIn(Collection ages)` | `{"age" : {"$nin" : [ages…]}}` |
+| `IsNotNull`, `NotNull` | `findByFirstnameNotNull()` | `{"firstname" : {"$ne" : null}}` |
+| `IsNull`, `Null` | `findByFirstnameNull()` | `{"firstname" : null}` |
+| `Like`, `StartingWith`, `EndingWith` | `findByFirstnameLike(String name)` | `{"firstname" : name} (name as regex)` |
+| `NotLike`, `IsNotLike` | `findByFirstnameNotLike(String name)` | `{"firstname" : { "$not" : name }} (name as regex)` |
+| `Containing` on String | `findByFirstnameContaining(String name)` | `{"firstname" : name} (name as regex)` |
+| `NotContaining` on String | `findByFirstnameNotContaining(String name)` | `{"firstname" : { "$not" : name}} (name as regex)` |
+| `Containing` on Collection | `findByAddressesContaining(Address address)` | `{"addresses" : { "$in" : address}}` |
+| `NotContaining` on Collection | `findByAddressesNotContaining(Address address)` | `{"addresses" : { "$not" : { "$in" : address}}}` |
+| `Regex` | `findByFirstnameRegex(String firstname)` | `{"firstname" : {"$regex" : firstname }}` |
+| `(No keyword)` | `findByFirstname(String name)` | `{"firstname" : name}` |
+| `Not` | `findByFirstnameNot(String name)` | `{"firstname" : {"$ne" : name}}` |
+| `Near` | `findByLocationNear(Point point)` | `{"location" : {"$near" : [x,y]}}` |
+| `Near` | `findByLocationNear(Point point, Distance max)` | `{"location" : {"$near" : [x,y], "$maxDistance" : max}}` |
+| `Near` | `findByLocationNear(Point point, Distance min, Distance max)` | `{"location" : {"$near" : [x,y], "$minDistance" : min, "$maxDistance" : max}}` |
+| `Within` | `findByLocationWithin(Circle circle)` | `{"location" : {"$geoWithin" : {"$center" : [ [x, y], distance]}}}` |
+| `Within` | `findByLocationWithin(Box box)` | `{"location" : {"$geoWithin" : {"$box" : [ [x1, y1], x2, y2]}}}` |
+| `IsTrue`, `True` | `findByActiveIsTrue()` | `{"active" : true}` |
+| `IsFalse`, `False` | `findByActiveIsFalse()` | `{"active" : false}` |
+| `Exists` | `findByLocationExists(boolean exists)` | `{"location" : {"$exists" : exists }}` |
+
diff --git a/spring-boot/spring-boot-mybatis/README.md b/spring-boot/spring-boot-mybatis/README.md
new file mode 100644
index 0000000..0d287a6
--- /dev/null
+++ b/spring-boot/spring-boot-mybatis/README.md
@@ -0,0 +1,249 @@
+# spring boot 整合 mybatis
+
+## 一、说明
+
+#### 1.1 项目结构
+
+1. 项目查询用的表对应的建表语句放置在resources的sql文件夹下;
+
+2. 关于mybatis sql的写法提供两种方式:
+
+ xml 写法:对应的类为ProgrammerMapper.java 和 programmerMapper.xml,用MybatisXmlTest进行测试;
+
+ 注解写法:对应的类为Programmer.java ,用MybatisAnnotationTest进行测试。
+
+
+
+#### 1.2 项目主要依赖
+
+需要说明的是按照spring 官方对应自定义的starter 命名规范的推荐:
+
+- 官方的starter命名:spring-boot-starter-XXXX
+- 其他第三方starter命名:XXXX-spring-boot-starte
+
+所以mybatis的starter命名为mybatis-spring-boot-starter,如果有自定义starter需求,也需要按照此命名规则进行命名。
+
+```xml
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.3.2
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.13
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+```
+
+spring boot 与 mybatis 版本的对应关系:
+
+| MyBatis-Spring-Boot-Starter | [MyBatis-Spring](http://www.mybatis.org/spring/index.html#Requirements) | Spring Boot |
+| --------------------------- | ------------------------------------------------------------ | ------------- |
+| **1.3.x (1.3.1)** | 1.3 or higher | 1.5 or higher |
+| **1.2.x (1.2.1)** | 1.3 or higher | 1.4 or higher |
+| **1.1.x (1.1.1)** | 1.3 or higher | 1.3 or higher |
+| **1.0.x (1.0.2)** | 1.2 or higher | 1.3 or higher |
+
+## 二、整合 mybatis
+
+#### 2.1 在application.yml 中配置数据源
+
+spring boot 2.x 版本默认采用Hikari作为数据库连接池,Hikari是目前java平台性能最好的连接池,性能好于druid。
+
+```yaml
+spring:
+ datasource:
+ url: jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
+ username: root
+ password: root
+ driver-class-name: com.mysql.cj.jdbc.Driver
+
+ # 如果不想配置对数据库连接池做特殊配置的话,以下关于连接池的配置就不是必须的
+ # spring-boot 2 默认采用高性能的 Hikari 作为连接池 更多配置可以参考 https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby
+ type: com.zaxxer.hikari.HikariDataSource
+ hikari:
+ # 池中维护的最小空闲连接数
+ minimum-idle: 10
+ # 池中最大连接数,包括闲置和使用中的连接
+ maximum-pool-size: 20
+ # 此属性控制从池返回的连接的默认自动提交行为。默认为true
+ auto-commit: true
+ # 允许最长空闲时间
+ idle-timeout: 30000
+ # 此属性表示连接池的用户定义名称,主要显示在日志记录和JMX管理控制台中,以标识池和池配置。 默认值:自动生成
+ pool-name: custom-hikari
+ #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
+ max-lifetime: 1800000
+ # 数据库连接超时时间,默认30秒,即30000
+ connection-timeout: 30000
+ # 连接测试sql 这个地方需要根据数据库方言差异而配置 例如 oracle 就应该写成 select 1 from dual
+ connection-test-query: SELECT 1
+
+# mybatis 相关配置
+mybatis:
+ # 指定 sql xml 文件的位置
+ mapper-locations: classpath*:mappers/*.xml
+ configuration:
+ # 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。
+ # oracle数据库建议配置为JdbcType.NULL, 默认是Other
+ jdbc-type-for-null: 'null'
+ # 是否打印sql语句 调试的时候可以开启
+ log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+```
+
+#### 2.2 xml方式的sql语句
+
+新建 ProgrammerMapper.java 和 programmerMapper.xml,及其测试类
+
+```java
+@Mapper
+public interface ProgrammerMapper {
+
+ void save(Programmer programmer);
+
+ Programmer selectById(int id);
+
+ int modify(Programmer programmer);
+
+ void delete(int id);
+}
+```
+
+```xml
+
+
+
+
+
+ insert into programmer (name, age, salary, birthday) VALUES (#{name}, #{age}, #{salary}, #{birthday})
+
+
+
+
+
+ update programmer set name=#{name},age=#{age},salary=#{salary},birthday=#{birthday} where id=#{id}
+
+
+
+ delete from programmer where id = #{id}
+
+
+
+```
+
+测试类
+
+```java
+/***
+ * @description: xml Sql测试类
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MybatisXmlTest {
+
+ @Autowired
+ private ProgrammerMapper mapper;
+
+ @Test
+ public void save() {
+ mapper.save(new Programmer("xiaominng", 12, 3467.34f, new Date()));
+ mapper.save(new Programmer("xiaominng", 12, 3467.34f, new Date()));
+ }
+
+ @Test
+ public void modify() {
+ mapper.modify(new Programmer(1, "xiaohong", 112, 347.34f, new Date()));
+ }
+
+ @Test
+ public void selectByCondition() {
+ Programmer programmers = mapper.selectById(1);
+ System.out.println(programmers);
+ }
+
+ @Test
+ public void delete() {
+ mapper.delete(2);
+ Programmer programmers = mapper.selectById(2);
+ Assert.assertNull(programmers);
+ }
+}
+```
+
+#### 2.3 注解方式的sql语句
+
+```java
+@Mapper
+public interface ProgrammerDao {
+
+ @Insert("insert into programmer (name, age, salary, birthday) VALUES (#{name}, #{age}, #{salary}, #{birthday})")
+ void save(Programmer programmer);
+
+ @Select("select * from programmer where name = #{id}")
+ Programmer selectById(int id);
+
+ @Update("update programmer set name=#{name},age=#{age},salary=#{salary},birthday=#{birthday} where id=#{id}")
+ int modify(Programmer programmer);
+
+ @Delete(" delete from programmer where id = #{id}")
+ void delete(int id);
+}
+```
+
+测试类
+
+```java
+/***
+ * @description: 注解Sql测试类
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class MybatisAnnotationTest {
+
+ @Autowired
+ private ProgrammerDao programmerDao;
+
+ @Test
+ public void save() {
+ programmerDao.save(new Programmer("xiaominng", 12, 3467.34f, new Date()));
+ programmerDao.save(new Programmer("xiaominng", 12, 3467.34f, new Date()));
+ }
+
+ @Test
+ public void modify() {
+ programmerDao.modify(new Programmer(1, "xiaolan", 21, 347.34f, new Date()));
+ }
+
+ @Test
+ public void selectByCondition() {
+ Programmer programmers = programmerDao.selectById(1);
+ System.out.println(programmers);
+ }
+
+ @Test
+ public void delete() {
+ programmerDao.delete(3);
+ Programmer programmers = programmerDao.selectById(3);
+ Assert.assertNull(programmers);
+ }
+}
+
+```
+
diff --git a/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerDao.java b/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerDao.java
index d8a35a3..61cd54e 100644
--- a/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerDao.java
+++ b/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerDao.java
@@ -3,8 +3,6 @@ package com.heibaiying.springboot.dao;
import com.heibaiying.springboot.bean.Programmer;
import org.apache.ibatis.annotations.*;
-import java.util.List;
-
/**
* @author : heibaiying
*/
diff --git a/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerMapper.java b/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerMapper.java
index 6c769c8..9797c00 100644
--- a/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerMapper.java
+++ b/spring-boot/spring-boot-mybatis/src/main/java/com/heibaiying/springboot/dao/ProgrammerMapper.java
@@ -3,8 +3,6 @@ package com.heibaiying.springboot.dao;
import com.heibaiying.springboot.bean.Programmer;
import org.apache.ibatis.annotations.Mapper;
-import java.util.List;
-
/**
* @author : heibaiying
*/
diff --git a/spring-boot/spring-boot-mybatis/src/main/resources/application.yml b/spring-boot/spring-boot-mybatis/src/main/resources/application.yml
index 06b8071..932dc69 100644
--- a/spring-boot/spring-boot-mybatis/src/main/resources/application.yml
+++ b/spring-boot/spring-boot-mybatis/src/main/resources/application.yml
@@ -1,55 +1,55 @@
spring:
datasource:
- url: jdbc:mysql://127.0.0.1:3306/mysql?useUnicode=true&characterEncoding=utf-8
+ url: jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
- # ԴĻ,¹ӳصþͲDZ
- # spring-boot 2 Ĭϲøܵ Hikari Ϊӳ ÿԲο https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby
+ # 如果不想配置对数据库连接池做特殊配置的话,以下关于连接池的配置就不是必须的
+ # spring-boot 2 默认采用高性能的 Hikari 作为连接池 更多配置可以参考 https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby
type: com.zaxxer.hikari.HikariDataSource
hikari:
- # άС
+ # 池中维护的最小空闲连接数
minimum-idle: 10
- # úʹе
+ # 池中最大连接数,包括闲置和使用中的连接
maximum-pool-size: 20
- # ԿƴӳطصӵĬԶύΪĬΪtrue
+ # 此属性控制从池返回的连接的默认自动提交行为。默认为true
auto-commit: true
- # ʱ
+ # 允许最长空闲时间
idle-timeout: 30000
- # ԱʾӳصûƣҪʾ־¼JMX̨УԱʶغͳá ĬֵԶ
+ # 此属性表示连接池的用户定义名称,主要显示在日志记录和JMX管理控制台中,以标识池和池配置。 默认值:自动生成
pool-name: custom-hikari
- #ԿƳӵڣֵ0ʾڣĬ180000030
+ #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
max-lifetime: 1800000
- # ݿӳʱʱ,Ĭ30룬30000
+ # 数据库连接超时时间,默认30秒,即30000
connection-timeout: 30000
- # Ӳsql طҪݿⷽԲ oracle Ӧд select 1 from dual
+ # 连接测试sql 这个地方需要根据数据库方言差异而配置 例如 oracle 就应该写成 select 1 from dual
connection-test-query: SELECT 1
-# mybatis
+# mybatis 相关配置
mybatis:
- # ָ sql xml ļλ
+ # 指定 sql xml 文件的位置
mapper-locations: classpath*:mappers/*.xml
configuration:
- # ûΪṩض JDBC ʱΪֵָ JDBC ͡
- # oracleݿ⽨ΪJdbcType.NULL, ĬOther
+ # 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。
+ # oracle数据库建议配置为JdbcType.NULL, 默认是Other
jdbc-type-for-null: 'null'
- # Ƿӡsql ԵʱԿ
+ # 是否打印sql语句 调试的时候可以开启
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-# ע 1
+# 注 1
# oracle
# driver="oracle.jdbc.driver.OracleDriver"
- # url="jdbc:oracle:thin:@localhost:1521:ݿ"
+ # url="jdbc:oracle:thin:@localhost:1521:数据库名"
# mysql
- # driver="com.mysql.jdbc.Driver"
- # url="jdbc:mysql://localhost/ݿ?[Ӳ]"
+ # driver="com.mysql.cj.jdbc.Driver"
+ # url="jdbc:mysql://localhost/数据库名?[后接参数]"
-# ע 2
- # mybatis ø˵Բοsettings http://www.mybatis.org/mybatis-3/zh/configuration.html
+# 注 2
+ # mybatis 配置更多说明可以参考settings http://www.mybatis.org/mybatis-3/zh/configuration.html
-# ע 3
- # spring boot 2.0 ĬϲHikari Ϊӳ githubַ https://github.com/brettwooldridge/HikariCP
\ No newline at end of file
+# 注 3
+# spring boot 2.0 默认采用Hikari 作为连接池 Hikari github地址 https://github.com/brettwooldridge/HikariCP
\ No newline at end of file
diff --git a/spring-boot/spring-boot-rabbitmq/README.md b/spring-boot/spring-boot-rabbitmq/README.md
new file mode 100644
index 0000000..942df79
--- /dev/null
+++ b/spring-boot/spring-boot-rabbitmq/README.md
@@ -0,0 +1,390 @@
+# spring boot 整合 rabbitmq
+
+## 一、 项目结构说明
+
+1.1 之前关于spring 整合 rabbitmq 我们采用的是单项目的方式,为了使得用例更具有实际意义,这里采用maven多模块的构建方式,在spring-boot-rabbitmq下构建三个子模块:
+
+1. rabbitmq-common 是公共模块,用于存放公共的接口、配置和bean,被rabbitmq-producer和rabbitmq-consumer在pom.xml中引用;
+2. rabbitmq-producer 是消息的生产者模块;
+3. rabbitmq-consumer是消息的消费者模块。
+
+1.2 关于rabbitmq安装、交换机、队列、死信队列等基本概念可以参考我的手记[《RabbitMQ实战指南》读书笔记](https://github.com/heibaiying/LearningNotes/blob/master/notes/%E4%B8%AD%E9%97%B4%E4%BB%B6/RabbitMQ/%E3%80%8ARabbitMQ%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0.md),里面有详细的配图说明。
+
+
+
+
+
+## 二、关键依赖
+
+在父工程的项目中统一导入依赖rabbitmq的starter(spring-boot-starter-amqp),父工程的pom.xml如下
+
+```xml
+
+
+
+ 4.0.0
+ pom
+
+
+ rabbitmq-consumer
+ rabbitmq-producer
+ rabbitmq-common
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.1.RELEASE
+
+
+ com.heibaiying
+ spring-boot-rabbitmq
+ 0.0.1-SNAPSHOT
+ spring-boot-rabbitmq
+ RabbitMQ project for Spring Boot
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+```
+
+
+
+## 三、公共模块(rabbitmq-common)
+
+- bean 下为公共的实体类。
+- constant 下为公共配置,用静态常量引用。(这里我使用静态常量是为了方便引用,实际中也可以按照情况,抽取为公共配置文件)
+
+
+
+```java
+package com.heibaiying.constant;
+
+/**
+ * @author : heibaiying
+ * @description : rabbit 公用配置信息
+ */
+public class RabbitInfo {
+
+ // queue 配置
+ public static final String QUEUE_NAME = "spring.boot.simple.queue";
+ public static final String QUEUE_DURABLE = "true";
+
+ // exchange 配置
+ public static final String EXCHANGE_NAME = "spring.boot.simple.exchange";
+ public static final String EXCHANGE_TYPE = "topic";
+
+ // routing key
+ public static final String ROUTING_KEY = "springboot.simple.*";
+}
+
+```
+
+
+
+## 四、服务消费者(rabbitmq-consumer)
+
+
+
+#### 4.1 消息消费者配置
+
+```yaml
+spring:
+ rabbitmq:
+ addresses: 127.0.0.1:5672
+ # RabbitMQ 默认的用户名和密码都是guest 而虚拟主机名称是 "/"
+ # 如果配置其他虚拟主机地址,需要预先用管控台或者图形界面创建 图形界面地址 http://主机地址:15672
+ username: guest
+ password: guest
+ virtual-host: /
+ listener:
+ simple:
+ # 为了保证信息能够被正确消费,建议签收模式设置为手工签收,并在代码中实现手工签收
+ acknowledge-mode: manual
+ # 侦听器调用者线程的最小数量
+ concurrency: 10
+ # 侦听器调用者线程的最大数量
+ max-concurrency: 50
+```
+
+#### 4.2 使用注解@RabbitListener和@RabbitHandler创建消息监听者
+
+1. 使用注解创建的交换机、队列、和绑定关系会在项目初始化的时候自动创建,但是不会重复创建;
+2. 这里我们创建两个消息监听器,分别演示消息是基本类型和消息是对象时的配置区别。
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 消息是对象的消费者
+ */
+
+@Component
+@Slf4j
+public class RabbitmqBeanConsumer {
+
+ @RabbitListener(bindings = @QueueBinding(
+ value = @Queue(value = RabbitBeanInfo.QUEUE_NAME, durable = RabbitBeanInfo.QUEUE_DURABLE),
+ exchange = @Exchange(value = RabbitBeanInfo.EXCHANGE_NAME, type = RabbitBeanInfo.EXCHANGE_TYPE),
+ key = RabbitBeanInfo.ROUTING_KEY)
+ )
+ @RabbitHandler
+ public void onMessage(@Payload Programmer programmer, @Headers Map headers, Channel channel) throws Exception {
+ log.info("programmer:{} ", programmer);
+ Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
+ channel.basicAck(deliveryTag, false);
+ }
+}
+```
+
+```java
+@Component
+@Slf4j
+public class RabbitmqConsumer {
+
+ @RabbitListener(bindings = @QueueBinding(
+ value = @Queue(value = RabbitInfo.QUEUE_NAME, durable = RabbitInfo.QUEUE_DURABLE),
+ exchange = @Exchange(value = RabbitInfo.EXCHANGE_NAME, type = RabbitInfo.EXCHANGE_TYPE),
+ key = RabbitInfo.ROUTING_KEY)
+ )
+ @RabbitHandler
+ public void onMessage(Message message, Channel channel) throws Exception {
+ MessageHeaders headers = message.getHeaders();
+ // 获取消息头信息和消息体
+ log.info("msgInfo:{} ; payload:{} ", headers.get("msgInfo"), message.getPayload());
+ // DELIVERY_TAG 代表 RabbitMQ 向该Channel投递的这条消息的唯一标识ID,是一个单调递增的正整数
+ Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
+ // 第二个参数代表是否一次签收多条,当该参数为 true 时,则可以一次性确认 DELIVERY_TAG 小于等于传入值的所有消息
+ channel.basicAck(deliveryTag, false);
+ }
+
+}
+```
+
+
+
+## 五、 消息生产者(rabbitmq-producer)
+
+
+
+#### 5.1 消息生产者配置
+
+```yaml
+spring:
+ rabbitmq:
+ addresses: 127.0.0.1:5672
+ # RabbitMQ 默认的用户名和密码都是guest 而虚拟主机名称是 "/"
+ # 如果配置其他虚拟主机地址,需要预先用管控台或者图形界面创建 图形界面地址 http://主机地址:15672
+ username: guest
+ password: guest
+ virtual-host: /
+ # 是否启用发布者确认 具体确认回调实现见代码
+ publisher-confirms: true
+ # 是否启用发布者返回 具体返回回调实现见代码
+ publisher-returns: true
+ # 是否启用强制消息 保证消息的有效监听
+ template.mandatory: true
+
+server:
+ port: 8090
+```
+
+#### 5.2 创建消息生产者
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 消息生产者
+ */
+@Component
+@Slf4j
+public class RabbitmqProducer {
+
+ @Autowired
+ private RabbitTemplate rabbitTemplate;
+
+ public void sendSimpleMessage(Map headers, Object message,
+ String messageId, String exchangeName, String key) {
+ // 自定义消息头
+ MessageHeaders messageHeaders = new MessageHeaders(headers);
+ // 创建消息
+ Message
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
javax.servlet
javax.servlet-api
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
diff --git a/spring-boot/spring-boot-servlet/src/main/java/com/heibaiying/springbootservlet/servlet/CustomServletAnnation.java b/spring-boot/spring-boot-servlet/src/main/java/com/heibaiying/springbootservlet/servlet/CustomServletAnnotation.java
similarity index 92%
rename from spring-boot/spring-boot-servlet/src/main/java/com/heibaiying/springbootservlet/servlet/CustomServletAnnation.java
rename to spring-boot/spring-boot-servlet/src/main/java/com/heibaiying/springbootservlet/servlet/CustomServletAnnotation.java
index bd4d69e..de6cf62 100644
--- a/spring-boot/spring-boot-servlet/src/main/java/com/heibaiying/springbootservlet/servlet/CustomServletAnnation.java
+++ b/spring-boot/spring-boot-servlet/src/main/java/com/heibaiying/springbootservlet/servlet/CustomServletAnnotation.java
@@ -12,7 +12,7 @@ import java.io.IOException;
* @description : 自定义servlet
*/
@WebServlet(urlPatterns = "/servletAnn")
-public class CustomServletAnnation extends HttpServlet {
+public class CustomServletAnnotation extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
diff --git a/spring-boot/spring-boot-tomcat/README.md b/spring-boot/spring-boot-tomcat/README.md
new file mode 100644
index 0000000..ba6597d
--- /dev/null
+++ b/spring-boot/spring-boot-tomcat/README.md
@@ -0,0 +1,101 @@
+# spring boot 整合 tomcat
+
+## 一、说明
+
+#### 1.1 项目结构说明
+
+spring boot 整合 tomcat 后支持jsp 的使用(内置容器默认是不支持jsp),所以项目整合后采用jspController 跳转到show.jsp测试整合是否成功。
+
+
+
+#### 1.2 项目主要依赖
+
+```xml
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+ provided
+
+```
+
+## 二、整合 tomcat
+
+#### 2.1 修改启动类,继承自SpringBootServletInitializer,并覆盖重写其中configure方法
+
+```java
+/**
+ * 如果用外置tomcat,启动报错java.lang.NoClassDefFoundError: javax/el/ELManager
+ * 是因为tomcat 7.0 el-api包中没有ELManager类 , 切换tomcat 为8.0 以上版本即可
+ */
+@SpringBootApplication
+public class SpringBootTomcatApplication extends SpringBootServletInitializer {
+
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ //传入SpringBoot应用的主程序
+ return application.sources(SpringBootTomcatApplication.class);
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootTomcatApplication.class, args);
+ }
+
+}
+```
+
+#### 2.2 在application.yml 中指定访问视图文件的前缀和后缀
+
+```yml
+spring:
+ mvc:
+ view:
+ prefix: /WEB-INF/jsp/
+ suffix: .jsp
+```
+
+#### 2.3 新建controller和show.jsp 测试整合是否成功
+
+```java
+@Controller
+@RequestMapping("index")
+public class JspController {
+
+ @RequestMapping
+ public String jsp(Model model){
+ Programmer programmer = new Programmer("heibai", 21, 1298.31f, LocalDate.now());
+ model.addAttribute("programmer",programmer);
+ return "show";
+ }
+}
+```
+
+```jsp
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+ programmer
+
+
+
+
+ - 姓名: ${programmer.name}
+ - 年龄: ${programmer.age}
+
+
+
+```
+
diff --git a/spring-boot/spring-boot-websocket/README.md b/spring-boot/spring-boot-websocket/README.md
new file mode 100644
index 0000000..6682892
--- /dev/null
+++ b/spring-boot/spring-boot-websocket/README.md
@@ -0,0 +1,183 @@
+# spring boot websocket
+
+## 一、说明
+
+### 1.1 项目结构说明
+
+1. 项目模拟一个简单的群聊功能,为区分不同的聊天客户端,登录时候将临时用户名存储在session当中;
+2. 关于websocket的主要配置在websocket文件夹下;
+3. 模板引擎采用freemaker;
+4. 项目以web的方式构建。
+
+
+
+
+
+### 1.2 主要依赖
+
+```xml
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+ org.springframework.boot
+ spring-boot-starter-freemarker
+
+```
+
+
+
+## 二、spring boot websocket
+
+#### 2.1 创建消息处理类ChatSocket,使用@ServerEndpoint声明websocket服务
+
+```java
+@ServerEndpoint(value = "/socket/{username}")
+@Component
+public class ChatSocket {
+
+ /**
+ * 建立连接时候触发
+ */
+ @OnOpen
+ public void onOpen(Session session, @PathParam("username") String username) {
+ // 这个方法是线程不安全的
+ Constant.nameAndSession.putIfAbsent(username, session);
+ }
+
+
+ /**
+ * 关闭连接时候触发
+ */
+ @OnClose
+ public void onClose(Session session, @PathParam("username") String username) {
+ Constant.nameAndSession.remove(username);
+ }
+
+ /**
+ * 处理消息
+ */
+ @OnMessage
+ public void onMessage(Session session, String message, @PathParam("username") String username) throws UnsupportedEncodingException {
+ // 防止中文乱码
+ String msg = URLDecoder.decode(message, "utf-8");
+ // 简单模拟群发消息
+ Constant.nameAndSession.forEach((s, webSocketSession)
+ -> {
+ try {
+ webSocketSession.getBasicRemote().sendText(username + " : " + msg);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+}
+
+```
+
+#### 2.2 配置ServerEndpointExporter,ServerEndpointExporter会在运行时候自动注册我们用@ServerEndpoint声明的websocket服务。
+
+```java
+@Configuration
+public class WebSocketConfig {
+
+ /***
+ * 检测{@link javax.websocket.server.ServerEndpointConfig}和{@link ServerEndpoint} 类型的bean,
+ * 并在运行时使用标准Java WebSocket时注册。
+ * 我们在{@link com.heibaiying.springboot.websocket.WebSocketConfig}中就是使用@ServerEndpoint去声明websocket服务
+ */
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
+}
+```
+
+#### 2.3 前端websocket的实现
+
+```jsp
+
+
+
+ ${Session["username"]}您好!欢迎进入群聊大厅!
+
+
+ ${Session["username"]}您好!欢迎进入群聊大厅!
+
+
+
+
+
+
+
+
+
+```
+
+#### 2.4 简单登录的实现
+
+```java
+
+
+
+ Title
+
+
+
+
+
+```
+
+```java
+/**
+ * @description : 简单登录
+ */
+@Controller
+public class LoginController {
+
+ @PostMapping("login")
+ public String login(String username, HttpSession session) {
+ session.setAttribute(Constant.USER_NAME, username);
+ return "chat";
+ }
+
+ @GetMapping
+ public String index() {
+ return "index";
+ }
+}
+```
+
diff --git a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/constant/Constant.java b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/constant/Constant.java
index 4a3b0a8..529eb1d 100644
--- a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/constant/Constant.java
+++ b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/constant/Constant.java
@@ -4,11 +4,7 @@ import javax.websocket.Session;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-/**
- * @author : 罗祥
- * @description :
- * @date :create in 2018/12/27
- */
+
public interface Constant {
String USER_NAME="username";
diff --git a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/controller/LoginController.java b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/controller/LoginController.java
index 582497f..868311f 100644
--- a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/controller/LoginController.java
+++ b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/controller/LoginController.java
@@ -8,9 +8,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpSession;
/**
- * @author : 罗祥
* @description : 简单登录
- * @date :create in 2018/12/27
*/
@Controller
public class LoginController {
diff --git a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/ChatSocket.java b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/ChatSocket.java
index 4080827..40474bf 100644
--- a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/ChatSocket.java
+++ b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/ChatSocket.java
@@ -21,20 +21,28 @@ import java.net.URLDecoder;
@Component
public class ChatSocket {
-
- @OnOpen //建立连接时候触发
+ /**
+ * 建立连接时候触发
+ */
+ @OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
// 这个方法是线程不安全的
Constant.nameAndSession.putIfAbsent(username, session);
}
- @OnClose //关闭连接时候触发
+ /**
+ * 关闭连接时候触发
+ */
+ @OnClose
public void onClose(Session session, @PathParam("username") String username) {
Constant.nameAndSession.remove(username);
}
- @OnMessage //处理消息
+ /**
+ * 处理消息
+ */
+ @OnMessage
public void onMessage(Session session, String message, @PathParam("username") String username) throws UnsupportedEncodingException {
// 防止中文乱码
String msg = URLDecoder.decode(message, "utf-8");
diff --git a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/WebSocketConfig.java b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/WebSocketConfig.java
index 4bba5dd..4e97831 100644
--- a/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/WebSocketConfig.java
+++ b/spring-boot/spring-boot-websocket/src/main/java/com/heibaiying/springboot/websocket/WebSocketConfig.java
@@ -4,12 +4,19 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+import javax.websocket.server.ServerEndpoint;
+
/**
* @author : heibaiying
*/
@Configuration
public class WebSocketConfig {
+ /***
+ * 检测{@link javax.websocket.server.ServerEndpointConfig}和{@link ServerEndpoint} 类型的bean,
+ * 并在运行时使用标准Java WebSocket时注册。
+ * 我们在{@link com.heibaiying.springboot.websocket.WebSocketConfig}中就是使用@ServerEndpoint去声明websocket服务
+ */
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
diff --git a/spring-boot/spring-boot-yml-profile/README.md b/spring-boot/spring-boot-yml-profile/README.md
new file mode 100644
index 0000000..937d48d
--- /dev/null
+++ b/spring-boot/spring-boot-yml-profile/README.md
@@ -0,0 +1,247 @@
+# spring-boot 基础
+
+## 一、说明
+
+#### 1.1 项目结构说明
+
+1. 本项目搭建一个简单的hello spring 的 web工程,简单说明spring-boot 的开箱即用的特性;
+2. 模板引擎采用freemaker 和 thymeleaf 作为示例,分别对应模板文件makershow.ftl 和 leafShow.html;
+3. spring boot 2.x 默认是不支持jsp的,需要额外的配置,关于使用jsp的整合可以参考spring-boot-jsp项目。
+
+
+
+#### 1.2 项目依赖
+
+导入相关的starter(启动器)
+
+```xml
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.1.RELEASE
+
+
+ com.heibaiying
+ spring-boot-base
+ 0.0.1-SNAPSHOT
+ spring-boot-base
+ Demo project for Spring Boot
+
+
+ 1.8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-freemarker
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+```
+
+1. spring boot 项目默认继承自spring-boot-starter-parent,而spring-boot-starter-parent继承自spring-boot-dependencies, spring-boot-dependencies中定义了关于spring boot 依赖的各种jar包的版本,是spring boot 的版本管理中心。
+
+
+
+2. 关于spring boot 2.x官方支持的所有starter 可以参见官方文档 [Table 13.1. Spring Boot application starters](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#using-boot-starter)
+
+
+
+## 二、spring boot 主启动类
+
+ 如果采用IDEA 或者 Spring Tool Suite (STS) 等开发工具创建的spring boot 工程,会默认创建启动类,如果没有创建,需要手动创建启动类
+
+```java
+package com.heibaiying.springbootbase;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootBaseApplication {
+
+ // 启动类默认开启包扫描,扫描与主程序所在包及其子包,对于本工程而言 默认扫描 com.heibaiying.springbootbase
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootBaseApplication.class, args);
+ }
+
+}
+```
+
+@SpringBootApplication 注解是一个复合注解,里面包含了@ComponentScan注解,默认开启包扫描,扫描与主程序所在包及其子包,对于本工程而言 默认扫描 com.heibaiying.springbootbase
+
+```java
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@SpringBootConfiguration
+@EnableAutoConfiguration
+@ComponentScan(excludeFilters = {
+ @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
+ @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
+public @interface SpringBootApplication {
+ ...
+}
+```
+
+
+
+## 三、开箱即用的web工程
+
+在springbootBaseApplication.java 的同级目录创建controller文件夹,并在其中创建RestfulController.java,启动项目访问localhost:8080/restful/programmers 即可看到项目搭建成功。
+
+```java
+/**
+ * @author : heibaiying
+ * @description : restful 控制器
+ */
+@RestController
+@RequestMapping("restful")
+public class RestfulController {
+
+ @GetMapping("programmers")
+ private List getProgrammers() {
+ List programmers = new ArrayList<>();
+ programmers.add(new Programmer("xiaoming", 12, 100000.00f, LocalDate.of(2019, Month.AUGUST, 2)));
+ programmers.add(new Programmer("xiaohong", 23, 900000.00f, LocalDate.of(2013, Month.FEBRUARY, 2)));
+ return programmers;
+ }
+}
+```
+
+这里之所以能够开箱即用,是因为我们在项目中导入spring-boot-starter-web启动器,而@SpringBootApplication 复合注解中默认开启了@EnableAutoConfiguration注解允许开启自动化配置,spring在检查导入starter-web的依赖后就会开启web的自动化配置。
+
+
+
+## 四、模板引擎
+
+这里我们在一个项目中同时导入了freemaker 和 thymeleaf的starter(虽然并不推荐,但是在同一个项目中是可以混用这两种模板引擎的)。
+
+#### 4.1 freemarker
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 跳转渲染模板引擎 默认模板的存放位置为classpath:templates
+ */
+@Controller
+@RequestMapping("freemarker")
+public class FreeMarkerController {
+
+ @RequestMapping("show")
+ private String programmerShow(ModelMap modelMap){
+ List programmerList=new ArrayList<>();
+ programmerList.add(new Programmer("xiaoming",12,100000.00f,LocalDate.of(2019,Month.AUGUST,2)));
+ programmerList.add(new Programmer("xiaohong",23,900000.00f,LocalDate.of(2013,Month.FEBRUARY,2)));
+ modelMap.addAttribute("programmers",programmerList);
+ return "markerShow";
+ }
+}
+
+```
+
+```html
+
+
+
+
+ freemarker模板引擎
+
+
+
+ <#list programmers as programmer>
+ - 姓名: ${programmer.name} 年龄: ${programmer.age}
+ #list>
+
+
+
+```
+
+#### 4.2 thymeleaf
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 跳转渲染模板引擎 默认模板的存放位置为classpath:templates
+ */
+@Controller
+@RequestMapping("thymeleaf")
+public class ThymeleafController {
+
+ @RequestMapping("show")
+ private String programmerShow(ModelMap modelMap) {
+ List programmerList = new ArrayList<>();
+ programmerList.add(new Programmer("xiaoming", 12, 100000.00f, LocalDate.of(2019, Month.AUGUST, 2)));
+ programmerList.add(new Programmer("xiaohong", 23, 900000.00f, LocalDate.of(2013, Month.FEBRUARY, 2)));
+ modelMap.addAttribute("programmers", programmerList);
+ return "leafShow";
+ }
+}
+
+```
+
+```html
+
+
+
+
+ thymeleaf模板引擎
+
+
+
+
+
+```
+
+#### 4.3 文档说明
+
+freemarker:提供了完善的中文文档,地址 http://freemarker.foofun.cn/
+
+thymeleaf:官方英文文档地址:[thymeleaf 3.0.11RELEASE](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.pdf)
+
+注:我在本仓库中也上传了一份[thymeleaf中文文档(gangzi828(刘明刚 译)](https://github.com/heibaiying/spring-samples-for-all/tree/master/referenced%20documents),翻译的版本为3.0.5RELEASE
\ No newline at end of file
diff --git a/spring-boot/spring-boot-yml-profile/src/main/resources/application.yml b/spring-boot/spring-boot-yml-profile/src/main/resources/application.yml
index 0b9e370..7c5541a 100644
--- a/spring-boot/spring-boot-yml-profile/src/main/resources/application.yml
+++ b/spring-boot/spring-boot-yml-profile/src/main/resources/application.yml
@@ -1,10 +1,10 @@
-# ָ
+# 指定启动的配置
spring:
profiles:
active: dev
-# õIJȼ devûage,Իõģproddev,ᰴվȷȣʹdevе
-# õȼԲ鿴ĿREADME.md
+# 配置的补充与优先级 在dev中没有配置age,所以会采用主配置的,在prod中配置dev,会按照精确优先,使用dev中的配置
+# 更多配置的优先级可以查看项目的README.md
programmer:
age: 999
diff --git a/spring/spring-dubbo-annotation/README.md b/spring/spring-dubbo-annotation/README.md
index bf9d8fb..75b8e75 100644
--- a/spring/spring-dubbo-annotation/README.md
+++ b/spring/spring-dubbo-annotation/README.md
@@ -16,7 +16,7 @@
## 二、项目依赖
-**在父工程的项目中同一导入依赖dubbo依赖的的jar包**
+**在父工程的项目中统一导入依赖dubbo依赖的的jar包**
这里需要注意的是ZooKeeper 3.5.x 和 ZooKeeper 3.4.x 是存在不兼容的情况 详见官网解释[ZooKeeper Version Compatibility](https://curator.apache.org/zk-compatibility.html), zookeeper 3.5 目前是beta版本,所以zookeeper 我选择的版本是 zookeeper-3.4.9 作为服务端。但默认情况下 curator-framework自动引用的最新的3.5的版本客户端,会出现 KeeperException$UnimplementedException 异常
diff --git a/spring/spring-dubbo/README.md b/spring/spring-dubbo/README.md
index 52b799b..bc4bc80 100644
--- a/spring/spring-dubbo/README.md
+++ b/spring/spring-dubbo/README.md
@@ -16,7 +16,7 @@
## 二、项目依赖
-**在父工程的项目中同一导入依赖dubbo依赖的的jar包**
+**在父工程的项目中统一导入依赖dubbo依赖的的jar包**
这里需要注意的是ZooKeeper 3.5.x 和 ZooKeeper 3.4.x 是存在不兼容的情况 详见官网解释[ZooKeeper Version Compatibility](https://curator.apache.org/zk-compatibility.html), zookeeper 3.5 目前是beta版本,所以zookeeper 我选择的版本是 zookeeper-3.4.9 作为服务端。但默认情况下 curator-framework自动引用的最新的3.5的版本客户端,会出现 KeeperException$UnimplementedException 异常
diff --git a/spring/spring-websocket-annotation/README.md b/spring/spring-websocket-annotation/README.md
index 1306854..c235a81 100644
--- a/spring/spring-websocket-annotation/README.md
+++ b/spring/spring-websocket-annotation/README.md
@@ -4,7 +4,7 @@
### 1.1 项目结构说明
-1. 项目模拟一个简单的群聊功能,为区分不同的聊天客户端,登录时候用临时用户名作为session的id;
+1. 项目模拟一个简单的群聊功能,为区分不同的聊天客户端,登录时候将临时用户名存储在session当中;
2. webconfig 包是基础注解的方式配置web,在spring-base-annotation项目中已经讲解过每个类作用;
3. CustomHander为消息的自定义处理器;
4. CustomHandershakerInterceptor为自定义的 websocket 的握手拦截器;
diff --git a/spring/spring-websocket/README.md b/spring/spring-websocket/README.md
index 8f82b01..7752223 100644
--- a/spring/spring-websocket/README.md
+++ b/spring/spring-websocket/README.md
@@ -4,7 +4,7 @@
### 1.1 项目结构说明
-1. 项目模拟一个简单的群聊功能,为区分不同的聊天客户端,登录时候用临时用户名作为session的id;
+1. 项目模拟一个简单的群聊功能,为区分不同的聊天客户端,登录时候将临时用户名存储在session当中;
2. CustomHander为消息的自定义处理器;
3. CustomHandershakerInterceptor为自定义的 websocket 的握手拦截器;
4. 项目以web的方式构建。