Spring boot
第一章 概念
Spring Boot 特点 :自动配置、起步依赖和 Actuator 运行状态的监控。
第一章 建造工程
2.1. 起步依赖
spring-boot-starter-web Web功能的起步依赖
spring-boot-starter-test Spring Boot测试功能的起步依赖
spring-boot-devtools springloaded 热部署
spring-boot-starter-jdbc using JDBC with the HikariCP connection pool
spring-boot-starter-json reading and writing json
spring-boot-starter-websocket building WebSocket applications using Spring Framework’s WebSocket support
spring-boot-starter-web-services using Spring Web Services
2.2. 常用注解
@RestController 功能相当于@Controller 注解加上ResponseBody 注解
@RequestMapping 注解是 置请求地址的 Uri 射的
@RunWith(SpringRunner.class) Junit测试
@SpringBootTest Junit测试
@Configuration 声明配置类
@PropertySource("classpath:db.properties") 引用属性配置文件
@ConfigurationProperties(prefix = "mysql") 可以读取属性文件,prefix = "mysql" 声明其前缀
@Bean 声明Bean
2.3. Pom.xml
<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 https://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.3.1.RELEASE</version> </parent> <groupId>com.kai</groupId> <artifactId>springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.31</version> </dependency> <!-- 修改后立即生效,热部署 --> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
2.4. 启动程序
这个类是整个项目的启动入口
这个类最好放在整个package的根包中,因为扫描时是以这个类所在的package向下扫描,不在这个package中的controller等,需要重写@ComponentScan添加扫描package。
package cn.kai.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApplicationStart { public static void main(String[] args) throws Exception { SpringApplication.run(ApplicationStart.class, args); } }
2.5. @RestController 和@Controller的区别
@RestController注解相当于@ResponseBody + @Controller合在一起的作用。
1) @RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。
2) @Controller返回到return指定的页面,需要配合视图解析器InternalResourceViewResolver。
如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。
2.6. 案例controller
//@RestController声明控制类,并返回数据(json/xml)到页面 @RestController @EnableAutoConfiguration public class HelloController { @Autowired private DataSource dataSource; @RequestMapping("/") String home() { return "Hello World!"; }
第三章 配置文件读取
3.1. 配置文件引入
//@Configuration 声明配置类 //@PropertySource 引用属性配置文件 @Configuration @PropertySource("classpath:db.properties") public class DBConfig { //取属性文件属性值 @Value("${mysql.Driver}") String mysqlDriver; @Value("${mysql.url}") String mysqlUrl; @Value("${mysql.user}") String mysqlUser; @Value("${mysql.password}") String mysqlPassword; //@Bean生成Bean可以直接使用 @Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(mysqlDriver); dataSource.setUrl(mysqlUrl); dataSource.setUsername(mysqlUser); dataSource.setPassword(mysqlPassword); return dataSource; } }
3.2. 使用@ConfigurationProperties注入
3.2.1. 配置文件
//@ConfigurationProperties 可以读取名为: application.properties 属性文件 //prefix = "mysql" 声明其前缀 @ConfigurationProperties(prefix = "mysql") public class PropConfiguration { //定义的属性名需与application.properties文件中参数名一致 private String driverClassName; private String url; private String username; private String password; Geter,seter方法
3.2.2. 读取文件
1)
//@EnableConfigurationProperties enbale 配置文件类
@EnableConfigurationProperties(PropConfiguration.class)
@Bean
public DataSource dataSource(PropConfiguration prop) {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(prop.getDriverClassName());
dataSource.setUrl(prop.getUrl());
dataSource.setUsername(prop.getUsername());
dataSource.setPassword(prop.getPassword());
return dataSource;
}
2)
//属性注入
@Autowired
PropConfiguration propConfiguration;
3)
PropConfiguration propConfiguration;
//通过构造函数注入
public DBConfig(PropConfiguration propConfiguration) {
this.propConfiguration = propConfiguration;
}
3.3. 不使用属性文件类(PropConfiguration)
用@ConfigurationProperties直接注入
//不借助配置文件类,用@ConfigurationProperties直接注入
//自动判断dataSource需要的get属性,从文件中直接读取,配置文件属性名需要与dataSource的get属性名相同
@Bean
@ConfigurationProperties(prefix = "mysql")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
3.4. Yaml配置文件
配置文件除了application.properties,还可以使用后缀为:.yml或.yaml类型,既:
application.yml或application.yaml
YAML是一种简洁的非标记语言,YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读。
如果application.properties和YAML两个配置文件都有,springboot会把两个文件的配置合并,如果有重复属性,以application.properties中的为准。
mysql:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
username: root
password: xxxx
“:”后面必须要有空格
3.5. 自定义配置文件
3.6. 多个环境的配置文件
第四章 整合SpringMVC
虽然默认配置已经可以使用SpringMVC了,不过我们有时候需要进行自定义配置。
4.1. 修改服务器端口
#tomcat server信息
server:
port: 8080
servlet:
path: "*.action"
Controller访问
@RequestMapping("hello.action")
String home() {
return "Hello World!";
}
4.2. 访问静态资源
默认的静态资源路径为:
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public/
只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。
4.3. 日志打印
import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger log = LoggerFactory.getLogger(UserInterceptors.class);
如果使用lombok可以用@Slf4j代替log定义声明,使用时直接:log.debug();
Log等级定义
#日志信息
logging:
level:
cn.kai.springboot: debug
4.4. 拦截器
1.如果你想要保持Spring Boot 的一些默认MVC特征,同时又想自定义一些MVC配置(包括:拦截器,格式化器, 视图控制器、消息转换器 等等),你应该让一个类实现`WebMvcConfigurer`,并且添加`@Configuration`注解,但是**千万不要**加`@EnableWebMvc`注解。如果你想要自定义`HandlerMapping`、`HandlerAdapter`、`ExceptionResolver`等组件,你可以创建一个`WebMvcRegistrationsAdapter`实例 来提供以上组件。
2. 如果你想要完全自定义SpringMVC,不保留SpringBoot提供的一切特征,你可以自己定义类并且添加`@Configuration`注解和`@EnableWebMvc`注解
4.4.1. 自定义拦截器
public class UserInterceptors implements HandlerInterceptor{ 实现3个方法 }
4.4.2. 定义一个configuration类实现WebMvcConfigurer
对于拦截器需要重写addInterceptors方法去注册拦截器。 @Configuration public class MvcConfiguration implements WebMvcConfigurer{ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new UserInterceptors()).addPathPatterns("/**"); } }
第五章 整合jdbc和事务,连接池
5.1. SpringBoot提供jdbc的连接池
<-- 连接池--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
JDBC 连接池 HikariCP:
https://www.oschina.net/p/hikaricp
Spring boot:spring-boot-starter-jdbc自带了HikariCP连接池,不需要再引入,直接用:
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>1.3.5</version> <scope>compile</scope> </dependency>
5.2. mysql数据库驱动
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
5.3. 配置
HikariCP
#数据源配置 spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8 username: root password: xxxx hikari: idle-timeout: 60000 maximum-pool-size: 30 minimum-idle: 10
Druid连接池
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.6</version> </dependency>
#初始化连接数
spring.datasource.druid.initial-size=1
#最小空闲连接
spring.datasource.druid.min-idle=1
#最大活动连接
spring.datasource.druid.max-active=20
#获取连接时测试是否可用
spring.datasource.druid.test-on-borrow=true
#监控页面启动
spring.datasource.druid.stat-view-servlet.allow=true
5.4. 事务
SpringBoot中通过注解来控制。就是我们熟知的`@Transactional`
@Transactional public void insertUser(User user) throws Exception{
第六章 整合mybatis
6.1. Mybatis启动器
SpringBoot官方并没有提供Mybatis的启动器,不过Mybatis[官网](https://github.com/mybatis/spring-boot-starter)自己实现了:
<!--mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency>
6.2. 配置mapper接口
因为没有配置mapper接口的xml,因此我们需要给每一个Mapper接口添加`@Mapper`注解,才能被识别
import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper { }
配置mapper扫描器
import org.mybatis.spring.annotation.MapperScan; @SpringBootApplication @MapperScan("cn.kai.springboot.mapper") public class ApplicationStart {
6.3. 配置文件
#mybatis # mybatis 别名扫描 mybatis: type-aliases-package: cn.kai.springboot.pojo # mapper.xml文件位置 #mybatis: # mapper-locations: classpath:mappers/*.xml configuration: map-underscore-to-camel-case: true
第七章 通用mapper
使用了通用mapper可以使用其框架写好的增删改查等功能。
7.1. 通用Mapper启动器
<dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.0.2</version> </dependency>
配置了这个启动器,不需要再配:
spring-boot-starter-jdbc
mybatis-spring-boot-starter
Mybatis
mybatis-spring
spring-boot-starte
7.2. Mapper
需要继承tk.mybatis.mapper.common.Mapper
@Mapper public interface UserMapper extends tk.mybatis.mapper.common.Mapper<User>{ }
使用了通用mapper需要更换tk的mapper扫描器
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication @MapperScan("cn.kai.springboot.mapper") public class ApplicationStart {
7.3. pojo类需要指明表名和主键
//@Table指定数据库表名 @Table(name = "user") public class User{ //@Id指明主键 //@KeySql(useGeneratedKeys = true) 是否自增主键 @Id @KeySql(useGeneratedKeys = true) private int id;
第八章 运行状态监控Actuator
第九章 单元测试Junit test
9.1. 测试功能的起步依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency>
9.2. @RunWith 和 @SpringBootTest
需要加上@RunWith(SpringRunner.class)和@SpringBootTest
@RunWith(SpringRunner.class) @SpringBootTest class UserServiceImplTest { @Autowired private UserMapper userMapper; @Test void testGetUserById() { User user = userMapper.selectByPrimaryKey(29); System.out.println("user:"+user); } }
第十章 问题
10.1. 通用mapper调用selectByPrimaryKey时查不到数据
并且sql为:
SELECT username,sex,birthday,address FROM user WHERE username = ? AND sex = ? AND birthday = ? AND address = ?
测试代码:
User user = userMapper.selectByPrimaryKey(29);
System.out.println("user:"+user);
日志:
2020-06-29 23:15:56.390 DEBUG 9740 --- [ main] c.k.s.m.UserMapper.selectByPrimaryKey : ==> Preparing: SELECT username,sex,birthday,address FROM user WHERE username = ? AND sex = ? AND birthday = ? AND address = ?
2020-06-29 23:15:56.413 DEBUG 9740 --- [ main] c.k.s.m.UserMapper.selectByPrimaryKey : ==> Parameters: 29(Integer), 29(Integer), 29(Integer), 29(Integer)
2020-06-29 23:15:56.432 DEBUG 9740 --- [ main] c.k.s.m.UserMapper.selectByPrimaryKey : <== Total: 0
user:null
原因:
User中的主键定义为int了
private int id;
解决:
将id改为Long
private Long id;
10.2. Eclipse 中报missing node.js
错误:
解决:
将eclipse目录:
eclipse2020\plugins\org.eclipse.wildwebdeveloper_0.5.5.202002262342中内容删掉
10.3. 启动服务时错误
错误信息:
java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.20.jar:8.0.20]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.20.jar:8.0.20]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) ~[mysql-connector-java-8.0.20.jar:8.0.20]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) ~[mysql-connector-java-8.0.20.jar:8.0.20]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73) ~[mysql-connector-java-8.0.20.jar:8.0.20]
原因:
原因是当前使用的mysql版本6.0.6驱动过高,且没有配置过time_zone导致
解决办法:
配置url后加上:serverTimezone=UTC
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC