diff --git a/pom.xml b/pom.xml
index 607ff9b..3269d27 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,7 @@
spring-boot-demo-template-enjoy
spring-boot-demo-orm-jdbctemplate
spring-boot-demo-orm-jpa
+ spring-boot-demo-orm-mybatis
spring-boot-demo-email
spring-boot-demo-upload
spring-boot-demo-war
diff --git a/spring-boot-demo-orm-mybatis/.gitignore b/spring-boot-demo-orm-mybatis/.gitignore
new file mode 100644
index 0000000..82eca33
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/.gitignore
@@ -0,0 +1,25 @@
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
\ No newline at end of file
diff --git a/spring-boot-demo-orm-mybatis/README.md b/spring-boot-demo-orm-mybatis/README.md
new file mode 100644
index 0000000..ddde73a
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/README.md
@@ -0,0 +1,256 @@
+# spring-boot-demo-orm-mybatis
+
+> 此 demo 演示了 Spring Boot 如何与原生的 mybatis 整合,使用了 mybatis 官方提供的脚手架 `mybatis-spring-boot-starter `可以很容易的和 Spring Boot 整合。
+
+## pom.xml
+
+```xml
+
+
+ 4.0.0
+
+ spring-boot-demo-orm-mybatis
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-demo-orm-mybatis
+ Demo project for Spring Boot
+
+
+ com.xkcoding
+ spring-boot-demo
+ 1.0.0-SNAPSHOT
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 1.3.2
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ ${mybatis.version}
+
+
+
+ mysql
+ mysql-connector-java
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ cn.hutool
+ hutool-all
+
+
+
+ com.google.guava
+ guava
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ spring-boot-demo-orm-mybatis
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+```
+
+## SpringBootDemoOrmMybatisApplication.java
+
+```java
+/**
+ *
+ * 启动类
+ *
+ *
+ * @package: com.xkcoding.orm.mybatis
+ * @description: 启动类
+ * @author: yangkai.shen
+ * @date: Created in 2018/11/8 10:52
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@MapperScan(basePackages = {"com.xkcoding.orm.mybatis.mapper"})
+@SpringBootApplication
+public class SpringBootDemoOrmMybatisApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootDemoOrmMybatisApplication.class, args);
+ }
+}
+```
+
+## UserMapper.java
+
+```java
+/**
+ *
+ * User Mapper
+ *
+ *
+ * @package: com.xkcoding.orm.mybatis.mapper
+ * @description: User Mapper
+ * @author: yangkai.shen
+ * @date: Created in 2018/11/8 10:54
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Mapper
+@Component
+public interface UserMapper {
+
+ /**
+ * 查询所有用户
+ *
+ * @return 用户列表
+ */
+ @Select("SELECT * FROM orm_user")
+ List selectAllUser();
+
+ /**
+ * 根据id查询用户
+ *
+ * @param id 主键id
+ * @return 当前id的用户,不存在则是 {@code null}
+ */
+ @Select("SELECT * FROM orm_user WHERE id = #{id}")
+ User selectUserById(@Param("id") Long id);
+
+ /**
+ * 保存用户
+ *
+ * @param user 用户
+ * @return 成功 - {@code 1} 失败 - {@code 0}
+ */
+ int saveUser(@Param("user") User user);
+
+ /**
+ * 删除用户
+ *
+ * @param id 主键id
+ * @return 成功 - {@code 1} 失败 - {@code 0}
+ */
+ int deleteById(@Param("id") Long id);
+
+}
+```
+
+## UserMapper.xml
+
+```xml
+
+
+
+
+
+ INSERT INTO `orm_user` (`name`,
+ `password`,
+ `salt`,
+ `email`,
+ `phone_number`,
+ `status`,
+ `create_time`,
+ `last_login_time`,
+ `last_update_time`)
+ VALUES (#{user.name},
+ #{user.password},
+ #{user.salt},
+ #{user.email},
+ #{user.phoneNumber},
+ #{user.status},
+ #{user.createTime},
+ #{user.lastLoginTime},
+ #{user.lastUpdateTime})
+
+
+
+ DELETE
+ FROM `orm_user`
+ WHERE `id` = #{id}
+
+
+```
+
+## UserMapperTest.java
+
+```java
+/**
+ *
+ * UserMapper 测试类
+ *
+ *
+ * @package: com.xkcoding.orm.mybatis.mapper
+ * @description: UserMapper 测试类
+ * @author: yangkai.shen
+ * @date: Created in 2018/11/8 11:25
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Slf4j
+public class UserMapperTest extends SpringBootDemoOrmMybatisApplicationTests {
+ @Autowired
+ private UserMapper userMapper;
+
+ @Test
+ public void selectAllUser() {
+ List userList = userMapper.selectAllUser();
+ Assert.assertTrue(CollUtil.isNotEmpty(userList));
+ log.debug("【userList】= {}", userList);
+ }
+
+ @Test
+ public void selectUserById() {
+ User user = userMapper.selectUserById(1L);
+ Assert.assertNotNull(user);
+ log.debug("【user】= {}", user);
+ }
+
+ @Test
+ public void saveUser() {
+ String salt = IdUtil.fastSimpleUUID();
+ User user = User.builder().name("testSave3").password(SecureUtil.md5("123456" + salt)).salt(salt).email("testSave3@xkcoding.com").phoneNumber("17300000003").status(1).lastLoginTime(new DateTime()).createTime(new DateTime()).lastUpdateTime(new DateTime()).build();
+ int i = userMapper.saveUser(user);
+ Assert.assertEquals(1, i);
+ }
+
+ @Test
+ public void deleteById() {
+ int i = userMapper.deleteById(1L);
+ Assert.assertEquals(1, i);
+ }
+}
+```
+
+## 参考
+
+- Mybatis官方文档:http://www.mybatis.org/mybatis-3/zh/index.html
+
+- Mybatis官方脚手架文档:http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/
+
+- Mybatis整合Spring Boot官方demo:https://github.com/mybatis/spring-boot-starter/tree/master/mybatis-spring-boot-samples
diff --git a/spring-boot-demo-orm-mybatis/pom.xml b/spring-boot-demo-orm-mybatis/pom.xml
new file mode 100644
index 0000000..5d35084
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ spring-boot-demo-orm-mybatis
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-boot-demo-orm-mybatis
+ Demo project for Spring Boot
+
+
+ com.xkcoding
+ spring-boot-demo
+ 1.0.0-SNAPSHOT
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 1.3.2
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ ${mybatis.version}
+
+
+
+ mysql
+ mysql-connector-java
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+
+ cn.hutool
+ hutool-all
+
+
+
+ com.google.guava
+ guava
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ spring-boot-demo-orm-mybatis
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/SpringBootDemoOrmMybatisApplication.java b/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/SpringBootDemoOrmMybatisApplication.java
new file mode 100644
index 0000000..27e2ba0
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/SpringBootDemoOrmMybatisApplication.java
@@ -0,0 +1,27 @@
+package com.xkcoding.orm.mybatis;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ *
+ * 启动类
+ *
+ *
+ * @package: com.xkcoding.orm.mybatis
+ * @description: 启动类
+ * @author: yangkai.shen
+ * @date: Created in 2018/11/8 10:52
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@MapperScan(basePackages = {"com.xkcoding.orm.mybatis.mapper"})
+@SpringBootApplication
+public class SpringBootDemoOrmMybatisApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootDemoOrmMybatisApplication.class, args);
+ }
+}
diff --git a/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/entity/User.java b/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/entity/User.java
new file mode 100644
index 0000000..21c9d88
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/entity/User.java
@@ -0,0 +1,80 @@
+package com.xkcoding.orm.mybatis.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ *
+ * 用户实体类
+ *
+ *
+ * @package: com.xkcoding.orm.mybatis.entity
+ * @description: 用户实体类
+ * @author: yangkai.shen
+ * @date: Created in 2018/11/8 10:58
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class User implements Serializable {
+ private static final long serialVersionUID = -1840831686851699943L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+
+ /**
+ * 用户名
+ */
+ private String name;
+
+ /**
+ * 加密后的密码
+ */
+ private String password;
+
+ /**
+ * 加密使用的盐
+ */
+ private String salt;
+
+ /**
+ * 邮箱
+ */
+ private String email;
+
+ /**
+ * 手机号码
+ */
+ private String phoneNumber;
+
+ /**
+ * 状态,-1:逻辑删除,0:禁用,1:启用
+ */
+ private Integer status;
+
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+ /**
+ * 上次登录时间
+ */
+ private Date lastLoginTime;
+
+ /**
+ * 上次更新时间
+ */
+ private Date lastUpdateTime;
+}
diff --git a/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/mapper/UserMapper.java b/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/mapper/UserMapper.java
new file mode 100644
index 0000000..b76ac32
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/main/java/com/xkcoding/orm/mybatis/mapper/UserMapper.java
@@ -0,0 +1,61 @@
+package com.xkcoding.orm.mybatis.mapper;
+
+import com.xkcoding.orm.mybatis.entity.User;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ *
+ * User Mapper
+ *
+ *
+ * @package: com.xkcoding.orm.mybatis.mapper
+ * @description: User Mapper
+ * @author: yangkai.shen
+ * @date: Created in 2018/11/8 10:54
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Mapper
+@Component
+public interface UserMapper {
+
+ /**
+ * 查询所有用户
+ *
+ * @return 用户列表
+ */
+ @Select("SELECT * FROM orm_user")
+ List selectAllUser();
+
+ /**
+ * 根据id查询用户
+ *
+ * @param id 主键id
+ * @return 当前id的用户,不存在则是 {@code null}
+ */
+ @Select("SELECT * FROM orm_user WHERE id = #{id}")
+ User selectUserById(@Param("id") Long id);
+
+ /**
+ * 保存用户
+ *
+ * @param user 用户
+ * @return 成功 - {@code 1} 失败 - {@code 0}
+ */
+ int saveUser(@Param("user") User user);
+
+ /**
+ * 删除用户
+ *
+ * @param id 主键id
+ * @return 成功 - {@code 1} 失败 - {@code 0}
+ */
+ int deleteById(@Param("id") Long id);
+
+}
diff --git a/spring-boot-demo-orm-mybatis/src/main/resources/application.yml b/spring-boot-demo-orm-mybatis/src/main/resources/application.yml
new file mode 100644
index 0000000..a61559f
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/main/resources/application.yml
@@ -0,0 +1,32 @@
+spring:
+ datasource:
+ url: jdbc:mysql://127.0.0.1:3306/spring-boot-demo?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
+ username: root
+ password: root
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ type: com.zaxxer.hikari.HikariDataSource
+ initialization-mode: always
+ continue-on-error: true
+ schema:
+ - "classpath:db/schema.sql"
+ data:
+ - "classpath:db/data.sql"
+ hikari:
+ minimum-idle: 5
+ connection-test-query: SELECT 1 FROM DUAL
+ maximum-pool-size: 20
+ auto-commit: true
+ idle-timeout: 30000
+ pool-name: SpringBootDemoHikariCP
+ max-lifetime: 60000
+ connection-timeout: 30000
+logging:
+ level:
+ com.xkcoding: debug
+ com.xkcoding.orm.mybatis.mapper: trace
+mybatis:
+ configuration:
+ # 下划线转驼峰
+ map-underscore-to-camel-case: true
+ mapper-locations: classpath:mappers/*.xml
+ type-aliases-package: com.xkcoding.orm.mybatis.entity
diff --git a/spring-boot-demo-orm-mybatis/src/main/resources/db/data.sql b/spring-boot-demo-orm-mybatis/src/main/resources/db/data.sql
new file mode 100644
index 0000000..3ab2b59
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/main/resources/db/data.sql
@@ -0,0 +1,2 @@
+INSERT INTO `orm_user`(`id`,`name`,`password`,`salt`,`email`,`phone_number`) VALUES (1, 'user_1', 'ff342e862e7c3285cdc07e56d6b8973b', '412365a109674b2dbb1981ed561a4c70', 'user1@xkcoding.com', '17300000001');
+INSERT INTO `orm_user`(`id`,`name`,`password`,`salt`,`email`,`phone_number`) VALUES (2, 'user_2', '6c6bf02c8d5d3d128f34b1700cb1e32c', 'fcbdd0e8a9404a5585ea4e01d0e4d7a0', 'user2@xkcoding.com', '17300000002');
\ No newline at end of file
diff --git a/spring-boot-demo-orm-mybatis/src/main/resources/db/schema.sql b/spring-boot-demo-orm-mybatis/src/main/resources/db/schema.sql
new file mode 100644
index 0000000..22804e5
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/main/resources/db/schema.sql
@@ -0,0 +1,13 @@
+DROP TABLE IF EXISTS `orm_user`;
+CREATE TABLE `orm_user` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
+ `name` VARCHAR(32) NOT NULL UNIQUE COMMENT '用户名',
+ `password` VARCHAR(32) NOT NULL COMMENT '加密后的密码',
+ `salt` VARCHAR(32) NOT NULL COMMENT '加密使用的盐',
+ `email` VARCHAR(32) NOT NULL UNIQUE COMMENT '邮箱',
+ `phone_number` VARCHAR(15) NOT NULL UNIQUE COMMENT '手机号码',
+ `status` INT(2) NOT NULL DEFAULT 1 COMMENT '状态,-1:逻辑删除,0:禁用,1:启用',
+ `create_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '创建时间',
+ `last_login_time` DATETIME DEFAULT NULL COMMENT '上次登录时间',
+ `last_update_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '上次更新时间'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Spring Boot Demo Orm 系列示例表';
diff --git a/spring-boot-demo-orm-mybatis/src/main/resources/mappers/UserMapper.xml b/spring-boot-demo-orm-mybatis/src/main/resources/mappers/UserMapper.xml
new file mode 100644
index 0000000..d236ccf
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/main/resources/mappers/UserMapper.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+ INSERT INTO `orm_user` (`name`,
+ `password`,
+ `salt`,
+ `email`,
+ `phone_number`,
+ `status`,
+ `create_time`,
+ `last_login_time`,
+ `last_update_time`)
+ VALUES (#{user.name},
+ #{user.password},
+ #{user.salt},
+ #{user.email},
+ #{user.phoneNumber},
+ #{user.status},
+ #{user.createTime},
+ #{user.lastLoginTime},
+ #{user.lastUpdateTime})
+
+
+
+ DELETE
+ FROM `orm_user`
+ WHERE `id` = #{id}
+
+
\ No newline at end of file
diff --git a/spring-boot-demo-orm-mybatis/src/test/java/com/xkcoding/orm/mybatis/SpringBootDemoOrmMybatisApplicationTests.java b/spring-boot-demo-orm-mybatis/src/test/java/com/xkcoding/orm/mybatis/SpringBootDemoOrmMybatisApplicationTests.java
new file mode 100644
index 0000000..9d607e6
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/test/java/com/xkcoding/orm/mybatis/SpringBootDemoOrmMybatisApplicationTests.java
@@ -0,0 +1,16 @@
+package com.xkcoding.orm.mybatis;
+
+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 SpringBootDemoOrmMybatisApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-boot-demo-orm-mybatis/src/test/java/com/xkcoding/orm/mybatis/mapper/UserMapperTest.java b/spring-boot-demo-orm-mybatis/src/test/java/com/xkcoding/orm/mybatis/mapper/UserMapperTest.java
new file mode 100644
index 0000000..dcb10c7
--- /dev/null
+++ b/spring-boot-demo-orm-mybatis/src/test/java/com/xkcoding/orm/mybatis/mapper/UserMapperTest.java
@@ -0,0 +1,61 @@
+package com.xkcoding.orm.mybatis.mapper;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.xkcoding.orm.mybatis.SpringBootDemoOrmMybatisApplicationTests;
+import com.xkcoding.orm.mybatis.entity.User;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ *
+ * UserMapper 测试类
+ *
+ *
+ * @package: com.xkcoding.orm.mybatis.mapper
+ * @description: UserMapper 测试类
+ * @author: yangkai.shen
+ * @date: Created in 2018/11/8 11:25
+ * @copyright: Copyright (c) 2018
+ * @version: V1.0
+ * @modified: yangkai.shen
+ */
+@Slf4j
+public class UserMapperTest extends SpringBootDemoOrmMybatisApplicationTests {
+ @Autowired
+ private UserMapper userMapper;
+
+ @Test
+ public void selectAllUser() {
+ List userList = userMapper.selectAllUser();
+ Assert.assertTrue(CollUtil.isNotEmpty(userList));
+ log.debug("【userList】= {}", userList);
+ }
+
+ @Test
+ public void selectUserById() {
+ User user = userMapper.selectUserById(1L);
+ Assert.assertNotNull(user);
+ log.debug("【user】= {}", user);
+ }
+
+ @Test
+ public void saveUser() {
+ String salt = IdUtil.fastSimpleUUID();
+ User user = User.builder().name("testSave3").password(SecureUtil.md5("123456" + salt)).salt(salt).email("testSave3@xkcoding.com").phoneNumber("17300000003").status(1).lastLoginTime(new DateTime()).createTime(new DateTime()).lastUpdateTime(new DateTime()).build();
+ int i = userMapper.saveUser(user);
+ Assert.assertEquals(1, i);
+ }
+
+ @Test
+ public void deleteById() {
+ int i = userMapper.deleteById(1L);
+ Assert.assertEquals(1, i);
+ }
+}
\ No newline at end of file