spring-boot学习笔记1
spring-boot教程:
1.启动方式:
spring-boot方式启动:
1.1 通过ide启动
点击xxxApplication.java文件 -->运行
1.2 通过mvn启动:
进入到项目根目录
mvn spring-boot:run
1.3 项目部署时:
-
mvn 打包
mvn clean package
-
在target目录下会多出一个文件jar文件,通过以下方式运行
java -jar target/xxx.jar
2. 配置属性:
2.1 application.properties
修改 mian/resource/application.properties
application.properties文件:
参数说明:
server.port=8081 //设置端口号
server.servlet.context-path=/demo/ // 请求时需要新增的路由,比如原来localhost:8081,增加此配置后,访问必须是localhost:8081/demo
application.yml文件(使用这个配置文件):
参数说明:
server:
port: 8081
servlet:
context-path: /demo/
2.2 自定义配置:
application.yml
server:
port: 8081
servlet:
context-path: /demo/
minMoney: 1 # 这里是自定义的配置
代码中使用
@Value("${minMonney}")
private BigDecimal money
@value会自动注入到Bean中,这是一个spring的注解,具体说明可以看下面跳转这里
2.3 配置里面引用另一个配置:
application.yml:
minMoney: 1
description: 最少发${minMoney}元
2.4 具有层级关系的配置:
limit:
minMoney: 1
description: 最少发${limit.minMoney}元
上面的二级属性配置是无法通过@Value直接读取的
下面是读取的方案:
首先创建一个limit对象,将limit下面的属性配置,都作为这个对象的私有域
LimitConfig.java
@Component
@ConfigurationProperties(prefix = "limit")
public class LimitConfig {
private BigDecimal minMoney;
private String description;
public BigDecimal getMinMoney() {
return minMoney;
}
public void setMinMoney(BigDecimal minMoney) {
this.minMoney = minMoney;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
使用上述定义好的配置:
@RestController
public class Hello {
@Autowired
private LimitConfig config;
@GetMapping("/say")
public String say(){
return config.getMinMoney()+"-"+config.getDescription();
}
}
@Autowired: 是自动注入的意思,他会总ioc容器中找到提前实例化的对象,并将其取出,赋值
autowired 标注在哪里就相当于告诉spring,这里依赖一个对象,需要交由springIoc 去实例化,然后注入
@Autowired 如果使用在属性上,会直接实例化,如果使用在方法上,会实例化依赖的参数对象,然后执行一遍方法.
2.5 划分生产和测试环境
创建application-dev.yml文件和application-prod.yml文件
现在 有三个配置文件,appLication.ym 里面决定引用哪一个可配置文件生产还是测试
清空appliation.yml,并写入下面的配置
spring:
profiles:
active: dev
##下面是公共部分,所以一也放到这里了
server:
port: 8081
servlet:
context-path: /demo
application-dev.yml
limit:
minMoney: 0.01
maxMoney: 0.02
description: 最少发${limit.minMoney}元,最多${limit.maxMoney}元
application-prod.yml
limit:
minMoney: 1
maxMoney: 999
description: 最少发${limit.minMoney}元,最多${limit.maxMoney}元
在上线的时候如何切换正式和测试:
mvn clean package
java -jar -Dspring.profiles.active=prod target\xxxxx-SNAPSHOT.jar
通过参数-Dspring.profile.active 指定运行的配置
3.controller的使用
三个注解:
@controller | 处理http请求 |
---|---|
@RestController | Spring4后的新注解,原来返回json,需要@ResponseBody和@controller配合 |
@RequestMapping | 配置url映射 |
3.1 @Controller
如果想使用这个注解并想返回信息的话,需要一个依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
在resource下的template里新建index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>this is test1</h1>
</body>
</html>
下面是java中的使用
@Controller
public class Hello {
@Autowired
private LimitConfig config;
@GetMapping("/say")
public String say(){
return "index";
}
}
不使用模板的话,@controller注解的类是无法返回字符串的,如果想返回字符串,需要配合@ResponseBody注解
@Controller
@ResponseBody
public class Hello {
@Autowired
private LimitConfig config;
@GetMapping("/say")
public String say(){
return config.getMinMoney()+"-"+config.getDescription();
}
}
@Controller+@ResponseBody = @RestController
3.1.1 同一方法映射多个路由
@GetMapping({"/say","/hi"})
public String say(){
return config.getMinMoney()+"-"+config.getDescription();
}
3.1.2 返回网页和字符串
3.1.3 抽离出公共的路由部分
场景:
@RestController
public class Hello {
@Autowired
private LimitConfig config;
@GetMapping("/hello/say")
public String say(){
return config.getMinMoney()+"-"+config.getDescription();
}
@GetMapping("/hello/eat")
public String eat(){
return "吃苹果";
}
}
因为他们同属于一个controller,所以在构建路由的时候有了公共的/hello部分,如何抽离出公共的/hello
部分:
使用注解@RequestMapping("公共路由部分")
@RequestMapping("/hello")
public class Hello {
@Autowired
private LimitConfig config;
@GetMapping("/say")
public String say(){
return config.getMinMoney()+"-"+config.getDescription();
}
@GetMapping("/eat")
public String eat(){
return "吃苹果";
}
}
3.1.4 post方式
@PostMapping("/eat")
public String eat(){
return "吃苹果";
}
3.1.5 任何方式都可以
@RequestMapping("/eat")
public String eat(){
return "吃苹果";
}
3.2 获取参数
@PathVariable | 获取url中的数据 |
---|---|
@RequestParam | 获取请求参数的值 |
3.2.1 从url获取参数
请求实例:
localhost:8081/
通过@PathVariable获取
@GetMapping("/say/{id}/haha")
public String say(@PathVariable("id") Integer id){
return "请求id"+id;
}
3.2.2 通过传参的方式获取
3.3 spring-boot的热部署:
3.3.1 pom.xml 中增加依赖
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
...
<build>
<plugins>
...
<plugin>
<!--热部署配置-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork:如果没有该项配置,整个devtools不会起作用-->
<fork>true</fork>
</configuration>
</plugin>
...
</plugins>
</build>
3.3.2idea中设置:
File-->setting-->Buid,Execution,Development-->complier-->勾选build project automaticlly
ctrl+alt+shift+/ 选择 Registery -->勾选complier.automake.allow.when.app.running
4. 操作数据库:
4.1 spirng-data-jpa
jpa是一套接口规范,不负责具体实现,spring-data-jpa实现的产品有hibernate,toplink等
4.1.2 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependecy>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependecy>
4.1.2 读取配置文件
application.yml 文件中的配置文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/luckmoney
username: root
password: root
jpa:
hibernate:
ddl-auto: create
show-sql: true
4.2 创建表结构:
创建表相关的一些注解
1. @Entity :表明是一个实体类
2. @Table :对应的数据表名
3. @Id :主键
4. @GeneratedValue:主键生成策略
5. @Column : 映射表对应的字段名
6. @Basic : 表示该属性是表字段的映射。 如果实体的字段上没有任何注解默认就是@Basic
7. @Transient : 表示该属性不是表字段的映射
8. @Lob : 将属性映射成支持的大对象类型 ,如Clob、Blob
9. @IdClass 联合主键,一般不用也不推荐用
10. @Temporal : 用来设置Date类型的属性映射到对应精度的字段
创建实例表:
package com.springboot.learn2hours;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.math.BigDecimal;
@Entity
public class LuckyMoney {
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Id
@GeneratedValue
private Integer id;
private BigDecimal money;
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
}
创建表结构的时候,ddl-auto: create
,等创建完以后,需要将其改为ddl-auto: update
4.3 CURD基本操作
4.3.1 获取列表页
需要从数据库查出数据,所以需要一个dao,一个接口
package com.springboot.learn2hours;
import org.springframework.data.jpa.repository.JpaRepository;
public interface LuckyMoneyRepository extends JpaRepository<LuckyMoney,Integer> {
}
需要继承jpaRepository 第一个参数是实体类,第二个参数是id的类型
4.3.2 创建restful接口
package com.springboot.learn2hours;
import org.springframework.beans.factory.annotation.Autowired;
public class LuckyMoneyController {
@Autowired
private LuckyMoneyRepository repository;
}
repository是连接数据库的抽象接口,根据依赖倒转原则可以在使用的时候使用具体的类.
对上面的代码增加访问的api
package com.springboot.learn2hours;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class LuckyMoneyController {
@Autowired
private LuckyMoneyRepository repository;
@GetMapping("luckyMoney")
public List<LuckyMoney> list(){
return repository.findAll();
}
}
创建:
@PostMapping("/luckMoney")
public LuckyMoney create(@RequestParam("producer") String producer,
@RequestParam("consumer") String consumer){
LuckyMoney luckmoney = new LuckyMoney();
luckmoney.setProducer(producer);
luckmoney.setConsumer(consumer);
return repository.save(luckmoney);
}
4.4 java的项目分层:
- DAO (Data access object): 数据访问层(接口)
- DAOImpl: DAO层的数据实现
- Entity: 数据对象的实体(php中叫model)
- Service : 中间层,业务逻辑层
- ServiceImpl: service的实现类
- Utils : 常用的自定义工具
- Controller: 处理web请求
tip: 知识补充
@Value() 用于注入一个值到bean中
通过这个注解注入值有两种情况
-
不通过配置文件注入值
@Value("normal") private String nomal;// 注入普通的字符串
@Value("#{systemProperties['os.name']}") private String systemPropertiesName; //注入系统属性
@Value("#{T(java.lang.Math.random()* 100.0)") private double randomNumber;// 注入表达式
@Value("#{beanInject.another}") private String fromAnotherBean; //注入其他对象的属性(这里是beanINject对象的another属性)
-
通过配置文件注入值
通过配置文件注入属性值的方式有两种:
-
spring-boot中的application.properties/yml文件 在spring-boot启动时自动加载进去
-
自定义属性文件:
自定义属性文件配置通过@PropertySource加载
@Component // 引入外部配置文件组:${app.configinject}的值来自config.properties。 // 如果相同 @PropertySource({"classpath:com/hry/spring/configinject/config.properties", "classpath:com/hry/spring/configinject/config_${anotherfile.configinject}.properties"}) public class ConfigurationFileInject{ @Value("${app.name}") private String appName; // 这里的值来自application.properties,spring boot启动时默认加载此文件 @Value("${book.name}") private String bookName; // 注入第一个配置外部文件属性 @Value("${book.name.placeholder}") private String bookNamePlaceholder; // 注入第二个配置外部文件属性 @Autowired private Environment env; // 注入环境变量对象,存储注入的属性值 public String toString(){ StringBuilder sb = new StringBuilder(); sb.append("bookName=").append(bookName).append("\r\n") .append("bookNamePlaceholder=").append(bookNamePlaceholder).append("\r\n") .append("appName=").append(appName).append("\r\n") .append("env=").append(env).append("\r\n") // 从eniroment中获取属性值 .append("env=").append(env.getProperty("book.name.placeholder")).append("\r\n"); return sb.toString(); } }
@Autowired
-