diff --git a/chapter-2-spring-boot-quick-start/pom.xml b/chapter-2-spring-boot-quick-start/pom.xml
new file mode 100644
index 0000000..f86c3de
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/pom.xml
@@ -0,0 +1,84 @@
+
+
+ 4.0.0
+
+ spring.boot.core
+ chapter-2-spring-boot-quick-start
+ 0.0.1-SNAPSHOT
+ jar
+
+ chapter-2-spring-boot-quick-start
+ 第二章快速入门案例
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.M4
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 1.5.1.RELEASE
+
+
+
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/libs-milestone
+
+ false
+
+
+
+
+
diff --git a/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/QuickStartApplication.java b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/QuickStartApplication.java
new file mode 100644
index 0000000..001fea7
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/QuickStartApplication.java
@@ -0,0 +1,12 @@
+package spring.boot.core;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class QuickStartApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(QuickStartApplication.class, args);
+ }
+}
diff --git a/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/domain/User.java b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/domain/User.java
new file mode 100644
index 0000000..5291ee2
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/domain/User.java
@@ -0,0 +1,79 @@
+package spring.boot.core.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+/**
+ * 用户实体类
+ *
+ * Created by bysocket on 21/07/2017.
+ */
+@Entity
+public class User implements Serializable {
+
+ /**
+ * 编号
+ */
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 年龄
+ */
+ private Integer age;
+
+ /**
+ * 出生时间
+ */
+ private String birthday;
+
+ 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 Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getBirthday() {
+ return birthday;
+ }
+
+ public void setBirthday(String birthday) {
+ this.birthday = birthday;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ ", age=" + age +
+ ", birthday=" + birthday +
+ '}';
+ }
+}
diff --git a/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/domain/UserRepository.java b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/domain/UserRepository.java
new file mode 100644
index 0000000..6e40f4a
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/domain/UserRepository.java
@@ -0,0 +1,12 @@
+package spring.boot.core.domain;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * 用户持久层操作接口
+ *
+ * Created by bysocket on 21/07/2017.
+ */
+public interface UserRepository extends JpaRepository {
+
+}
diff --git a/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/service/UserService.java b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/service/UserService.java
new file mode 100644
index 0000000..8111e6f
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/service/UserService.java
@@ -0,0 +1,24 @@
+package spring.boot.core.service;
+
+
+import spring.boot.core.domain.User;
+
+import java.util.List;
+
+/**
+ * User 业务层接口
+ *
+ * Created by bysocket on 24/07/2017.
+ */
+public interface UserService {
+
+ List findAll();
+
+ User insertByUser(User user);
+
+ User update(User user);
+
+ User delete(Long id);
+
+ User findById(Long id);
+}
diff --git a/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/service/impl/UserServiceImpl.java b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..9da3385
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/service/impl/UserServiceImpl.java
@@ -0,0 +1,57 @@
+package spring.boot.core.service.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import spring.boot.core.domain.User;
+import spring.boot.core.domain.UserRepository;
+import spring.boot.core.service.UserService;
+
+import java.util.List;
+
+/**
+ * User 业务层实现
+ *
+ * Created by bysocket on 24/07/2017.
+ */
+@Service
+public class UserServiceImpl implements UserService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
+
+ @Autowired
+ UserRepository userRepository;
+
+ @Override
+ public List findAll() {
+ return userRepository.findAll();
+ }
+
+ @Override
+ public User insertByUser(User user) {
+ LOGGER.info("新增用户:" + user.toString());
+ return userRepository.save(user);
+ }
+
+ @Override
+ public User update(User user) {
+ LOGGER.info("更新用户:" + user.toString());
+ return userRepository.save(user);
+ }
+
+ @Override
+ public User delete(Long id) {
+ User user = userRepository.findById(id).get();
+ userRepository.delete(user);
+
+ LOGGER.info("删除用户:" + user.toString());
+ return user;
+ }
+
+ @Override
+ public User findById(Long id) {
+ LOGGER.info("获取用户 ID :" + id);
+ return userRepository.findById(id).get();
+ }
+}
diff --git a/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/web/UserController.java b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/web/UserController.java
new file mode 100644
index 0000000..e4b409b
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/java/spring/boot/core/web/UserController.java
@@ -0,0 +1,90 @@
+package spring.boot.core.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import spring.boot.core.domain.User;
+import spring.boot.core.service.UserService;
+
+/**
+ * 用户控制层
+ *
+ * Created by bysocket on 24/07/2017.
+ */
+@Controller
+@RequestMapping(value = "/users") // 通过这里配置使下面的映射都在 /users
+public class UserController {
+
+ @Autowired
+ UserService userService; // 用户服务层
+
+ /**
+ * 获取用户列表
+ * 处理 "/users" 的 GET 请求,用来获取用户列表
+ * 通过 @RequestParam 传递参数,进一步实现条件查询或者分页查询
+ */
+ @RequestMapping(method = RequestMethod.GET)
+ public String getUserList(ModelMap map) {
+ map.addAttribute("userList", userService.findAll());
+ return "userList";
+ }
+
+ /**
+ * 显示创建用户表单
+ *
+ */
+ @RequestMapping(value = "/create", method = RequestMethod.GET)
+ public String createUserForm(ModelMap map) {
+ map.addAttribute("user", new User());
+ map.addAttribute("action", "create");
+ return "userForm";
+ }
+
+ /**
+ * 创建用户
+ * 处理 "/users" 的 POST 请求,用来获取用户列表
+ * 通过 @ModelAttribute 绑定参数,也通过 @RequestParam 从页面中传递参数
+ */
+ @RequestMapping(value = "/create", method = RequestMethod.POST)
+ public String postUser(@ModelAttribute User user) {
+ userService.insertByUser(user);
+ return "redirect:/users/";
+ }
+
+ /**
+ * 显示需要更新用户表单
+ * 处理 "/users/{id}" 的 GET 请求,通过 URL 中的 id 值获取 User 信息
+ * URL 中的 id ,通过 @PathVariable 绑定参数
+ */
+ @RequestMapping(value = "/update/{id}", method = RequestMethod.GET)
+ public String getUser(@PathVariable Long id, ModelMap map) {
+ map.addAttribute("user", userService.findById(id));
+ map.addAttribute("action", "update");
+ return "userForm";
+ }
+
+ /**
+ * 处理 "/users/{id}" 的 PUT 请求,用来更新 User 信息
+ *
+ */
+ @RequestMapping(value = "/update", method = RequestMethod.POST)
+ public String putUser(@ModelAttribute User user) {
+ userService.update(user);
+ return "redirect:/users/";
+ }
+
+ /**
+ * 处理 "/users/{id}" 的 GET 请求,用来删除 User 信息
+ */
+ @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
+ public String deleteUser(@PathVariable Long id) {
+
+ userService.delete(id);
+ return "redirect:/users/";
+ }
+
+}
\ No newline at end of file
diff --git a/chapter-2-spring-boot-quick-start/src/main/resources/application.properties b/chapter-2-spring-boot-quick-start/src/main/resources/application.properties
new file mode 100644
index 0000000..51350c6
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+## 是否显示 SQL 语句
+spring.jpa.show-sql=true
\ No newline at end of file
diff --git a/chapter-2-spring-boot-quick-start/src/main/resources/static/css/default.css b/chapter-2-spring-boot-quick-start/src/main/resources/static/css/default.css
new file mode 100755
index 0000000..4da3051
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/resources/static/css/default.css
@@ -0,0 +1,2 @@
+/* contentDiv */
+.contentDiv {padding:20px 60px;}
\ No newline at end of file
diff --git a/chapter-2-spring-boot-quick-start/src/main/resources/static/images/favicon.ico b/chapter-2-spring-boot-quick-start/src/main/resources/static/images/favicon.ico
new file mode 100755
index 0000000..e5a2934
Binary files /dev/null and b/chapter-2-spring-boot-quick-start/src/main/resources/static/images/favicon.ico differ
diff --git a/chapter-2-spring-boot-quick-start/src/main/resources/templates/userForm.html b/chapter-2-spring-boot-quick-start/src/main/resources/templates/userForm.html
new file mode 100644
index 0000000..c6768ad
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/resources/templates/userForm.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+ 用户管理
+
+
+
+
+
+
《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chapter-2-spring-boot-quick-start/src/main/resources/templates/userList.html b/chapter-2-spring-boot-quick-start/src/main/resources/templates/userList.html
new file mode 100644
index 0000000..3d680f1
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/main/resources/templates/userList.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+ 用户列表
+
+
+
+
+
+
+
《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
+
+
+
+
+
+ | 用户编号 |
+ 名称 |
+ 年龄 |
+ 出生时间 |
+ 管理 |
+
+
+
+
+ |
+ |
+ |
+ |
+ 删除 |
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chapter-2-spring-boot-quick-start/src/test/java/spring/boot/core/QuickStartApplicationTests.java b/chapter-2-spring-boot-quick-start/src/test/java/spring/boot/core/QuickStartApplicationTests.java
new file mode 100644
index 0000000..ce75da4
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/test/java/spring/boot/core/QuickStartApplicationTests.java
@@ -0,0 +1,16 @@
+package spring.boot.core;
+
+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 QuickStartApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/chapter-2-spring-boot-quick-start/src/test/java/spring/boot/core/domain/UserRepositoryTests.java b/chapter-2-spring-boot-quick-start/src/test/java/spring/boot/core/domain/UserRepositoryTests.java
new file mode 100644
index 0000000..d65b35f
--- /dev/null
+++ b/chapter-2-spring-boot-quick-start/src/test/java/spring/boot/core/domain/UserRepositoryTests.java
@@ -0,0 +1,120 @@
+package spring.boot.core.domain;
+
+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
+ UserRepository userRepository;
+
+ /**
+ * 单元测试 - 新增用户
+ */
+ @Test
+ public void testSave() {
+ User user = new User();
+ user.setName("mumu");
+ user.setAge(2);
+// user.setBirthday(new Date());
+ user = userRepository.save(user);
+
+ // 验证新增用户
+ Assert.assertNotNull(user.getId());
+ }
+
+ /**
+ * 单元测试 - 删除用户
+ */
+ @Test
+ public void testDelete() {
+
+ // 新增两个用户数据
+ User mumu = new User();
+ mumu.setName("mumu");
+ mumu.setAge(2);
+// mumu.setBirthday(new Date());
+ userRepository.save(mumu);
+
+ User zizi = new User();
+ zizi.setName("zizi");
+ zizi.setAge(25);
+// zizi.setBirthday(new Date());
+ userRepository.save(zizi);
+
+ // 验证是否获取的用户列表大小是 2
+ Assert.assertEquals(2, userRepository.findAll().size());
+
+ // 删除用户
+ userRepository.delete(mumu);
+
+ // 验证是否获取的用户列表大小是 1
+ Assert.assertEquals(1, userRepository.findAll().size());
+ }
+
+ /**
+ * 单元测试 - 更新用户
+ */
+ @Test
+ public void testUpdate() {
+ User user = new User();
+ user.setName("mumu");
+ user.setAge(2);
+// user.setBirthday(new Date());
+ user = userRepository.save(user);
+
+ user.setName("zizi");
+ user = userRepository.save(user);
+
+ // 验证新增用户的编号是否为 1
+ Assert.assertNotNull(user.getId());
+ Assert.assertEquals("zizi", user.getName());
+ }
+
+ /**
+ * 单元测试 - 获取用户列表
+ */
+ @Test
+ public void testFindAll() {
+ // 新增两个用户数据
+ User mumu = new User();
+ mumu.setName("mumu");
+ mumu.setAge(2);
+// mumu.setBirthday(new Date());
+ userRepository.save(mumu);
+
+ User zizi = new User();
+ zizi.setName("zizi");
+ zizi.setAge(25);
+// zizi.setBirthday(new Date());
+ userRepository.save(zizi);
+
+ // 验证是否获取的用户列表大小是 2
+ Assert.assertEquals(2, userRepository.findAll().size());
+ }
+
+ /**
+ * 单元测试 - 获取单个用户
+ */
+ @Test
+ public void testFindById() {
+ // 新增用户
+ User mumu = new User();
+ mumu.setName("mumu");
+ mumu.setAge(2);
+// mumu.setBirthday(new Date());
+ userRepository.save(mumu);
+
+ // 验证是否获取的用户是否是插入的用户
+ User expected = userRepository.findById(1L).get();
+ Assert.assertEquals("mumu", expected.getName());
+ }
+
+
+}