1. 程式人生 > >Spring Boot(二)配置與使用

Spring Boot(二)配置與使用

一、專案屬性配置

注意:在上個專案的基礎上進行操作

將application.propertites改為application.yml,yml檔案格式更為簡單

配置埠、專案字首路徑(注意格式,value前有空格

新建GirlProperties java檔案(屬性配置檔案,簡化配置)

package com.mlj.girl;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component//必須寫,否則無法識別
@ConfigurationProperties(prefix = "girl")//屬性字首
public class GirlProperties {

    private String cupSize;

    private Integer age;

    public String getCupSize() {
        return cupSize;
    }

    public void setCupSize(String cupSize) {
        this.cupSize = cupSize;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

在application.yml中飲用配置

girl:
  cupSize: B
  age: 18

在controller中使用配置的屬性

package com.mlj.girl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

//相當於@controller和@responseBody的組合
@RestController
public class HelloController {

    @Autowired//注入依賴
    private GirlProperties girlProperties;


    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String say() {
        return girlProperties.getCupSize();
    }
}

二、多環境配置(如生產環境和開發環境)

新建application-dev.yml application-prod.yml

server:
  port: 8080
  servlet:
    context-path: /girl
girl:
  cupSize: B
  age: 18
server:
  port: 8081
  servlet:
    context-path: /girl
girl:
  cupSize: F
  age: 18

修改application.yml

這裡指定了開發環境dev,直接執行就會引用application-dev.yml的配置

spring:
#開發環境配置
  profiles:
    active: dev

執行時指定環境(避免頻繁改動配置)

編譯專案

進入target目錄

java -jar jar包 --配置檔案的引數(指定執行環境)

mvn install

cd target

java -jar jar包名 --spring.profiles.active.dev

三、controller層常用註解

@PathVariable符合rest風格介面url 

package com.mlj.girl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

//相當於@controller和@responseBody的組合
@RestController
public class HelloController {

    @Autowired
    private GirlProperties girlProperties;

    @GetMapping(value = "/hello/{id}")
    public String say(@PathVariable("id") Integer id,
                      @RequestParam(value = "myId",required = false,defaultValue = "0") Integer myId) {

        return "id:" + id + "myId:" + myId;
    }
}

@GetMappting相當於@RequestMapping(method = RequestMethod.GET),適用於查詢操作。相對應的有

@PostMapping 適用於新增操作

@PutMapping 適用於修改操作

@DeleteMapping 適用於刪除操作

@Controller與@RestController

@RestController是相當於@controller和@responseBody的組合,返回json物件

@Controller返回的是html模板,目前開發為了提高效能大多前後端分離,所以一般使用@RestController

四、jpa資料庫操作

新建資料庫dbgirl

配置資料來源和jpa

在application.yml中

#資料庫配置
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/dbgirl
    username: root
    password: root
#jpa配置
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

新建實體類:(注意:必須有無參構造方法,否則表建立失敗)

類似hibernate的註解開發,省去了複雜配置

package com.mlj.girl;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Girl {

    @Id
    @GeneratedValue//自動生成策略
    private Integer id;

    private String cupSize;

    private Integer age;

    public Girl() {
    }
//    必須有無參構造

    
//get set方法省略
}

新建介面GirlRepository

繼承JpaRepository類,相當於hibernate中的session,可以對資料庫進行操作

package com.mlj.girl;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface GirlRepository extends JpaRepository<Girl,Integer> {

  
}

新建類GirlController

因為沒有複雜邏輯,先省略service.

對資料庫表進行增刪改查操作。girlRepository內有封裝好的一般操作,查詢條件為id,如果想自定義條件,需要在girlRepository中增加相應操作

package com.mlj.girl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class GirlController {

    @Autowired
    private GirlRepository girlRepository;
    @Autowired
    private GirlService girlService;

    /**
     * 獲取列表
     *
     * @return
     */
    @GetMapping(value = "/girls")
    public List<Girl> girlList() {
        return girlRepository.findAll();
    }

    /**
     * 新增
     *
     * @param cupSize
     * @param age
     * @return
     */
    @PostMapping(value = "/girls")
    public Girl girlAdd(@RequestParam("cupSize") String cupSize,
                        @RequestParam("age") Integer age) {
        Girl girl = new Girl();
        girl.setCupSize(cupSize);
        girl.setAge(age);
        return girlRepository.save(girl);
    }

    /**
     * 查詢一個女生
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/girls/{id}")
    public Girl girlFindOne(@PathVariable(value = "id") Integer id) {
        return girlRepository.findById(id).get();
    }

    /**
     * 更新
     *
     * @param id
     * @param cupSize
     * @param age
     * @return
     */
    @PutMapping(value = "/girls/{id}")
    public Girl girlUpdate(@PathVariable(value = "id") Integer id,
                           @RequestParam(value = "cupSize") String cupSize,
                           @RequestParam(value = "age") Integer age) {
        Girl girl = new Girl();
        girl.setId(id);
        girl.setCupSize(cupSize);
        girl.setAge(age);
        return girlRepository.save(girl);
    }

    /**
     * 刪除
     *
     * @param id
     */
    @DeleteMapping(value = "/girls/{id}")
    public void girlDelete(@PathVariable(value = "id") Integer id) {
        girlRepository.deleteById(id);
    }


}

自定義條件查詢

根據女生的年齡查詢

在girlRepository中增加方法findByAge:(注意:方法名不能隨便起,遵守JPA約定,idea會自定提示

package com.mlj.girl;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface GirlRepository extends JpaRepository<Girl,Integer> {

    //根據年齡查詢
    public List<Girl> findByAge(Integer age);
}

五、事務處理

在service層需要事務處理的方法上添加註解@Transactional,一般除了查詢操作都要求事務處理

當我們在一個方法內要對資料庫進行兩次操作,希望兩次操作同時進行時,事務就起作用了。例如:我要同時在資料庫新增兩個girl,當一個girl不符合條件時會新增失敗,另一個則會新增成功,這就需要事務處理了。

將資料庫表cupSize位數修改為1,人為製造錯誤進行測試,觀察資料庫資料變化

package com.mlj.girl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class GirlService {

    @Autowired
    private GirlRepository girlRepository;

    @Transactional
//    查詢不需要加事務
    public void insertTow() {
        Girl girl1 = new Girl();
        girl1.setCupSize("C");
        girl1.setAge(17);
        girlRepository.save(girl1);

        Girl girl2 = new Girl();
        girl1.setCupSize("DDDD");
        girl1.setAge(19);
        girlRepository.save(girl2);
    }
}

    @PostMapping(value = "/girls/tow")
    public void girlTow() {
        girlService.insertTow();
    }

六、問題與解決

org.apache.catalina.LifecycleException: Failed to start component [Connector

我的是埠被佔用了,兩個環境用了一個埠號,修改埠號或者殺死程序。

Inferred type 'S' for type parameter 'S' is not within its bound;

girlRepository.findOne(id)報錯。 .findOne(id)不適用2.0以上的版本。改為girlRepository.findById(id).get();

Ambiguous handler methods mapped for HTTP path

重複對映錯誤。在使用@PathVariable進行路徑對映時,注意進行區分

@GetMapping(value = "/girls/{id}") 
@GetMapping(value = "/girls/{age}")重複對映。改為@GetMapping(value = "/girls/age")

Transactional註解不回滾

資料庫引擎要支援事務,如果是MySQL,注意表要使用支援事務的引擎,比如innodb,如果是myisam,事務是不起作用的。

修改資料庫引擎

或者在

修改mysql安裝目錄下的my.ini檔案,在[mysqld]下加上:

1

default-storage-engine=INNODB