特别说明: 本人平时混迹于 B 站,不咋回复这里的评论,有问题可以到 B 站视频评论区留言找我
视频地址: https://space.bilibili.com/31137138/favlist?fid=326428938
课件说明: 本次提供的课件是 Spring Cloud Netflix 版微服务架构指南,如果有兴趣想要学习 Spring Cloud Alibaba 版,可以前往 http://www.qfdmy.com 查看相关课程资源
案例代码: https://github.com/topsale/hello-spring-cloud-netflix
概述
Spring Boot 可以称之为 新一代 JavaEE 开发标准;随着动态语言的流行 (Ruby、Groovy、Scala、Node.js),Java 的开发显得格外的笨重:繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术集成难度大。
在上述环境下,Spring Boot 应运而生。它使用 “习惯优于配置” (项目中存在大量的配置,此外还内置了一个习惯性的配置,让你无需手动进行配置)的理念让你的项目快速的运行起来。使用 Spring Boot 很容易创建一个独立运行(运行 Jar,内嵌 Servlet 容器)准生产级别的基于 Spring 框架的项目,使用 Spring Boot 你可以不用或者只需很少的 Spring 配置。
Spring 简史
Spring 1.x 时代
在 Spring1.x 时代,都是通过 xml 文件配置 bean,随着项目的不断扩大,需要将 xml 配置分放到不同的配置文件中,需要频繁的在 java 类和 xml 配置文件中切换。
Spring 2.x 时代
随着 JDK 1.5 带来的注解支持,Spring2.x 可以使用注解对 Bean 进行申明和注入,大大的减少了 xml 配置文件,同时也大大简化了项目的开发。
那么,问题来了,究竟是应该使用 xml 还是注解呢?
最佳实践:
- 应用的基本配置用 xml,比如:数据源、资源文件等
- 业务开发用注解,比如:Service 中注入 bean 等
Spring 3.x 时代
从 Spring3.x 开始提供了 Java 配置方式,使用 Java 配置方式可以更好的理解你配置的 Bean,现在我们就处于这个时代,并且 Spring4.x 和 Spring boot 都推荐使用 java 配置的方式。
Spring 5.x 时代
Spring5.x 是 Java 界首个支持响应式的 Web 框架,是 Spring 的一个重要版本,距离 Spring4.x 差不多四年。在此期间,大多数增强都是在 Spring Boot 项目中完成的,其最大的亮点就是提供了完整的端到端响应式编程的支持(新增 Spring WebFlux 模块)。
Spring WebFlux 同时支持使用旧的 Spring MVC 注解声明 Reactive Controller
。和传统的 MVC Controller
不同,Reactive Controller
操作的是 非阻塞 的 ServerHttpRequest
和 ServerHttpResponse
,而不再是 Spring MVC 里的 HttpServletRequest 和 HttpServletResponse。
至此也代表着 Java 正式迎来了响应式异步编程的时代。
优缺点
优点
- 快速构建项目
- 对主流开发框架的无配置集成
- 项目可独立运行,无需外部依赖 Servlet 容器
- 提供运行时的应用监控
- 极大地提高了开发、部署效率
- 与云计算的天然集成
缺点
- 版本迭代速度很快,一些模块改动很大
- 由于不用自己做配置,报错时很难定位
第一个 Spring Boot 应用程序
创建项目
这里我们使用 Intellij IDEA 来新建一个 Spring Boot 项目
Spring 初始化器
填写项目信息
选择版本和依赖
保存项目到指定目录
工程目录结构
创建完成后的工程目录结构如下:
│ .gitignore
│ pom.xml
│
│
└─src
├─main
│ ├─java
│ │ └─com
│ │ └─funtl
│ │ └─hello
│ │ └─spring
│ │ └─boot
│ │ HelloSpringBootApplication.java
│ │
│ └─resources
│ │ application.properties
│ │
│ ├─static
│ └─templates
└─test
└─java
└─com
└─funtl
└─hello
└─spring
└─boot
HelloSpringBootApplicationTests.java
- .gitignore:Git 过滤配置文件
- pom.xml:Maven 的依赖管理配置文件
- HelloSpringBootApplication.java:程序入口
- resources:资源文件目录
- static: 静态资源文件目录
- templates:模板资源文件目录
- application.properties:Spring Boot 的配置文件,实际开发中会替换成 YAML 语言配置(application.yml)
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.funtl</groupId>
<artifactId>hello-spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-boot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.funtl.hello.spring.boot.HelloSpringBootApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
- parent:继承了 Spring Boot 的 Parent,表示我们是一个 Spring Boot 工程
-
spring-boot-starter-web
:包含了spring-boot-starter
还自动帮我们开启了 Web 支持
功能演示
我们创建一个 Controller 来演示一下 Spring Boot 的神奇功能
package com.funtl.hello.spring.boot.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping(value = "/")
public String sayHi() {
return "Hello Spring Boot.";
}
}
启动 HelloSpringBootApplication
的 main()
方法,浏览器访问 http://localhost:8080 可以看到:
Hello Spring Boot.
神奇之处
- 没有配置 web.xml
- 没有配置 application.xml,Spring Boot 帮你配置了
- 没有配置 application-mvc.xml,Spring Boot 帮你配置了
- 没有配置 Tomcat,Spring Boot 内嵌了 Tomcat 容器
Spring Boot 单元测试
主要是通过 @RunWith
和 @SpringBootTest
注解来开启单元测试功能
package com.funtl.hello.spring.boot;
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.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import java.net.URL;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = HelloSpringBootApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloSpringBootApplicationTests {
@LocalServerPort
private int port;
private URL base;
@Autowired
private TestRestTemplate template;
@Before
public void setUp() throws Exception {
this.base = new URL("http://localhost:" + port + "/");
}
@Test
public void contextLoads() {
ResponseEntity<String> response = template.getForEntity(base.toString(), String.class);
assertThat(response.getBody(), equalTo("Hello Spring Boot"));
}
}
运行它会先启动 Spring Boot 工程,再启动单元测试
Spring Boot 常用配置
自定义 Banner
在 Spring Boot 启动的时候会有一个默认的启动图案
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
我们在 src/main/resources
目录下新建一个 banner.txt
通过 http://patorjk.com/software/taag 网站生成字符串,将网站生成的字符复制到 banner.txt 中
再次运行这个程序
${AnsiColor.BRIGHT_RED}
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////
常用属性设置:
-
${AnsiColor.BRIGHT_RED}
:设置控制台中输出内容的颜色 -
${application.version}
:用来获取MANIFEST.MF
文件中的版本号 -
${application.formatted-version}
:格式化后的${application.version}
版本信息 -
${spring-boot.version}
:Spring Boot 的版本号 -
${spring-boot.formatted-version}
:格式化后的${spring-boot.version}
版本信息
配置文件
Spring Boot 项目使用一个全局的配置文件 application.properties
或者是 application.yml
,在 resources
目录下或者类路径下的 /config
下,一般我们放到 resources
下。
修改 Tomcat 的端口为 9090,并将默认的访问路径 "/" 修改为 "boot",可以在 application.properties
中添加:
server.port=9090
server.context-path=/boot
或在 application.yml 中添加:
server:
port: 9090
context-path: /boot
测试效果:
Starter POM
Spring Boot 为我们提供了简化企业级开发绝大多数场景的 starter pom ,只要使用了应用场景所需要的 starter pom ,相关的技术配置将会消除,就可以得到 Spring Boot 为我们提供的自动配置的 Bean。
日志配置
Spring Boot 对各种日志框架都做了支持,我们可以通过配置来修改默认的日志的配置
默认情况下,Spring Boot 使用 Logback 作为日志框架
logging:
file: ../logs/spring-boot-hello.log
level.org.springframework.web: DEBUG
关闭特定的自动配置
关闭特定的自动配置使用 @SpringBootApplication
注解的 exclude
参数即可,这里以关闭数据源的自动配置为例
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
Spring Boot 整合 HikariCP
什么是 HikariCP
HiKariCP 是数据库连接池的一个后起之秀,号称性能最好,可以完美地 PK 掉其他连接池。是一个高性能的 JDBC 连接池,基于 BoneCP 做了不少的改进和优化。超快,快到连 Spring Boot 2 都宣布支持了。
什么是 BoneCP
传说中 BoneCP 在快速这个特点上做到了极致,官方数据是 C3P0 等的 25 倍左右,以下为性能测试报告。
单线程
- 1,000,000 获取连接/释放连接请求
- 获取/释放连接之间没有延迟
- 连接池范围:20-50
- 增量:5
- 线程:1
- 分区:1
多线程
- 500 个线程分别获取释放 100 个连接
- 在获取连接和释放连接之间引入了 10ms 的延迟
Thread.sleep()
,模拟连接完成工作 - 连接池范围:50-200
- 增量:5
- 线程:5
Prepared Statement
- 500 个线程分别获取释放 100 个连接
- 无延迟
- 连接池范围:50-200
- 增量:5
- 线程:5
为什么需要 HikariCP
BoneCP 作者放弃维护,并在 Github 项目主页推荐大家使用 HikariCP,Hikari(ひかり[shi ga li]) 来自日文,是 光 的意思。这个产品的口号是 快速、简单、可靠
优化
- 字节码精简 : 优化代码,直到编译后的字节码最少,这样,CPU 缓存可以加载更多的程序代码
- 优化代理和拦截器 : 减少代码,例如 HikariCP 的 Statement proxy 只有 100 行代码,只有 BoneCP 的十分之一
-
自定义数组类型(FastStatementList)代替 ArrayList : 避免每次
get()
调用都要进行 range check,避免调用remove()
时的从头到尾的扫描 - 自定义集合类型(ConcurrentBag): 提高并发读写的效率
- 其他针对 BoneCP 缺陷的优化: 比如对于耗时超过一个 CPU 时间片的方法调用的研究(但没说具体怎么优化)
代码量
几个连接池的代码量对比(代码量越少,一般意味着执行效率越高、发生 BUG 的可能性越低)
Pool | Files | Code |
---|---|---|
Vibur | 34 | 1927 |
HikariCP | 21 | 2228 |
Tomcat | 31 | 6345 |
BoneCP | 49 | 7293 |
C3P0 | 120 | 15550 |
速度
别人发推文测试 Hikari 速度
稳定性
可靠性
另外,关于可靠性方面,也是有实验和数据支持的。对于数据库连接中断的情况,通过测试 getConnection()
,各种 CP 的不相同处理方法如下(所有 CP 都配置了跟 connectionTimeout
类似的参数为 5 秒钟)
-
HikariCP(A): 等待 5 秒钟后,如果连接还是没有恢复,则抛出一个
SQLExceptions
异常;后续的getConnection()
也是一样处理 -
C3P0(C-): 完全没有反应,没有提示,也不会在
CheckoutTimeout
配置的时长超时后有任何通知给调用者;然后等待 2 分钟后终于醒来了,返回一个 error -
Tomcat(F): 返回一个 connection,然后调用者如果利用这个无效的 connection 执行 SQL 语句 结果可想而知;大约 55 秒之后终于醒来了,这时候的
getConnection()
终于可以返回一个 error,但没有等待参数配置的 5 秒钟,而是立即返回 error - BoneCP(C): 跟 Tomcat 的处理方法一样;也是大约 55 秒之后才醒来,有了正常的反应,并且终于会等待 5 秒钟之后返回 error 了
整合 HikariCP
POM
<!-- 主要增加 HikariCP 依赖 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>${hikaricp.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<!-- 排除 tomcat-jdbc 以使用 HikariCP -->
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
application.yml
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.141.130:3306/myshop?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
hikari:
minimum-idle: 5
idle-timeout: 600000
maximum-pool-size: 10
auto-commit: true
pool-name: MyHikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
注意: 具体使用方法在 测试 MyBatis 操作数据库 时进行介绍,此处仅为准备环节
Spring Boot 整合 TkMyBatis
tk.mybatis 是在 MyBatis 框架的基础上提供了很多工具,让开发更加高效
POM
在 pom.xml
文件中引入 mapper-spring-boot-starter
依赖,该依赖会自动引入 MyBaits 相关依赖
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
application.yml
mybatis:
# 实体类的存放路径
type-aliases-package: com.funtl.hello.spring.boot.domain
mapper-locations: classpath:mapper/*.xml
创建通用父级接口
主要作用是让 DAO 层的接口继承该接口,以达到使用 tk.mybatis 的目的
package tk.mybatis.mapper;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
/**
* 自己的 Mapper
* 特别注意,该接口不能被扫描到,否则会出错
* <p>Title: MyMapper</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2018/5/29 0:57
*/
public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
}
Spring Boot 整合 PageHelper
PageHelper 是 Mybatis 的分页插件,支持多数据库、多数据源。可以简化数据库的分页查询操作,整合过程也极其简单,只需引入依赖即可
POM
在 pom.xml
文件中引入 pagehelper-spring-boot-starter
依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
代码生成插件
我们无需手动编写 实体类、DAO、XML 配置文件,只需要使用 MyBatis 提供的一个 Maven 插件就可以自动生成所需的各种文件便能够满足基本的业务需求,如果业务比较复杂只需要修改相关文件即可
配置插件
在 pom.xml
文件中增加 mybatis-generator-maven-plugin
插件
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.1.5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
注意:
configurationFile
自动生成所需的配置文件路径
自动生成的配置
在 src/main/resources/generator/
目录下创建 generatorConfig.xml
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 引入数据库连接配置 -->
<properties resource="jdbc.properties"/>
<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!-- 配置 tk.mybatis 插件 -->
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="com.funtl.utils.MyMapper"/>
</plugin>
<!-- 配置数据库连接 -->
<jdbcConnection
driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.connectionURL}"
userId="${jdbc.username}"
password="${jdbc.password}">
</jdbcConnection>
<!-- 配置实体类存放路径 -->
<javaModelGenerator targetPackage="com.funtl.hello.spring.boot.domain" targetProject="src/main/java"/>
<!-- 配置 XML 存放路径 -->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
<!-- 配置 DAO 存放路径 -->
<javaClientGenerator
targetPackage="com.funtl.hello.spring.boot.mapper"
targetProject="src/main/java"
type="XMLMAPPER"/>
<!-- 配置需要指定生成的数据库和表,% 代表所有表 -->
<table catalog="myshop" tableName="%">
<!-- 默认为 false,如果设置为 true,在生成的 SQL 中,table 名字不会加上 catalog 或 schema -->
<property name="ignoreQualifiersAtRuntime" value="true"/>
<!-- mysql 配置 -->
<generatedKey column="id" sqlStatement="Mysql" identity="true"/>
</table>
</context>
</generatorConfiguration>
配置数据源
在 src/main/resources
目录下创建 jdbc.properties
数据源配置:
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://192.168.141.130:3306/myshop?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=123456
插件自动生成
mvn mybatis-generator:generate
# 输出如下
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" -Dvisualvm.id=757855494303000 -Dmaven.multiModuleProjectDirectory=D:\Workspace\Study\other\hello-spring-boot "-Dmaven.home=C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\plugins\maven\lib\maven3" "-Dclassworlds.conf=C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\plugins\maven\lib\maven3\bin\m2.conf" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=64651:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\plugins\maven\lib\maven3\boot\plexus-classworlds-2.5.2.jar" org.codehaus.classworlds.Launcher -Didea.version2019.1.3 --update-snapshots -s D:\apache-maven-3.6.1\conf\settings.xml org.mybatis.generator:mybatis-generator-maven-plugin:1.3.7:generate
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello-spring-boot 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- mybatis-generator-maven-plugin:1.3.7:generate (default-cli) @ hello-spring-boot ---
[INFO] Connecting to the Database
[INFO] Introspecting table myshop..%
[INFO] Generating Record class for table myshop..tb_item_param_item
[INFO] Generating Mapper Interface for table myshop..tb_item_param_item
[INFO] Generating SQL Map for table myshop..tb_item_param_item
[INFO] Generating Record class for table myshop..tb_item_cat
[INFO] Generating Mapper Interface for table myshop..tb_item_cat
[INFO] Generating SQL Map for table myshop..tb_item_cat
[INFO] Generating Record class for table myshop..tb_order
[INFO] Generating Mapper Interface for table myshop..tb_order
[INFO] Generating SQL Map for table myshop..tb_order
[INFO] Generating Record class for table myshop..tb_content
[INFO] Generating Mapper Interface for table myshop..tb_content
[INFO] Generating SQL Map for table myshop..tb_content
[INFO] Generating Record class for table myshop..tb_order_item
[INFO] Generating Mapper Interface for table myshop..tb_order_item
[INFO] Generating SQL Map for table myshop..tb_order_item
[INFO] Generating Record class for table myshop..tb_item
[INFO] Generating Mapper Interface for table myshop..tb_item
[INFO] Generating SQL Map for table myshop..tb_item
[INFO] Generating Record class for table myshop..tb_item_desc
[INFO] Generating Mapper Interface for table myshop..tb_item_desc
[INFO] Generating SQL Map for table myshop..tb_item_desc
[INFO] Generating Record class for table myshop..tb_item_param
[INFO] Generating Mapper Interface for table myshop..tb_item_param
[INFO] Generating SQL Map for table myshop..tb_item_param
[INFO] Generating Record class for table myshop..tb_order_shipping
[INFO] Generating Mapper Interface for table myshop..tb_order_shipping
[INFO] Generating SQL Map for table myshop..tb_order_shipping
[INFO] Generating Record class for table myshop..tb_user
[INFO] Generating Mapper Interface for table myshop..tb_user
[INFO] Generating SQL Map for table myshop..tb_user
[INFO] Generating Record class for table myshop..tb_content_category
[INFO] Generating Mapper Interface for table myshop..tb_content_category
[INFO] Generating SQL Map for table myshop..tb_content_category
[INFO] Saving file TbItemParamItemMapper.xml
[INFO] Saving file TbItemCatMapper.xml
[INFO] Saving file TbOrderMapper.xml
[INFO] Saving file TbContentMapper.xml
[INFO] Saving file TbOrderItemMapper.xml
[INFO] Saving file TbItemMapper.xml
[INFO] Saving file TbItemDescMapper.xml
[INFO] Saving file TbItemParamMapper.xml
[INFO] Saving file TbOrderShippingMapper.xml
[INFO] Saving file TbUserMapper.xml
[INFO] Saving file TbContentCategoryMapper.xml
[INFO] Saving file TbItemParamItem.java
[INFO] Saving file TbItemParamItemMapper.java
[INFO] Saving file TbItemCat.java
[INFO] Saving file TbItemCatMapper.java
[INFO] Saving file TbOrder.java
[INFO] Saving file TbOrderMapper.java
[INFO] Saving file TbContent.java
[INFO] Saving file TbContentMapper.java
[INFO] Saving file TbOrderItem.java
[INFO] Saving file TbOrderItemMapper.java
[INFO] Saving file TbItem.java
[INFO] Saving file TbItemMapper.java
[INFO] Saving file TbItemDesc.java
[INFO] Saving file TbItemDescMapper.java
[INFO] Saving file TbItemParam.java
[INFO] Saving file TbItemParamMapper.java
[INFO] Saving file TbOrderShipping.java
[INFO] Saving file TbOrderShippingMapper.java
[INFO] Saving file TbUser.java
[INFO] Saving file TbUserMapper.java
[INFO] Saving file TbContentCategory.java
[INFO] Saving file TbContentCategoryMapper.java
[WARNING] Column id, specified as an identity column in table myshop..tb_order, does not exist in the table.
[WARNING] Column id, specified as an identity column in table myshop..tb_item_desc, does not exist in the table.
[WARNING] Column id, specified as an identity column in table myshop..tb_order_shipping, does not exist in the table.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.892 s
[INFO] Finished at: 2019-06-24T03:40:09+08:00
[INFO] Final Memory: 30M/634M
[INFO] ------------------------------------------------------------------------
Process finished with exit code 0
CRUD 案例
package com.funtl.hello.spring.boot;
import java.util.Date;
import com.funtl.hello.spring.boot.domain.TbUser;
import com.funtl.hello.spring.boot.mapper.TbUserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
@Rollback
public class HelloSpringBootApplicationTests {
/**
* 注入 DAO
*/
@Autowired
private TbUserMapper tbUserMapper;
/**
* 查询
*/
@Test
public void testSelectAll() {
List<TbUser> tbUsers = tbUserMapper.selectAll();
tbUsers.forEach(tbUser -> {
System.out.println(tbUser);
});
}
/**
* 条件查询
*/
@Test
public void testSelectCondition() {
Example example = new Example(TbUser.class);
example.createCriteria().andEqualTo("username", "zhangsan");
List<TbUser> tbUsers = tbUserMapper.selectByExample(example);
tbUsers.forEach(tbUser -> {
System.out.println(tbUser);
});
}
/**
* 新增
*/
@Test
public void testInsert() {
TbUser tbUser = new TbUser();
tbUser.setUsername("Lusifer");
tbUser.setPassword("123456");
tbUser.setPhone("15888888888");
tbUser.setEmail("topsale@vip.qq.com");
tbUser.setCreated(new Date());
tbUser.setUpdated(new Date());
tbUserMapper.insert(tbUser);
}
/**
* 更新
*/
@Test
public void testUpdate() {
TbUser tbUser = tbUserMapper.selectByPrimaryKey(37L);
tbUser.setUsername("Happy");
tbUserMapper.updateByPrimaryKey(tbUser);
}
/**
* 修改
*/
@Test
public void testDelete() {
tbUserMapper.deleteByPrimaryKey(37L);
}
/**
* 分页
*/
@Test
public void testPage() {
Example example = new Example(TbUser.class);
example.createCriteria().andLike("username", "z%");
PageHelper.startPage(1, 5);
PageInfo<TbUser> pageInfo = new PageInfo<>(tbUserMapper.selectByExample(example));
System.out.println(pageInfo.getTotal());
System.out.println(pageInfo.getPages());
pageInfo.getList().forEach(tbUser -> {
System.out.println(tbUser);
});
}
}
特别说明: 本人平时混迹于 B 站,不咋回复这里的评论,有问题可以到 B 站视频评论区留言找我
视频地址: https://space.bilibili.com/31137138/favlist?fid=326428938
课件说明: 本次提供的课件是 Spring Cloud Netflix 版微服务架构指南,如果有兴趣想要学习 Spring Cloud Alibaba 版,可以前往 http://www.qfdmy.com 查看相关课程资源
案例代码: https://github.com/topsale/hello-spring-cloud-netflix