SpringBoot--springboot配置文件详解以及简易整合MyBatis
SpringBoot配置
要求:
-
学习配置文件的基本使用。
-
学习配置信息的书写以及获取。
application.properties
解析:在springboot项目中会自动生成application.properties配置文件,我么可以在其中配置一些信息,而且这个配置文件spring boot可以自动识别到。
springboot这个配置文件到底可以配置那些东西呢?
官方文档:
Common Application Properties
尝试修改配置文件
application.prperties
server.port= 9090server.servlet.context-path= /start
重启并测试:
SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的。
-
application.properties
-
-
语法结构 :key=value
-
properties只能保存键值对
-
-
application.yml
-
-
语法结构 :key:空格 value
-
配置文件的作用 :修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
yml配置文件与properties配置文件对比:
层次清晰:yml配置文件的层级表示更加的清晰,yml配置文件用换行加缩进的方式来表示层级,相同的层级只需要写一次,因为有了缩进,层级表示更加的明确。
关注数据: yml配置文件更关注数据,在properties配置文件层级占大部分的内容,而在yml配置文件中层级用更少的配置来表示清楚,表示清楚之后,可以更加关注我们究竟要配置的值或数据。
yml配置信息书写与获取
yml配置文件在实际开发中会有两种开发方式:
-
书写三方技术需要的配置信息:第三方例如:MyBatis,Redis,Mybatis-Plus等
以Redis为例,如果程序中要使用Redis,我们需要两个步骤
首先导入Redis的起步依赖,起步依赖引进来之后,Redis还会提供文档,来说明需要什么样的配置信息。
第二步,根据文档来编写配置信息。写好的配置信息在布置工程启动之后,起步依赖内部会自动的获取这些配置信息从而使用。
此种情况下,我们只需要编写配置信息,不需要获取配置信息,
-
书写自己程序需要的自定义配置信息。
在此种情况下,我们不仅要书写配置信息,还需要写代码来获取配置信息。
例如:在使用阿里云对象服务的时候,在Java代码中会有一些服务相关的配置信息,这些配置信息直接写在Java代码中是不合适的,如果这样书写的话,配置信息就和Java代码强耦合了,假如配置信息出问题了,我们就不得不修改Java代码,需要重新编译,重新测试,重新打包,重新部署,十分耗时。
在实际开发中,这样的配置信息都是将其提取到一个配置文件里边。这样与Java代码的耦合度就被降低了,当配置信息出现问题的时候,只需要去修改配置文件,再重启服务器即可。将配置信息写入配置文件之后,Java代码要去获取这些配置信息从而使用,
所以不仅要会编写配置信息,还需要会去获取配置信息。
代码展示:
// 发件人邮箱private String user = "2089371290@qq.com";// 发件人邮箱授权码 不是密码,是邮箱服务,专门为三方客户端准备的,一种用于身份验证的信息,需要自己去申请private String code = "cuknpqpsqlfrddeh";// 发件人邮箱对应的服务器域名,163邮箱为smtp.163.com 腾讯为smtp.qq.comprivate String host = "smtp.qq.com";// 身份验证开关: 在发送邮件之前,需不需要对发件人的信息进行验证// 如果为true,则发送邮件之前,需对发件人的信息进行验证,否则发送失败private boolean auth = true;
这些配置信息直接放在了Java代码中,与Java代码高耦合,在实际开发中不能这样使用,需要将这些配置信息抽取到一个配置文件中。
如果要将这些配置信息配置到properties配置文件中。
email.user=2089371290@qq.comemail.code=cuknpqpsqlfrddehemail.host=smtp.qq.comemail.auth=true
但现在springboot项目主要使用yml配置文件,所以接下来的重心是在如何书写并获取yml配置文件。
application.yml
email:user: 2089371290@qq.comcode: cuknpqpsqlfrddehhost: smtp.qq.comauth: true
如何书写yml配置文件
yaml概述
YAML
,全称是 YAML Ain’t Markup Language(YAML不是一种标记语言)。虽然名字带着“叛逆”色彩,但它确实是一种非常实用的 数据序列化格式。简单地说,它是用来让程序和人类交流的一种方式,常用于配置文件和数据交换。
以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml
传统xml配置:
<server><port>8081<port>
</server>
yaml配置:
server:prot: 8080
yaml语法
说明:语法要求严格!
1、值前面必须要有空格作为分隔符,空格不能省略
2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3、属性和值的大小写都是十分敏感的。
字面量:普通的值 [ 数字,布尔值,字符串 ]
字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;
k: v
注意:
-
“ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;
比如 :name: "kuang \n shen" 输出 :kuang 换行 shen
-
' ' 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出
比如 :name: ‘kuang \n shen’ 输出 :kuang \n shen
对象、Map(键值对)
#对象、Map格式
k: v1:v2:
在下一行来写对象的属性和值得关系,注意缩进;比如:
student:name: lycage: 20
行内写法
student: {name: lyc,age: 20}
数组( List、set )
用 - 值表示数组中的一个元素,比如:
person:- teacher- doctor- student
行内写法
person: [teacher,doctor,student]
修改SpringBoot的默认端口号
配置文件中添加,端口号的参数,就可以切换端口;
server:port: 8023
如何获取yml配置文件
-
使用@Value来获取配置文件中的信息
具体语法:
@Value(“${键名}”)
代码展示:
// 发件人邮箱@Value("${email.user}")private String user;// 发件人邮箱授权码 不是密码,是邮箱服务,专门为三方客户端准备的,一种用于身份验证的信息,需要自己去申请@Value("${email.code}")private String code ;// 发件人邮箱对应的服务器域名,163邮箱为smtp.163.com 腾讯为smtp.qq.com@Value("${email.host}")private String host ;// 身份验证开关: 在发送邮件之前,需不需要对发件人的信息进行验证// 如果为true,则发送邮件之前,需对发件人的信息进行验证,否则发送失败@Value("${email.auth}")private boolean auth;
测试:
成功,且控制台打印出了Email中的值。
证明这种获取yml配置文件是可取的,但是还是有些繁琐,我们需要在每个成员变量上加上注解,代码量也较多,且相同的内容写了多次。
springboot项目还提供了一种注解,也是springboot项目的强大之处。
-
@ConfigurationProperties(prefix = "前缀") :默认从全局配置文件中获取值;
前提:需要保证实体类中的前缀和配置文件中的前缀保持一致,且保证实体类中的成员变量名与配置文件中的键名保持一致
代码展示:
@Component@ConfigurationProperties(prefix = "email")public class EmailProperties {// 发件人邮箱//@Value("${email.user}")private String user;// 发件人邮箱授权码 不是密码,是邮箱服务,专门为三方客户端准备的,一种用于身份验证的信息,需要自己去申请//@Value("${email.code}")private String code ;// 发件人邮箱对应的服务器域名,163邮箱为smtp.163.com 腾讯为smtp.qq.com//@Value("${email.host}")private String host ;// 身份验证开关: 在发送邮件之前,需不需要对发件人的信息进行验证// 如果为true,则发送邮件之前,需对发件人的信息进行验证,否则发送失败//@Value("${email.auth}")private boolean auth;
测试:
成功.
@Value这个使用起来并不友好!我们需要为每个属性单独注解赋值,比较麻烦;
功能对比图
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SPEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
1、@ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加
2、松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。(了解即可)
3、JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性,规范输出内容的
就比如前端中的input类型是什么,内容就只能是什么类型的
<input type = "email"/>
在后端则是使用 @Validated springBoot2.3版本以上不支持数据验证
@Component@Validated//javaConfig 绑定我们配置文件的值,可以采取这种方式//加载指定的配置文件//@PropertySource(value = "classpath:lyc.properties")@ConfigurationProperties(prefix = "person")public class Person {@Email()//SPEL表达式取出配置文件的值private String name;private Integer age;private Boolean happy;private Date birth;private Map <String,Object> maps;private List<Object> lists;private Dog dog;
限制 | 说明 |
---|---|
@Null | 限制只能为null |
@NotNull | 限制必须不为null |
@AssertFalse | 限制必须为false |
@AssertTrue | 限制必须为true |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Future | 限制必须是一个将来的日期 |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Past | 限制必须是一个过去的日期 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 |
4、复杂类型封装,yml中可以封装对象 , 使用value就不支持
结论:
-
配置yml和配置properties都可以获取到值 , 强烈推荐 yml;
-
如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;
-
如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!
再次测试:
person:name: "John"age: 30happy: truebirth: 1976-04-08T09:30:00.000-05:00maps: {k1: v1,k2: v2}lists:- code- music- girldog:name: 小黑age: 2
@ConfigurationProperties(prefix = "person")public class Person {private String name;private Integer age;private Boolean happy;private Date birth;private Map <String,Object> maps;private List<Object> lists;private Dog dog;
测试
@AutowiredPerson person;@Testvoid contextLoads() {System.out.println(person);}
注意事项:
@ConfigurationProperties作用: 将配置文件中配置的每一个属性的值,映射到这个组件中; 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定 参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
加载指定的配置文件
@PropertySource(value = "classpath: 指定的配置文件")
1.先写一个配置类
name = lyc
2.然后在我们的代码中指定加载lyc.properties文件
@Component//javaConfig 绑定我们配置文件的值,可以采取这种方式//加载指定的配置文件@PropertySource(value = "classpath:lyc.properties")//@ConfigurationProperties(prefix = "person")public class Person {//SPEL表达式取出配置文件的值@Value("${name}")
测试
@AutowiredPerson person;@Testvoid contextLoads() {System.out.println(person);}
结果:
配置文件占位符
配置文件还可以编写占位符生成随机数
person:name: John${random.uuid} #随机IDage: ${random.int}happy: truebirth: 2000/01/01maps: {k1: v1,k2: v2}hello: worldlists:- code- music- girldog:name: ${person.hello:hello}_小黑age: 2
测试结果
springboot整合MyBatis
练习配置文件的使用,以及体验springboot项目提供的起步依赖的简洁以及自动配置的方便。
回顾:spring整合MyBatis
-
引入依赖(mybatis,spring-mybais等)
-
配置Bean对象,(SQLSessionFactory,MapperScannerConigure,DataSource等)
springboot整合MyBatis
-
引入MyBatis-spring-boot-starter起步依赖(相当于spring整合MyBatis时引入的所有依赖,并且将一些Bean对象自动的注入到IOC容器中)
-
配置application.yml中的指定数据库的配置(驱动以及连接、用户名、密码)
具体流程: 浏览器——》 Controller层——》Service层——》Mapper层——》数据库
前置条件:
设置数据库数据
create table if not exists user(`id` int unsigned auto_increment comment 'ID',`name` varchar(100) comment '姓名',`age` tinyint unsigned comment '年龄',`gender` tinyint unsigned comment '性别,取值1或2',`phone` varchar(11) comment '手机号',primary key (`id`))engine = innodb default charset = utf8mb4;
首先:引入MyBatis的起步依赖。
<!-- mybatis的起步依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!-- MySQL驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
编写配置文件application.yml
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTCusername: rootpassword: 211314
编写业务代码:
pojo层:
package com.lyc.springbootmybatis.pojo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublic class User {private Integer id;private String name;private Short age;private Short gender;private String phone;}
mapper层:
package com.lyc.springbootmybatis.mapper;import com.lyc.springbootmybatis.pojo.User;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Select;import java.util.ArrayList;import java.util.List;@Mapperpublic interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")User findById(Integer id);@Select("SELECT * FROM user")ArrayList<User> findAll();}
service层:
Userservice接口
package com.lyc.springbootmybatis.services;import com.lyc.springbootmybatis.pojo.User;import org.springframework.stereotype.Service;import java.util.ArrayList;public interface UserService {ArrayList<User> getAllUsers();User getUserById(Integer id);}
实现类:
package com.lyc.springbootmybatis.services.impl;import com.lyc.springbootmybatis.mapper.UserMapper;import com.lyc.springbootmybatis.pojo.User;import com.lyc.springbootmybatis.services.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.ArrayList;@Servicepublic class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic ArrayList<User> getAllUsers() {return userMapper.findAll();}@Overridepublic User getUserById(Integer id) {return userMapper.findById(id);}}
controller层:
package com.lyc.springbootmybatis.controller;import com.lyc.springbootmybatis.pojo.User;import com.lyc.springbootmybatis.services.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;@RestControllerpublic class UserController {@Autowiredprivate UserService userService;@RequestMapping("/findById")public User getUserById(Integer id){return userService.getUserById(id);}@RequestMapping("/findAll")public ArrayList<User> getAllUsers(){return userService.getAllUsers();}}
测试:
测试成功!
注意事项:MyBatis起步依赖版本与当下springboot版本不适配,需要使用3.0.3。
总结:在spring整合MyBatis时,我们不仅需要导入依赖,还需要编写配置文件中的Bean对象。十分繁琐
而在springboot整合MyBatis时,我们仅仅只是导入了MyBatis的起步依赖以及MySQL驱动,配置文件也仅仅只写了数据源,并且是系统自动导入的,因此,springboot项目的简洁不言而喻。
希望对大家有所帮助!