####前言
Spring Boot
是用來簡化Spring
應用初始搭建以及開發過程的全新框架,被認為是SpringMVC
的接班人,和微服務緊密聯絡在一起。Spring Boot 簡單例項Demo
####SpringMVC 的優缺點
-
優點:
Spring Boot
適合快速開發,適合構建微服務系統。封裝了經常使用的元件,比如MyBatis
,Hibernate
,MongoDB
等。- 純
Java
的配置,簡單方便。 - 配置Maven等構建工具後,
java -jar
進行部署比較簡單。 Spring Boot
對自定義十分友好,可以配置在application.yml
或者Config
類,Spring Boot
的整體思想是有自定義的話,自定義優先,否則走預設配置。Spring Boot
使編碼,配置,部署,監控變得簡單起來。
-
缺點:
- 太方便,使得沒有經驗的新手根本不知道
Spring Boot
底層到底幹了什麼。整合度較高,使用過程中不容易瞭解底層。 - 相關學習文件少, 坑多。
- 太方便,使得沒有經驗的新手根本不知道
####第一個Spring Boot的應用
- 首先建立一個
New Project
,要選擇Spring Initializr,
然後Choose Initializr Service URL
應該選擇Custom
, 正確的連結應該是http://start.spring.io/
,而不是https://start.spring.io/
。https
會造成我們訪問失敗!
2.相關配置,Type
我們選擇Maven Project
3.選擇Web
就行了。另外Spring Boot
的版本是1.5.8
4.Finished
。大功告成!
5.由於預設的setting.xml
配置,導致我們從遠端下jar實在是太慢,所以我們要修改.m2
下面的setting.xml
檔案,同時將setting.xml
原本指向C:UsersAdministrator.m2
的倉庫地址,改成我們自定義的盤下面即可。
epository
我的setting.xml是這樣的,如果還是看不懂的話,請移步Setting.xml相關配置
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors
複製程式碼
6.我們可以看到這個DemoApplication
類, 這是整個Spring Boot
應用的入口,有@SpringBootApplication
這個註解,顯而易見。
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
複製程式碼
7.接下來我們建立一個HelloController.java
, @RestController
這個註解的作用:宣告這是一個Controller
類,返回json
。其實就是@ResponseBody
和@Controller
的結合體。
@RestController
public class HelloController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String say() {
return "Hello, Spring Boot!";
}
}
複製程式碼
8.啟動有3種方式。
(1)直接在Itellij IDEA
啟動。
(2)在專案的根目錄下,開啟命令視窗,輸入mvn spring-boot:run
(3)在專案的根目錄下,開啟命令視窗,輸入mvn install
,讓專案生成jar
包。
然後會發現target
包下面多了一個jar
包。
輸入命令java -jar target/demo-0.0.1-SNAPSHOT.jar
9.我們就可以訪問Spring Boot
應用了。
###專案屬性配置
1.我們可以在resources資料夾
下面建3個properties
, application-dev.properties
是開發環境下的配置檔案。application-prod.properties
是應用環境下的配置檔案。Spring Boot
預設讀取的配置檔案是application.properties
,我們只需要在application.properties
指定使用哪一個環境下的配置檔案即可。比如:spring.profiles.active=dev
2.我們在application-dev.properties
,配置一些資訊,讓我們的Controller
類去讀取配置資訊。
server.port=8081
server.context-path=/girl
cupSize=A
height=160
content="cupSize: ${cupSize}, age: ${height}"
girl.cupSize=A
girl.height=160
複製程式碼
3.Controller類讀取配置資訊,啟動Spring Boot輸出結果。
public class HelloController {
@Value("${cupSize}")
private String cupSize;
@Value("${height}")
private String height;
@Value("${content}")
private String content;
@RequestMapping(value = "/display", method = RequestMethod.GET)
public String display() {
return "cupSize=" + cupSize + ", height=" + height;
}
@RequestMapping(value = "/content", method = RequestMethod.GET)
public String displayContent() {
return content;
}
}
複製程式碼
4.Controller
類讀取配置資訊帶字首的字串,比如我們要讀取girl.cupSize=A girl.height=160
這些帶girl的配置資訊,我們該怎麼辦呢。我們需要定義一個GirlProperties.java
。@ConfigurationProperties
代表我們要讀取帶什麼字首的配置資訊,@Component
代表這個類已經在Spring配置檔案中註冊過。
@ConfigurationProperties(prefix = "girl")
@Component
public class GirlProperties {
private String cupSize;
private String height;
public String getCupSize() {
return cupSize;
}
public void setCupSize(String cupSize) {
this.cupSize = cupSize;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
}
複製程式碼
5.Controller
類讀取GirlProperties
,我們要使用@Autowired
注入GirlProperties
這個類的例項,它是通過bean的型別注入的。啟動Spring Boot應用,輸出結果。
@RestController
public class HelloController {
@Autowired
private GirlProperties girlProperties;
@RequestMapping(value = "/properties", method = RequestMethod.GET)
public String displayProperties() {
return girlProperties.getCupSize() + girlProperties.getHeight();
}
}
複製程式碼
###Controller的使用
1.儘量使用@GetMapping
和 @PostMapping
代替 @RequestMapping(value = "/xxxxx", method = RequestMethod.GET)
2.如果需要在Spring Boot
使用@Controller
,需要返回一個邏輯檢視。比如
@Controller
public class DemoController {
@RequestMapping(value = "/saylove", method = RequestMethod.GET)
public String sayLove() {
return "index";
}
}
複製程式碼
index.html
是在templates
資料夾下面的
3.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>girl</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.8.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
複製程式碼
###資料庫操作
1.在application-dev.properties
配置資料連線配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot
spring.datasource.username=root
spring.datasource.password=xiaoma96
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
複製程式碼
spring.jpa.hibernate.ddl-auto
有4個屬性:
create
: 不管資料庫原先有沒有這個表,每次啟動應用,都會drop這個表,然後再建立新的一張表。
update
: 如果資料庫中有這個表且有資料,那麼我會保留這張表,不會去刪除它。
create-drop
: 應用停止的時候, 會把資料庫裡面這張表刪除。
none
: 不產生任何行為。
2.什麼是JPA
?JPA
的英文全稱是Java Persistence API
定義了一系列物件持久化的標準,目前實現這個規範的產品有Hibernate
。
3.怎麼去使用JPA
? 之前用過Liferay
技術, Liferay
通過ServiceBuilder
生成Service.xml
,在這個Service.xml
配置你需要建立資料庫表的entity
資訊,然後定義一些方法的欄位。然後build一下。就會生成對應的CRUD
方法,很是智慧。而且在下一次應用啟動時,會生成對應的資料庫表喲。如果需要定製化sql語句,只需要在finderImpl
和ServiceImpl
裡面新增自己的方法,然後build
一下,重新生成介面。同樣JPA
,簡單的CRUD
我們不需要去寫sql語句,只需要定義一個GirlRepository
的介面,繼承JpaRepository<Girl, Integer>
就行了。需要定製化CRUD
,我們新增相應的方法就行了。
public interface GirlRepository extends JpaRepository<Girl, Integer> {
public List<Girl> findByAge(Integer age);
public List<Girl> findByCupSize(String cupSize);
public List<Girl> findByName(String name);
}
複製程式碼
4.定義RESTfulAPI
,開放CRUD
介面。增加,使用POST
, 查詢使用GET
, 更新使用PUT
,刪除使用DELETE
。
@RestController
public class GirlController {
@Autowired
private GirlRepository girlRepository;
/**
* Queries all girls.
* @return girls List queryed
*/
@GetMapping(value = "/girls")
public List<Girl> girlList() {
return girlRepository.findAll();
}
/**
* Adds girl
* @param name
* @param cupSize
* @param age
* @return girl added
*/
@PostMapping(value = "/girls")
public Girl girlAdd(@RequestParam("name") String name, @RequestParam("cupsize") String cupSize
, @RequestParam("age") Integer age) {
Girl girl = new Girl();
girl.setAge(age);
girl.setName(name);
girl.setCupSize(cupSize);
return girlRepository.save(girl);
}
/**
* Finds girl by id
* @param id
* @return girl finded
*/
@GetMapping(value = "/girls/{id}")
public Girl girlFindOne(@PathVariable("id") Integer id) {
return girlRepository.findOne(id);
}
/**
* Updates girl
* @param id
* @param name
* @param cupSize
* @param age
* @return girl updated
*/
@PutMapping(value = "/girls/{id}")
public Girl girlUpdateOne(@PathVariable("id") Integer id, @RequestParam("name") String name, @RequestParam("cupsize") String cupSize
, @RequestParam("age") Integer age) {
Girl girl = new Girl();
girl.setCupSize(cupSize);
girl.setName(name);
girl.setAge(age);
girl.setId(id);
return girlRepository.save(girl);
}
/**
* Deletes girl by id
* @param id
*/
@DeleteMapping(value = "/girls/{id}")
public void girlDeleteOne(@PathVariable("id") Integer id) {
girlRepository.delete(id);
}
/**
* Queries girls by name
* @param name
* @return girl list queryed
*/
@GetMapping(value = "/girls/name/{name}")
public List<Girl> girlFindByName(@PathVariable("name") String name) {
return girlRepository.findByName(name);
}
/**
* Queries girls by age
* @param age
* @return girl list queryed
*/
@GetMapping(value = "/girls/age/{age}")
public List<Girl> girlFindByAge(@PathVariable("age") Integer age) {
return girlRepository.findByAge(age);
}
/**
* Queries girls by cupsize
* @param cupSize
* @return girl list queryed
*/
@GetMapping(value = "/girls/cupsize/{cupsize}")
public List<Girl> girlFindByCupSize(@PathVariable("cupsize") String cupSize) {
return girlRepository.findByCupSize(cupSize);
}
}
複製程式碼
5.使用Postman
軟體,測試API
。在這裡,我就測試一個查詢api
,演示一下。
###事務管理
1.什麼是事務?事務是作為一個邏輯單元執行的一系列操作。它有4個特性
- 原子性:事務是一個原子操作,由一系列動作組成。事務的原子性確保動作要麼全部完成,要麼全部失敗。
- 一致性: 一旦事務完成,不管成功還是失敗,系統必須確保它所建模的業務處於一致的狀態,而不全是部分完成,或者是部分失敗,在現實的資料不應有被破壞。
- 隔離性: 可能有許多事務會同時處理相同的資料, 因此每個事務都應該與其他事務隔離開,防止資料被破壞。
- 永續性: 一旦事務完成, 無論發生什麼,系統發生錯誤,它的結果都不應該受到影響,這樣就能從任何系統崩潰中恢復過來, 通常情況下,事務的記過被寫到持久化儲存器。
2.我們常用的幾個事務:
PROPAGATION_REQUIRED
: 如果存在一個事務,則支援當前的事務,如果沒有則開啟。PROPAGATION_SUPPORTS
: 如果存在一個事務,就支援當前事務, 如果沒有事務,則以非事務執行。PROPAGATION_REQUIRES_NEW
: 啟動一個新的事務,不依賴當前事務,當前事務掛起。
3.我們模擬一個事務的回滾,體現事務的原子性,第一個save
操作不會出現問題,第二個save
操作會丟擲異常。但是不能部分成功,不能部分失敗。這二個操作最終會被回滾。
@Service
public class GirlService {
@Autowired
private GirlRepository girlRepository;
@Transactional
public void insertTwo() {
Girl girlA = new Girl("garrett-test", 18, "Z");
girlRepository.save(girlA);
Girl girlB = new Girl("mayday-test", 21, "BBBBBBBB");
girlRepository.save(girlB);
}
}
@RestController
public class GirlController {
@Autowired
private GirlService girlService;
/**
* Tests transaction
*/
@GetMapping(value = "/transaction")
public void transactionTest() {
girlService.insertTwo();
}
}
複製程式碼
4.啟動應用,開啟Postman
,測試API
。很顯然,操作發生異常進行回滾,資料庫未插入任何資料。
####尾言
學無止境,一起共勉。