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 |
|