目錄
?編輯
API接口設計的架構風格
一 Dao層實現(處理數據庫)
二 Sercice層實現(處理業務邏輯)
三 Controller層(處理http請求)
四 補充知識點
1 @PathVariable - 路徑變量
2 @CrossOrigin(Origins = "*")允許跨域訪問
3 可以在路徑之前加上需要訪問的路徑
restful 概念引入 REST(表現層狀態轉移Representional State Transfer)是一種軟件架構風格。
旨在構建高效、可拓展的分布式系統,尤其適用于Web服務,其核心思想是通過統一的接口和資源操作實現客戶端于服務器之間的交互。REST 憑借其簡潔、靈活的特點,成為現代 Web 服務的基石。
API接口設計的架構風格
API接口:Web應用暴露出來的讓別人訪問的請求路徑。jar包封裝的API接口。
CRUD案例實現:
一 Dao層實現(處理數據庫)
結構圖
代碼實現:
創建一個bean類,用來放數據庫用戶的信息
package org.example.springmvc.bean;import lombok.Getter;
import lombok.Setter;@Setter
@Getter
public class Employee {private Integer id;private String name;private Integer age;private String gender;public Employee(Integer id, String name, Integer age, String gender) {this.id = id;this.name = name;this.age = age;this.gender = gender;}public Employee() {}@Overridepublic String toString() {return "Employee{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +'}';}
}
定義一個接口里面寫上需要的方法
package org.example.springmvc.dao;import org.example.springmvc.bean.Employee;public interface EmployeeDao {// 查詢根據ID查詢員工Employee getEmployeeById(Integer id);// 添加員工void addEmployee(Employee employee);// 修改員工void updateEmployee(Employee employee);// 刪除員工(根據ID)void deleteEmployee(Integer id);}
接口的實現類(數據庫增刪改查的具體實現)
package org.example.springmvc.dao.Impl;import org.example.springmvc.bean.Employee;
import org.example.springmvc.dao.EmployeeDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;@Component
public class EmployeeDaoImpl implements EmployeeDao {private final JdbcTemplate jdbcTemplate;// 注入JdbcTemplatepublic EmployeeDaoImpl(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic Employee getEmployeeById(Integer id) {String sql = "select * from first_tb where id = ?";return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Employee.class), id);}@Overridepublic void addEmployee(Employee employee) {String sql = "insert into first_tb(id,name,age,gender) values(?,?,?,?)";jdbcTemplate.update(sql, employee.getId(), employee.getName(), employee.getAge(), employee.getGender());}@Overridepublic void updateEmployee(Employee employee) {String sql = "update first_tb set name = ?,age = ?,gender = ? where id = ?";jdbcTemplate.update(sql, employee.getName(), employee.getAge(), employee.getGender(), employee.getId());}@Overridepublic void deleteEmployee(Integer id) {String sql = "delete from first_tb where id = ?";jdbcTemplate.update(sql, id);}
}
測試類實現:(CRUD)
package org.example.springmvc;import org.example.springmvc.bean.Employee;
import org.example.springmvc.dao.EmployeeDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class SpringTest {@AutowiredEmployeeDao employeeDao;@Testpublic void test() {// 查Employee employee = employeeDao.getEmployeeById(1);System.out.println(employee);// 增刪改employeeDao.addEmployee(new Employee(7, "超哥", 18, "男"));employeeDao.updateEmployee(new Employee(1, "賢哥", 18, "男"));employeeDao.deleteEmployee(5);}
}
二 Sercice層實現(處理業務邏輯)
結構圖:
接口:
package org.example.springmvc.service;import org.example.springmvc.bean.Employee;public interface EmployeeService {// 根據id查詢員工Employee getEmployeeById(Integer id);// 添加員工void addEmployee(Employee employee);// 修改員工void updateEmployee(Employee employee);// 刪除員工void deleteEmployee(Integer id);}
接口的實現類:(實現更新操作的非空判斷)
package org.example.springmvc.service.Impl;import org.example.springmvc.bean.Employee;
import org.example.springmvc.dao.EmployeeDao;
import org.example.springmvc.service.EmployeeService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;@Service
public class EmployeeServiceImpl implements EmployeeService {private final EmployeeDao employeeDao;// 注入daopublic EmployeeServiceImpl(EmployeeDao EmployeeDao) {this.employeeDao = EmployeeDao;}@Overridepublic Employee getEmployeeById(Integer id) {return employeeDao.getEmployeeById(id);}@Overridepublic void addEmployee(Employee employee) {employeeDao.addEmployee(employee);}@Overridepublic void updateEmployee(Employee employee) {//防空處理,考慮到service是被controller調用的,所以要考慮某些屬性是空的,需要進行處理//1 去數據庫查詢到原來的值//2 把頁面帶來的值覆蓋原來的值,頁面沒帶的保持原狀Integer id = employee.getId();if (id == null) {return;}// 獲取數據庫當中的Employee employeeById = employeeDao.getEmployeeById(id);//傳過來的值不是空串,將值傳遞給數據庫if (StringUtils.hasText(employee.getName())) {employeeById.setName(employee.getName());}if (StringUtils.hasText(employee.getGender())) {employeeById.setGender(employee.getGender());}if (employee.getAge() != null) {employeeById.setAge(employee.getAge());}employeeDao.updateEmployee(employeeById);}@Overridepublic void deleteEmployee(Integer id) {employeeDao.deleteEmployee(id);}
}
測試類:
@AutowiredEmployeeService employeeService;@Testpublic void test1() {Employee employee = new Employee();employee.setId(7);employee.setAge(100);employeeService.updateEmployee(employee);}
三 Controller層(處理http請求)
代碼實現:
/*** 統一返回JSON* code: 說明:業務狀態碼,前后端商定不同的業務狀態嗎* msg: 說明:提示信息,前端根據業務狀態碼和提示信息進行業務邏輯處理* data: 說明:返回的數據* 前端統一處理業務邏輯,根據業務狀態碼和提示信息進行業務邏輯處理* 1 前端發送請求* 2 判斷狀態碼,成功就顯示數據,失敗就提示提示信息(或其它操作)**/
package org.example.springmvc.common;public class R<T> {private final Integer code;private final String msg;private final T data;// 私有化構造器,強制通過靜態工廠方法創建對象private R(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}// -------------------- 成功響應快捷方法 --------------------public static R<?> ok() {return new R<>(200, "success", null);}public static <T> R<T> ok(T data) {return new R<>(200, "success", data);}public static <T> R<T> ok(String msg, T data) {return new R<>(200, msg, data);}// -------------------- 錯誤響應快捷方法 --------------------public static R<?> error(int code, String msg) {return new R<>(code, msg, null);}public static R<?> error(ErrorCode errorCode) {return new R<>(errorCode.getCode(), errorCode.getMsg(), null);}// -------------------- 鏈式構建方法(可選) --------------------public R<T> withMsg(String msg) {return new R<>(this.code, msg, this.data);}public R<T> withData(T data) {return new R<>(this.code, this.msg, data);}// -------------------- Getter --------------------public Integer getCode() {return code;}public String getMsg() {return msg;}public T getData() {return data;}// -------------------- 狀態碼枚舉(可選) --------------------public enum ErrorCode {BAD_REQUEST(400, "參數錯誤"),UNAUTHORIZED(401, "未授權"),NOT_FOUND(404, "資源不存在"),INTERNAL_ERROR(500, "服務器內部錯誤");private final int code;private final String msg;ErrorCode(int code, String msg) {this.code = code;this.msg = msg;}public int getCode() {return code;}public String getMsg() {return msg;}}
}
需求類:
package org.example.springmvc.controller;import org.example.springmvc.bean.Employee;
import org.example.springmvc.common.R;
import org.example.springmvc.service.EmployeeService;
import org.springframework.web.bind.annotation.*;@RestController
public class EmployeeRestController {EmployeeService employeeService;// 構造器注入public EmployeeRestController(EmployeeService employeeService) {this.employeeService = employeeService;}// 根據id查詢員工// @RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)@GetMapping(value = "/employee/{id}")public R get(@PathVariable("id") Integer id) {Employee employeeById = employeeService.getEmployeeById(id);return R.ok(employeeById);}// 根據id刪除員工// @RequestMapping(value = "/employee/{id}", method = RequestMethod.POST)@DeleteMapping(value = "/employee/{id}")public R delete(@PathVariable("id") Integer id) {employeeService.deleteEmployee(id);return R.ok();}// 添加員工,前端發送請求,把 json 數據封裝到 Employee 對象中@PostMapping(value = "/employee")public R add(@RequestBody Employee employee) {employeeService.addEmployee(employee);return R.ok();}// 修改員工@PutMapping(value = "/employee")public R update(@RequestBody Employee employee) {employeeService.updateEmployee(employee);return R.ok();}}