SpringBoot 学习记录 2021.05.13 Started
环境搭建 Spring Boot 2.x
Java JDK
需要安装 JDK java8 也就是 1.8, 用 jdk-8u271-windows-x64.exe
网上有很多安装java8的教程,很简单。我已经安装完了。注意配置环境变量。
C:\Users\Reciter>java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
Maven 的安装和配置
Maven3的压缩包 找同事要一个,解压到本地,记得设置环境变量。网上有很多教程,也不做介绍了。
$ mvn -v
Apache Maven 3.1.1 (0728685237757ffbf44136acec0402957f723d9a; 2013-09-17 23:22:22+0800)
Maven home: E:\myHome\epan\javaz\maven\maven3
Java version: 1.8.0_211, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.8.0_211\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
记得添加 maven3的阿里镜像
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
IDEA 的安装
这个天天用,网上都有安装教程,就略过了。
配置 IDEA 的 Maven 环境
settings 搜 maven 在Build Tools下面有个Maven,将 Maven home directory 设置成 自己的maven目录。
Spring Boot 项目创建
创建项目
file - new - project...
选择 Spring Initializr 选择个 java web
注意java sdk 改成8
从新设置idea maven库的地址
创建完 就打开项目了,发现了一个问题,之前设置的maven 的库的地址是上个项目的,这个项目需要从新设置,要不maven的依赖库就会又从新下一遍,下载到 idea的maven库里。
端口 8080 冲突
\src\main\resources\application.yml 文件 配置
server:
port: 9443
项目启动成功
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
2021-05-13 11:20:20.289 INFO 19688 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 1.8.0_211 on LAPTOP-LAD2S0RU with PID 19688 (C:\Users\Reciter\Desktop\springBootStudy2021\target\classes started by Reciter in C:\Users\Reciter\Desktop\springBootStudy2021)
2021-05-13 11:20:20.291 INFO 19688 --- [ main] com.example.demo.DemoApplication : The following profiles are active: prod
2021-05-13 11:20:20.778 INFO 19688 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9443 (http)
2021-05-13 11:20:20.783 INFO 19688 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-05-13 11:20:20.783 INFO 19688 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.45]
2021-05-13 11:20:20.835 INFO 19688 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-05-13 11:20:20.835 INFO 19688 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 511 ms
2021-05-13 11:20:20.932 INFO 19688 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-05-13 11:20:21.020 INFO 19688 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9443 (http) with context path ''
2021-05-13 11:20:21.026 INFO 19688 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.029 seconds (JVM running for 1.625)
访问 http://127.0.0.1:9443/
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu May 13 16:21:55 CST 2021
There was an unexpected error (type=Not Found, status=404).
这是java的404页面,还没有接口页面
创建 controller/HelloController
HelloController.class
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@GetMapping("/hello")1. 1.
@ResponseBody
public String hello() {
return "hello,spring boot!";
}
}
访问: http://127.0.0.1:9443/hello
hello,spring boot!
SpringBoot 链接 mysql
思路整理:
- pom.xml 相当于前台的 webpack.json 主要作用是 引用了哪些第三方库,一般库的存放就在maven里面,idea不设置,就会在自己的库里,每次新项目都要从新设置maven库。
- application.properties 或者 application.yml 项目的属性配置文件,格式不一样,一个是
spring.datasource.username=root
另一个是 YAML 格式,就是tab 缩进,和python格式一样 - Controller层 用于调用,可以调用 Service层 或 DAO层
- DAO层,是个接口,用于定义都有哪些方法
- Entity层,实体层,用于定义对象都有哪些属性或者说字段
- Mapper层,补充DAO层,是个XML文件,里面是Sql语句
- Service层 调用DAO层,或者它本身就是接口
- Impl层 实现Service层接口
- 调用链:pom.xml -> application.yml -> DemoApplication -> Controller层 -> Service层(可跳过)-> DAO(Mapper补充) -> Entity层
几个重点问题
- pom.xml 添加 mybatis支持 添加3个 mybatis jdbc mysql
- mybatis 数据的抽象类,通用类
- jdbc 各种数据接口的大集合
- mysql 是某一种数据的具体操作方式
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 引入 MyBatis 场景启动器,包含其自动配置类及 MyBatis 3 相关依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
- 添加 lombok 方便定义实体类
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
- mysql数据库配置 放在 application.yml
spring:
datasource:
name: java-study-datasoure
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/javadbweb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowMultiQueries=true&useAffectedRows=true
username: root
password: 123456
绝对路径的概念
package com.example.demo;
每一个文件,都会有一个所谓位置的概念,对于每个项目的根来来说,它是有3个段落组成,然后由‘点’进行拼接,我这里的项目的根就是 com.example.demo,这里应该是为了网络上所有人发布包的根节点都不同,不会产生冲突,比如里面有公司名称,或者功能名称,项目名称等等,再进行拼接,就会得到一个绝对的根路径。然后所有的类在此根路径下,继续进行延展。
比如mapper文件就会对说明是附加到某个DAO上,这个时候,就会写上那个DAO的绝对路径。(不知道有没有相对路径概念)
文件目录
DemoApplication 分析
@SpringBootApplication 注解 说明是从这个类开始,也就是程序的起点
说下 import 这个关键字
import com.example.demo.service.HelloService === import HelloService from com.example.demo.service.HelloService
我这里有个小bug,就是我的实体类里面创建的JavaTest类,直接引用不好使,最后没办法,换成.*引用的了
HelloController 分析
- @Controller 注解 说明当前类是 Controller层
- @GetMapping 注解 说明当前方法是get方法,参数是访问的url
- @ResponseBody 注解 说明return回去的内容是展示内容
- @Autowired 注解是 自动装配,或者说动态注入,具体我还没分析,请自行找资料看。
JavaTestMapper 分析
- @Mapper 注解 说明这个接口是mapper
- 里面定义里一个 getJDBCValue 接口
HelloServiceImpl 分析
- @Service 注解 说明是一个 Service层
- implements 说明是继承的哪个接口 这里是继承的 HelloService接口
- @Override 注解 说明是覆盖覆写某个函数方法
HelloService 分析
- interface 说明当前是接口
很重要的mapper 分析
- namespace 说明这个mapper 他在哪 他是谁的归属,写那个接口文件的绝对路径
- id 说明这个函数的名称是什么
- resultType 说明 返回的实体类型
select * from java_test
是sql语句
application.yml 解析
spring:
datasource:
name: java-study-datasoure
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/javadbweb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowMultiQueries=true&useAffectedRows=true
username: root
password: 123456
mybatis:
mapper-locations: classpath*:mapper/*.xml
server:
port: 9443
- 这里注意 classpath是特指 resources 目录
pom.xml 没有解析,自己看吧
<?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 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.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 引入 MyBatis 场景启动器,包含其自动配置类及 MyBatis 3 相关依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
接口调用 postman,可以跳过登录,先用
下一阶段目标,从新梳理上述知识点
注解 都是基于 接口
注解 到 到类,类就一定要实现一个接口,因为注解最后要找到对应接口
@Autowired 自动装配
@Autowired
BannerService bannerService;
两种自动装配
- 接口 对应 有实现类,整好一个,就自动匹配,然后new完,注入回来
- 接口 对应 mapper的xml,我的理解就是xml就是接口的实现,然后new完,注入回来
总体上都省了一个new
@Autowired 是SpringBoot架构里的
@Resource 是Java架构里的。
@Resource和@Autowired注解都是用来实现依赖注入的。只是@AutoWried按by type自动注入,而@Resource默认按byName自动注入
@RestController
- @RestController = @Controller + @ResponseBody
- @Controller 是说你是控制层 接收url的,可以是 get post 等等
- @ResponseBody 是说 你方法里面 return 直接就返回到了接口层
@RequestMapping
@RequestMapping("${process.apiPath}/main/")
是告诉这个类 接收映射的基础url 应该都放在Controller层
@GetMapping
@GetMapping("getBanner")
是在方法上,告诉方法 接收的是get 地址是 基础url拼上这个字符串
ReturnMessage && ReturnFactory.success
@GetMapping("getBanner")
public ReturnMessage getBanner(){
List<BannerModel> bannerModelList = bannerService.getBannerMessage();
return ReturnFactory.success(bannerModelList);
}
ReturnMessage 就是返回的一个接口数据格式 有 data status msg
ReturnFactory.success 这个函数就是返回的 ReturnMessage 格式,将status=20 msg='ok' data=入参
接口 反射到 Impl实现类 Ctrl+T
点在函数名上,然后Ctrl+T 就跳转到 那个类实现了这个方法
MyBatis插件 接口反射到Mapper实现类
装个插件 叫 Free MyBatis plugin
安装完以后,左侧有箭头,点击进入xml的mapper,ctrl点击函数名,显示谁引入这个接口了。
Model的分析
这是另一种方案的Model,主要分析下这里的注解作用
@Data / lombok.Data
这里的 @Data 不等于 Spring Data,是两个东西。
看了好几圈,忽然反应过来,这个@Data是lombok的,作用的为了不写get set,省事用的。
- @Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集
@Accessors / lombok.experimental.Accessors
Accessor的中文含义是存取器,@Accessors用于配置getter和setter方法的生成结果
chain的中文含义是链式的,设置为true,则setter方法返回当前对象。
@Data
@Accessors(chain = true)
public class User {
private Long id;
private String name;
// 生成的setter方法如下,方法体略
public User setId(Long id) {}
public User setName(String name) {}
}
这个风格 用的话就是 u.id u.setId(1) setId返回的是对象
@NoArgsConstructor / lombok.NoArgsConstructor
@NoArgsConstructor : 生成一个无参数的构造方法
@AllArgsConstructor / lombok.AllArgsConstructor
添加一个构造函数,该构造函数含有所有已声明字段属性参数
@Table / javax.persistence.Table
@Table(name = "shop_center_pic") 声明此对象映射到数据库的数据表,通过它可以为实体指定表(Table)
@Column / javax.persistence.Column
@Column(name = "banner_pic") 注解 用来标识实体类中属性与数据表中字段的对应关系
@EqualsAndHashCode / lombok.EqualsAndHashCode
@EqualsAndHashCode(callSuper=false) 注解 附写 Equals 和 HashCode 这两个方法
话说 @Data注解里面 包含 @EqualsAndHashCode 注解了。
自己写个注解玩玩吗? 》 Annotation 注解快速入门
https://www.cnblogs.com/Qi1007/p/9768631.html
浅谈mybatis和jpa的区别
https://www.jianshu.com/p/32ce87c163d6
先有的 jpa(单表快) 后有的 mybatis (mapper)
两个都要学 都要会,jpa 和 mybatis 现在都有 代码生成器了。
挖坑 jsp 和 jpa 后期学
先把 mybatis 完成闭环后,再说,不能在最开始学的时候进行分散
Mapper Xml 位置更改到 Mapper接口的目录
pom.xml 文件里面 build下面加
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
application.yml里面的这个mapper-locations 没有用,开始一直以为有用了,耽误了一些时间
mybatis:
mapper-locations: classpath*:mapper/*.xml
@RequestParam get接参数
public List<OwnEntity> own (@RequestParam(required = true) String paramA) {
return ownService.getOwnList();
}
http://localhost:9443/own?paramA=1
可以进行调用,这里是必填参数
将参数传递到 mapper
参数paramA 先到 Controller层,然后 Service层,然后mapper 然后mapper.xml 然后 sql里面判断
-
步骤一 Controller层
-
步骤二 Service层
-
步骤三 Service层impl实现
-
步骤四 Mapper层
-
步骤五 Mapper层的impl实现
mapper xml里面 可以加
<if test="userType != null">
AND rep.user_type = #{userType}
</if>
mybatis官方中文文档 - 动态sql - 百度自行搜索
搜索接口 插件 restService
- 正常搜接口,因为是拼装的字符串,所以直接全局搜索,是搜不到的
- 当然,你也可以一个关键字,一个关键字的搜
参数的接收问题 重要!
- 接收一个参数的过程需要4个步骤,如果参数是50个的话,那就得给自己写死了,还不算后期添加修改参数。
- 解决方案1:将入参在Controller层,封装成Map
Map<String, Object> params = new HashMap<>(16);
params.put("youKeyName", "0");
- 解决方案2:将入参传入一个实体类,这样就自动映射这个实体类了
@PostMapping("/saveOrUpdate")
public ReturnMessage saveOrUpdate(MyModel myModel) throws Exception {
- 解决方案3:传入参数 和 实体类,两种一起用,最后再合并参数
params.putAll(yourModel.init())
新篇章
安装idea2019 之前2018和同事版本不一样
忽然发现,很多问题,版本2018和2019 不太一样,所以更新下2019
安装后,Maven问题
开始先改成了本地Maven库,但是有一些私有库,下不下来,因为自己的Maven3库,都是阿里源的,然后又改回了idea的maven库
有爆红的方法
等于是 全新的idea2019,所以lombok插件没有安装
又把常用的3个插件安装下:lombok、Free Mybatis plugin、Show REST Services 这三个plugins
RestfulToolkit 搜索Controller的插件
之前装的 Show REST Services 不好使,新装的这个好使。
最大端口为 65536
一个IP地址的端口可以有65536(2^16)个
添加 ReturnMessage类
这里是接口返回的数据格式
package com.example.demo.common.message;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ReturnMessage{
private int status;
private Object data;
private String msg;
}
添加 ReturnFactory类
这里是用ReturnMessage类型返回对象
package com.example.demo.common.message;
public class ReturnFactory {
public static ReturnMessage success(Object data) {
return new ReturnMessage(200, data, "ok");
}
}
添加 good 接口
@GetMapping("/good")
@ResponseBody
public ReturnMessage good () {
// return ReturnFactory.success("chenggong");
Map<String, Object> k = new HashMap<>(16);
k.put("kkk","kkjjlj");
return ReturnFactory.success(k);
}
接口动态获取参数,传什么,接什么
@GetMapping("/getMap")
@ResponseBody
public ReturnMessage getMap (@RequestParam(required = true) Map<String, String> Params) {
return ReturnFactory.success(Params);
}
待更新。。。
生活的意义就是你自己知道你要做什么,明确目标。没有目标,后面都是瞎扯!
https://pengchenggang.gitee.io/navigator/
SMART原则:
目标必须是具体的(Specific)
目标必须是可以衡量的(Measurable)
目标必须是可以达到的(Attainable)
目标必须和其他目标具有相关性(Relevant)
目标必须具有明确的截止期限(Time-based)