SpringBoot之路(一)之初識SpringBoot

####前言 Spring Boot是用來簡化Spring應用初始搭建以及開發過程的全新框架,被認爲是SpringMVC的接班人,和微服務緊密聯繫在一塊兒。Spring Boot 簡單實例Demohtml

####SpringMVC 的優缺點java

  • 優勢:mysql

    • Spring Boot適合快速開發,適合構建微服務系統。封裝了常用的組件,好比MyBatis, Hibernate, MongoDB等。
    • Java的配置,簡單方便。
    • 配置Maven等構建工具後,java -jar進行部署比較簡單。
    • Spring Boot對自定義十分友好,能夠配置在application.yml或者Config類,Spring Boot的總體思想是有自定義的話,自定義優先,不然走默認配置。
    • Spring Boot使編碼,配置,部署,監控變得簡單起來。
  • 缺點:git

    • 太方便,使得沒有經驗的新手根本不知道Spring Boot 底層到底幹了什麼。集成度較高,使用過程當中不容易瞭解底層。
    • 相關學習文檔少, 坑多。

####第一個Spring Boot的應用github

  1. 首先建立一個New Project,要選擇Spring Initializr, 而後Choose Initializr Service URL應該選擇Custom, 正確的連接應該是http://start.spring.io/,而不是https://start.spring.io/https會形成咱們訪問失敗!

Paste_Image.png

2.相關配置,Type咱們選擇Maven Project web

Paste_Image.png

3.選擇Web就好了。另外Spring Boot的版本是1.5.8 spring

Paste_Image.png

4.Finished。大功告成! sql

Paste_Image.png

5.因爲默認的setting.xml配置,致使咱們從遠程下jar實在是太慢,因此咱們要修改.m2下面的setting.xml文件,同時將setting.xml本來指向C:\Users\Administrator\.m2\repository的倉庫地址,改爲咱們自定義的盤下面便可。 個人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這個註解,顯而易見。apache

@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啓動。

Paste_Image.png
(2)在項目的根目錄下,打開命令窗口,輸入 mvn spring-boot:run
Paste_Image.png

(3)在項目的根目錄下,打開命令窗口,輸入mvn install,讓項目生成jar包。

Paste_Image.png
而後會發現 target包下面多了一個 jar包。
Paste_Image.png

輸入命令java -jar target/demo-0.0.1-SNAPSHOT.jar

Paste_Image.png
9.咱們就能夠訪問 Spring Boot應用了。

Paste_Image.png


###項目屬性配置 1.咱們能夠在resources文件夾下面建3個propertiesapplication-dev.properties是開發環境下的配置文件。application-prod.properties是應用環境下的配置文件。Spring Boot默認讀取的配置文件是application.properties,咱們只須要在application.properties指定使用哪個環境下的配置文件便可。好比:spring.profiles.active=dev

Paste_Image.png

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;
    }
}
複製代碼

Paste_Image.png

Paste_Image.png

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();
    }
}
複製代碼

Paste_Image.png


###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文件夾下面的

Paste_Image.png

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.什麼是JPAJPA的英文全稱是Java Persistence API定義了一系列對象持久化的標準,目前實現這個規範的產品有Hibernate

3.怎麼去使用JPA? 以前用過Liferay技術, Liferay經過ServiceBuilder生成Service.xml,在這個Service.xml配置你須要建立數據庫表的entity信息,而後定義一些方法的字段。而後build一下。就會生成對應的CRUD方法,非常智能。並且在下一次應用啓動時,會生成對應的數據庫表喲。若是須要定製化sql語句,只須要在finderImplServiceImpl裏面添加本身的方法,而後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,演示一下。

Paste_Image.png


###事務管理 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。很顯然,操做發生異常進行回滾,數據庫未插入任何數據。

image.png


####尾言 學無止境,一塊兒共勉。

相關文章
相關標籤/搜索