diff --git a/19.Spring-Boot-Testing/pom.xml b/19.Spring-Boot-Testing/pom.xml
new file mode 100644
index 0000000..eb75399
--- /dev/null
+++ b/19.Spring-Boot-Testing/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+
+ demo.springboot
+ Spring-Boot-Testing
+ 0.0.1-SNAPSHOT
+ jar
+
+ test
+ Demo project for Spring Boot test
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.9.RELEASE
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.7
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.3.1
+
+
+
+ tk.mybatis
+ mapper-spring-boot-starter
+ 1.1.5
+
+
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+ 1.2.3
+
+
+
+ com.oracle
+ ojdbc6
+ 6.0
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ 1.1.6
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/TestApplication.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/TestApplication.java
new file mode 100644
index 0000000..a2b29ae
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/TestApplication.java
@@ -0,0 +1,16 @@
+package demo.springboot.test;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@SpringBootApplication
+@EnableTransactionManagement
+@MapperScan("demo.springboot.test.mapper")
+public class TestApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TestApplication.class, args);
+ }
+}
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/config/MyMapper.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/config/MyMapper.java
new file mode 100644
index 0000000..8af8b4d
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/config/MyMapper.java
@@ -0,0 +1,8 @@
+package demo.springboot.test.config;
+
+import tk.mybatis.mapper.common.Mapper;
+import tk.mybatis.mapper.common.MySqlMapper;
+
+public interface MyMapper extends Mapper, MySqlMapper {
+
+}
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/controller/UserController.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/controller/UserController.java
new file mode 100644
index 0000000..5140961
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/controller/UserController.java
@@ -0,0 +1,28 @@
+package demo.springboot.test.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import demo.springboot.test.domain.User;
+import demo.springboot.test.service.UserService;
+
+@RestController
+public class UserController {
+
+ @Autowired
+ UserService userService;
+
+ @GetMapping("user/{userName}")
+ public User getUserByName(@PathVariable(value = "userName") String userName) {
+ return this.userService.findByName(userName);
+ }
+
+ @PostMapping("user/save")
+ public void saveUser(@RequestBody User user) {
+ this.userService.saveUser(user);
+ }
+}
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/domain/User.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/domain/User.java
new file mode 100644
index 0000000..52c36c5
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/domain/User.java
@@ -0,0 +1,96 @@
+package demo.springboot.test.domain;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Table(name = "T_USER")
+public class User {
+ @Id
+ @Column(name = "USER_ID")
+ private Long id;
+
+ @Column(name = "USERNAME")
+ private String username;
+
+ @Column(name = "PASSWORD")
+ private String passwd;
+
+ @Column(name = "CRATE_TIME")
+ private Date createTime;
+
+ @Column(name = "STATUS")
+ private String status;
+
+ /**
+ * @return ID
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ */
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ /**
+ * @return USERNAME
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * @param username
+ */
+ public void setUsername(String username) {
+ this.username = username == null ? null : username.trim();
+ }
+
+ /**
+ * @return PASSWD
+ */
+ public String getPasswd() {
+ return passwd;
+ }
+
+ /**
+ * @param passwd
+ */
+ public void setPasswd(String passwd) {
+ this.passwd = passwd == null ? null : passwd.trim();
+ }
+
+ /**
+ * @return CREATE_TIME
+ */
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ /**
+ * @param createTime
+ */
+ public void setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ }
+
+ /**
+ * @return STATUS
+ */
+ public String getStatus() {
+ return status;
+ }
+
+ /**
+ * @param status
+ */
+ public void setStatus(String status) {
+ this.status = status == null ? null : status.trim();
+ }
+}
\ No newline at end of file
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/mapper/SeqenceMapper.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/mapper/SeqenceMapper.java
new file mode 100644
index 0000000..63d3181
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/mapper/SeqenceMapper.java
@@ -0,0 +1,9 @@
+package demo.springboot.test.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+public interface SeqenceMapper {
+ @Select("select ${seqName}.nextval from dual")
+ Long getSequence(@Param("seqName") String seqName);
+}
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/mapper/UserMapper.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/mapper/UserMapper.java
new file mode 100644
index 0000000..5a2260a
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/mapper/UserMapper.java
@@ -0,0 +1,7 @@
+package demo.springboot.test.mapper;
+
+import demo.springboot.test.config.MyMapper;
+import demo.springboot.test.domain.User;
+
+public interface UserMapper extends MyMapper {
+}
\ No newline at end of file
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/IService.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/IService.java
new file mode 100644
index 0000000..8a0debf
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/IService.java
@@ -0,0 +1,27 @@
+package demo.springboot.test.service;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Service;
+
+@Service
+public interface IService {
+
+ Long getSequence(@Param("seqName") String seqName);
+
+ List selectAll();
+
+ T selectByKey(Object key);
+
+ int save(T entity);
+
+ int delete(Object key);
+
+ int updateAll(T entity);
+
+ int updateNotNull(T entity);
+
+ List selectByExample(Object example);
+
+}
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/UserService.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/UserService.java
new file mode 100644
index 0000000..b30168d
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/UserService.java
@@ -0,0 +1,9 @@
+package demo.springboot.test.service;
+
+import demo.springboot.test.domain.User;
+
+public interface UserService extends IService{
+ User findByName(String userName);
+
+ void saveUser(User user);
+}
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/impl/BaseService.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/impl/BaseService.java
new file mode 100644
index 0000000..5ce0070
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/impl/BaseService.java
@@ -0,0 +1,69 @@
+package demo.springboot.test.service.impl;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import demo.springboot.test.mapper.SeqenceMapper;
+import demo.springboot.test.service.IService;
+import tk.mybatis.mapper.common.Mapper;
+
+public abstract class BaseService implements IService {
+
+ @Autowired
+ protected Mapper mapper;
+ @Autowired
+ protected SeqenceMapper seqenceMapper;
+
+ public Mapper getMapper() {
+ return mapper;
+ }
+ @Override
+ public Long getSequence(@Param("seqName") String seqName){
+ return seqenceMapper.getSequence(seqName);
+ }
+
+ @Override
+ public List selectAll() {
+ //说明:查询所有数据
+ return mapper.selectAll();
+ }
+
+ @Override
+ public T selectByKey(Object key) {
+ //说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
+ return mapper.selectByPrimaryKey(key);
+ }
+
+ @Override
+ public int save(T entity) {
+ //说明:保存一个实体,null的属性也会保存,不会使用数据库默认值
+ return mapper.insert(entity);
+ }
+
+ @Override
+ public int delete(Object key) {
+ //说明:根据主键字段进行删除,方法参数必须包含完整的主键属性
+ return mapper.deleteByPrimaryKey(key);
+ }
+
+ @Override
+ public int updateAll(T entity) {
+ //说明:根据主键更新实体全部字段,null值会被更新
+ return mapper.updateByPrimaryKey(entity);
+ }
+
+ @Override
+ public int updateNotNull(T entity) {
+ //根据主键更新属性不为null的值
+ return mapper.updateByPrimaryKeySelective(entity);
+ }
+
+ @Override
+ public List selectByExample(Object example) {
+ //说明:根据Example条件进行查询
+ //重点:这个查询支持通过Example类指定查询列,通过selectProperties方法指定查询列
+ return mapper.selectByExample(example);
+ }
+}
diff --git a/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/impl/UserServiceImpl.java b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..d4fe661
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/java/demo/springboot/test/service/impl/UserServiceImpl.java
@@ -0,0 +1,33 @@
+package demo.springboot.test.service.impl;
+
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.stereotype.Repository;
+
+import demo.springboot.test.domain.User;
+import demo.springboot.test.service.UserService;
+import tk.mybatis.mapper.entity.Example;
+
+@Repository("userService")
+public class UserServiceImpl extends BaseService implements UserService {
+
+ @Override
+ public User findByName(String userName) {
+ Example example = new Example(User.class);
+ example.createCriteria().andCondition("username=", userName);
+ List userList = this.selectByExample(example);
+ if (userList.size() != 0)
+ return userList.get(0);
+ else
+ return null;
+ }
+
+ @Override
+ public void saveUser(User user) {
+ user.setId(this.getSequence("seq_user"));
+ user.setCreateTime(new Date());
+ this.save(user);
+ }
+
+}
diff --git a/19.Spring-Boot-Testing/src/main/resources/application.yml b/19.Spring-Boot-Testing/src/main/resources/application.yml
new file mode 100644
index 0000000..1cbdc17
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/resources/application.yml
@@ -0,0 +1,86 @@
+server:
+ context-path: /web
+
+spring:
+ datasource:
+ druid:
+ # 数据库访问配置, 使用druid数据源
+ type: com.alibaba.druid.pool.DruidDataSource
+ driver-class-name: oracle.jdbc.driver.OracleDriver
+ url: jdbc:oracle:thin:@localhost:1521:ORCL
+ username: test
+ password: 123456
+ # 连接池配置
+ initial-size: 5
+ min-idle: 5
+ max-active: 20
+ # 连接等待超时时间
+ max-wait: 30000
+ # 配置检测可以关闭的空闲连接间隔时间
+ time-between-eviction-runs-millis: 60000
+ # 配置连接在池中的最小生存时间
+ min-evictable-idle-time-millis: 300000
+ validation-query: select '1' from dual
+ test-while-idle: true
+ test-on-borrow: false
+ test-on-return: false
+ # 打开PSCache,并且指定每个连接上PSCache的大小
+ pool-prepared-statements: true
+ max-open-prepared-statements: 20
+ max-pool-prepared-statement-per-connection-size: 20
+ # 配置监控统计拦截的filters, 去掉后监控界面sql无法统计, 'wall'用于防火墙
+ filters: stat,wall
+ # Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
+ aop-patterns: demo.springboot.test.servie.*
+
+
+ # WebStatFilter配置
+ web-stat-filter:
+ enabled: true
+ # 添加过滤规则
+ url-pattern: /*
+ # 忽略过滤的格式
+ exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
+
+ # StatViewServlet配置
+ stat-view-servlet:
+ enabled: true
+ # 访问路径为/druid时,跳转到StatViewServlet
+ url-pattern: /druid/*
+ # 是否能够重置数据
+ reset-enable: false
+ # 需要账号密码才能访问控制台
+ login-username: druid
+ login-password: druid123
+ # IP白名单
+ # allow: 127.0.0.1
+ # IP黑名单(共同存在时,deny优先于allow)
+ # deny: 192.168.1.218
+
+ # 配置StatFilter
+ filter:
+ stat:
+ log-slow-sql: true
+
+mybatis:
+ config-location: classpath:config/mybatis-config.xml
+ # type-aliases扫描路径
+ type-aliases-package: demo.springboot.test.domain
+ # mapper xml实现扫描路径
+ mapper-locations: classpath:mapper/*.xml
+ property:
+ order: BEFORE
+
+
+#mappers 多个接口时逗号隔开
+mapper:
+ mappers: demo.springboot.test.config.MyMapper
+ not-empty: false
+ identity: oracle
+
+#pagehelper
+pagehelper:
+ helperDialect: oracle
+ reasonable: true
+ supportMethodsArguments: true
+ params: count=countSql
\ No newline at end of file
diff --git a/19.Spring-Boot-Testing/src/main/resources/config/mybatis-config.xml b/19.Spring-Boot-Testing/src/main/resources/config/mybatis-config.xml
new file mode 100644
index 0000000..864917c
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/resources/config/mybatis-config.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/19.Spring-Boot-Testing/src/main/resources/init.sql b/19.Spring-Boot-Testing/src/main/resources/init.sql
new file mode 100644
index 0000000..e00d3d2
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/main/resources/init.sql
@@ -0,0 +1,21 @@
+-- ----------------------------
+-- Table structure for T_USER
+-- ----------------------------
+CREATE TABLE T_USER (
+ ID NUMBER NOT NULL ,
+ USERNAME VARCHAR2(20 BYTE) NOT NULL ,
+ PASSWD VARCHAR2(128 BYTE) NOT NULL ,
+ CREATE_TIME DATE NULL ,
+ STATUS CHAR(1 BYTE) NOT NULL
+);
+COMMENT ON COLUMN T_USER.USERNAME IS '用户名';
+COMMENT ON COLUMN T_USER.PASSWD IS '密码';
+COMMENT ON COLUMN T_USER.CREATE_TIME IS '创建时间';
+COMMENT ON COLUMN T_USER.STATUS IS '是否有效 1:有效 0:锁定';
+-- ----------------------------
+-- Records of T_USER
+-- ----------------------------
+INSERT INTO T_USER VALUES ('2', 'tester', '243e29429b340192700677d48c09d992', TO_DATE('2017-12-11 17:20:21', 'YYYY-MM-DD HH24:MI:SS'), '1');
+INSERT INTO T_USER VALUES ('1', 'mrbird', '42ee25d1e43e9f57119a00d0a39e5250', TO_DATE('2017-12-11 10:52:48', 'YYYY-MM-DD HH24:MI:SS'), '1');
+
+create sequence seq_user start with 1 INCREMENT by 1;
\ No newline at end of file
diff --git a/19.Spring-Boot-Testing/src/test/java/demo/springboot/test/UserControllerTest.java b/19.Spring-Boot-Testing/src/test/java/demo/springboot/test/UserControllerTest.java
new file mode 100644
index 0000000..26f22c3
--- /dev/null
+++ b/19.Spring-Boot-Testing/src/test/java/demo/springboot/test/UserControllerTest.java
@@ -0,0 +1,101 @@
+package demo.springboot.test;
+
+import javax.servlet.http.Cookie;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.context.WebApplicationContext;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jayway.jsonpath.JsonPath;
+
+import demo.springboot.test.domain.User;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class UserControllerTest {
+
+ private MockMvc mockMvc;
+ private MockHttpSession session;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Autowired
+ ObjectMapper mapper;
+
+
+ @Before
+ public void setupMockMvc(){
+ mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
+ session = new MockHttpSession();
+ User user =new User();
+ user.setUsername("Dopa");
+ user.setPasswd("ac3af72d9f95161a502fd326865c2f15");
+ session.setAttribute("user",user);
+ }
+
+ @Test
+ @Transactional
+ public void test() throws Exception {
+// mockMvc.perform(
+// MockMvcRequestBuilders.get("/user/{userName}", "scott")
+// .contentType(MediaType.APPLICATION_JSON_UTF8))
+// .andExpect(MockMvcResultMatchers.status().isOk())
+// .andExpect(MockMvcResultMatchers.jsonPath("$.username").value("scott"))
+// .andDo(MockMvcResultHandlers.print());
+
+// String jsonStr = "{\"username\":\"Dopa\",\"passwd\":\"ac3af72d9f95161a502fd326865c2f15\",\"status\":\"1\"}";
+
+ User user = new User();
+ user.setUsername("Dopa");
+ user.setPasswd("ac3af72d9f95161a502fd326865c2f15");
+ user.setStatus("1");
+
+ String userJson = mapper.writeValueAsString(user);
+
+
+// mockMvc.perform(MockMvcRequestBuilders.post("/user/save").content(jsonStr.getBytes()));
+
+ mockMvc.perform(
+ MockMvcRequestBuilders.post("/user/save")
+ .contentType(MediaType.APPLICATION_JSON_UTF8)
+ .content(userJson.getBytes()))
+ .andExpect(MockMvcResultMatchers.status().isOk())
+ .andDo(MockMvcResultHandlers.print());
+
+// mockMvc.perform(MockMvcRequestBuilders.get("/hello?name={name}","mrbird"));
+// mockMvc.perform(MockMvcRequestBuilders.post("/user/{id}", 1));
+// mockMvc.perform(MockMvcRequestBuilders.fileUpload("/fileupload").file("file", "文件内容".getBytes("utf-8")));
+// mockMvc.perform(MockMvcRequestBuilders.get("/hello").param("message", "hello"));
+// mockMvc.perform(MockMvcRequestBuilders.get("/hobby/save").param("hobby", "sleep", "eat"));
+
+// MultiValueMap params = new LinkedMultiValueMap();
+// params.add("name", "mrbird");
+// params.add("hobby", "sleep");
+// params.add("hobby", "eat");
+// mockMvc.perform(MockMvcRequestBuilders.get("/hobby/save").params(params));
+// mockMvc.perform(MockMvcRequestBuilders.get("/index").sessionAttr(name, value));
+// mockMvc.perform(MockMvcRequestBuilders.get("/index").cookie(new Cookie(name, value)));
+// mockMvc.perform(MockMvcRequestBuilders.get("/index").contentType(MediaType.APPLICATION_JSON_UTF8));
+// mockMvc.perform(MockMvcRequestBuilders.get("/user/{id}", 1).accept(MediaType.APPLICATION_JSON));
+// mockMvc.perform(MockMvcRequestBuilders.get("/user/{id}", 1).header(name, values));
+
+// mockMvc.perform(MockMvcRequestBuilders.get("/index"))
+// .andDo(MockMvcResultHandlers.print());
+
+
+ }
+}