# SpringBootTutorial
**Repository Path**: ThroughFog/spring-boot-tutorial
## Basic Information
- **Project Name**: SpringBootTutorial
- **Description**: SpringBoot学习
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-04-27
- **Last Updated**: 2021-09-23
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
[TOC]
# SpringBoot
## 介绍
作用:Springboot是学习微服务框架的基石。
关系:SpringBoot是Spring的工具API框架
## 社区版idea安装插件
搜索`spring Assistant`,安装。
## pom.xml
`parent`标签
SpringBoot将现有的主流框架都进行了整合,在内部依据完成了jar包的依赖的配置,如果用户需要,则只添加某些核心包
那么所有的依赖都会按照规则自动地下载
`dependency`标签
通过启动项(就是starter)的方式,进行jar包文件加载,同时功能中的配置项,也会自动完成。
`build`标签
完成项目的打包、发布等的一系列的功能
`excludes`
在项目打包时,将这些包排除
`optional`标签
表示父子项目之间依赖不传递
## maven jar包依赖的传递性
例子:
1. A.jar ---> B.jar
2. B.jar ---> C.jar
仅需导A.jar即可
## 配置文件
### SpringBoot属性赋值
#### yml文件
1. 编辑配置文件
`application.yml`
```yaml
#定义dept属性值 YML文件默认支持UTF-8
Dept:
id: 101
name: test
```
2. 编辑实体类
`Dept`
```java
@Component
public class Dept {
@Value("${dept.id}")
private Integer id;
@Value("${dept.name}")
private String name;
//getter and setter and toString...
}
```
3. 测试
`test`
```java
@SpringBootTest //在执行测试方法时自动地启动Spring容器,并注入本类中带有@Autowired的属性
class SpringbootDemo1ApplicationTests {
@Autowired
private Dept dept;
@Test
void contextLoads() {
System.out.println(dept);
}
}
```
#### properties文件
`dept.properties`
```properties
dept.id2=110
dept.name2=springboot测试
```
`Dept`
```java
@PropertySource(value = "classpath:/dept.properties",encoding = "UTF-8")
@Data
public class Dept {
@Value("${dept.id2}")
private Integer id2;
@Value("${dept.name2}")
private String name2;
}
```
## lombok插件
`@Data`:自动生成`get`、`set`、`toString`方法
`@Accessors(chain=true)`:重写set方法,返回this对象。然后就可以使用链式调用
`@NoArgsConstructor`:无参构造
`@AllArgsConstructor`:全参构造
## 配置多环境
要求:多环境中每个数据项都应该保持一致。
关键语法:`---`表示环境的分割
规则:每个环境最好有自己的名称。如下代码块定义了一个`test`环境
```yaml
spring:
config:
activate:
on-profile: test
```
指定默认环境配置名称
```yaml
#默认环境选项,指定默认启动的环境项
spring:
config:
activate: prod
---
```
## 热部署
`依赖`
```xml
org.springframework.boot
spring-boot-devtools
```
#### idea环境配置
快捷键:ctrl + alt + shift + /
点击注册
给`complier.automake.allow.when.app.running`打勾
`settings`
将`Compiler`下的`Build project automatically`、`Compile independent moduled in paraller`勾上
## 整合Mybatis
### 导包
```xml
mysql
mysql-connector-java
runtime
8.0.23
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.4
```
### url参数
* autoReconnect `boolean` 是否自动重连
* serverTimeZone `Aisa/ShangHai` `GMT%2B8` 时区
* allowMultiQueries `boolean` 是否允许批量操作
* useUnicode `boolean` 是否使用Unicode编码
`application.yml`
```yaml
spring:
datasource:
username: root
url: jdbc:mysql://localhost:3306/jtadmin?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
password: root
mybatis:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:/mybatis/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
```
### mapper接口动态代理过程
查看注入的mapper属性的类
```java
@Test
void lookProxy() {
System.out.println(demoUserMapper.getClass());
}
```
`class com.sun.proxy.$Proxy69`
传入配置文件,根据配置文件信息实例化接口并创建代理。
* SqlSessionFactory包装了JDBC
* SqlSession持有jdbc-conn
* SqlSession操作数据库,执行SQL语句
## 整合Mybatis-plus
### 注解
`@TableName`:将对象与表绑定。如果没有添加注解的属性值,默认以类名当作表名进行查询。缺省优化
`@TableId`:绑定主键。缺省优化
* type 主键类型
* NONE 默认
* AUTO 自增
* ASSIGN_UUID 分配一个32位的UUID
`@TableField`:其他字段名。缺省优化
* value 数据库字段名
* exist 是否是数据库表字段。可以将表中没有的属性设为`false`
### 接口
继承MP写好的`BaseMapper`,泛型写实体类名。这个Mapper事先写好了基本的单表CRUD操作。
### YML配置文件
说明:MP包含了M。故不再使用Mybatis依赖。
将原来`mybatis`的配置项改为`mybatis-plus`即可将所有配置项继承过来。
```yaml
mybatis-plus:
type-aliases-package: com.jt.pojo
mapper-locations: classpath:mybatis/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
```
### 流程
1. 根据userMapper属性找到对应的class类型
2. 根据类型通过反射获取父级接口类型BaseMapper
3. 获取接口类型的泛型`DemoUser.class`
4. 根据`DemoUser.class`获取里面的注解,(获取主键名称),就得到了表名
5. 如上获取属性名。
6. 利用这个对象的`get`方法获取属性值,拼接`sql`
7. MP将拼接好的`sql`交给`mybatis(jdbc)`处理。
### MP的CURD
* 增加
```java
/**
* 插入元组
*/
@Test
public void TestInsert(){
DemoUser user = new DemoUser();
user.setName("MP测试").setSex("男").setAge(19);
userMapper.insert(user);
}
```
* 修改
**原则**:根据对象中不为null的属性当作set条件(动态sql)。如果是ById的操作,id必须赋值,并且Id当作唯一where条件
```java
/**
* 根据ID修改元组
* 修改id=231的数据name="Jack" age=18
*/
@Test
public void TestUpdate(){
DemoUser user = new DemoUser();
user.setName("MP测试").setSex("男").setAge(19);
userMapper.updateById()
}
```
* ById查询
```java
/**
* 查询id=21的用户
*/
@Test
public void TestSelectById(){
DemoUser user = userMapper.selectById(21);
System.out.println("user = " + user);
}
```
> QueryWrapper对象——条件构造器
>
> 用于拼接where条件
>
> 原则:拼接对象中不为空的属性充当where条件
>
> 使用:
>
> new对象,泛型为要查询的实体类,参数为实例化的对象
>
> ```
> QueryWrapper wrapper = new QueryWrapper<>(user1);
> ```
* ByWrapper查询等于
```java
System.out.println("-----SelectByWrapper-----");
DemoUser user1 = new DemoUser();
user1.setName("白骨精").setSex("女");
QueryWrapper wrapper = new QueryWrapper<>(user1);
List list = userMapper.selectList(wrapper);
System.out.println("list = " + list);
```
* ByWrapper其他运算符
> 特殊字符方法:
>
> 大于——gt 等于——eq
>
> 小于——lt 大于等于——ge
>
> 小于等于——le
>
> 连点方法自动将where条件拼起来,默认and。若为or,则接上一个`or()`方法
```java
@Test
public void TestSelectByWrapper(){
System.out.println("-----selectByWrapper-----");
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age", 18)
.eq("sex", "女");
userMapper.selectList(queryWrapper);
}
```
* like关键字
> like:前后都有百分号
>
> likeLeft:百分号位置靠左
> likeRight:百分号位置靠右
```java
@Test
public void TestSelectLike(){
System.out.println("-----selectLike-----");
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "精");
List users = userMapper.selectList(queryWrapper);
System.out.println("users = " + users);
}
```
* orderByDesc 降序
```java
/**
* sex=男
* 降序
*/
@Test
public void TestOderBy(){
System.out.println("-----selectLike-----");
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("sex", "男")
.orderByDesc("id");
List users = userMapper.selectList(queryWrapper);
System.out.println("users = " + users);
}
```
* In
**注意:传入数组时需要转化为集合,且数组使用包装类型**
`Integer[] ids = {1,3,5,6,7};`
`Arrays.asList(ids);`
```java
@Test
public void TestIn(){
System.out.println("-----selectIn-----");
Integer[] ids = {1,3,5,6,7};
//传入数组时需要转化为具体的集合
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", Arrays.asList(ids));
List users = userMapper.selectList(queryWrapper);
for (DemoUser user : users) {
System.out.println("user = " + user);
}
}
```
> condition:内部编辑一个判断的条件
> 如果返回值为true,则拼接该字段
> 若为false,则不拼接
>
> ```
> StringUtils.hasLength(name)
> ```
* SelectByDynamic
```java
/**
* 查询name=xxx and sex > xxx,当属性为空,要求动态生成sql
*/
@Test
public void TestDynamic(){
System.out.println("-----selectDynamic-----");
String name = "";
int age = 18;
//传入数组时需要转化为具体的集合
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq(name!=null || "".equals(name), "name", name)
.gt(age>0, "age",age);
List users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
```
* SelectObjs 只返回第一个字段
```java
/**
* 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
* 应用:可以根据条件查询Id的值,查询之后为后续的Sql提供数据支持
*/
@Test
public void TestSelectObjs(){
System.out.println("-----selectObjs-----");
List