本教程需要安裝以下工具,如果不清楚怎么安裝的可以看下我的這篇文章
鏈接: https://blog.csdn.net/qq_30627241/article/details/134804675
管理工具: maven
IDE: IDEA
數據庫: MySQL
測試工具: Postman
打開IDEA
創建項目,創建項目時保持網絡通暢
設置項目的基本信息,其中注意jdk版本要與Java版本匹配,這里使用jdk1.8和java8
選擇SpringBoot版本,選擇項目依賴(依賴可以創建完項目后在pom文件中修改)
至此項目創建完成
創建數據庫
創建用戶表
CREATE TABLE user
(uid int(10) primary key NOT NULL AUTO_INCREMENT,uname varchar(30) NOT NULL,password varchar(255) NOT NULL,UNIQUE (uname)
);
uid: 用戶編號,主鍵,自增
uname: 用戶名,作為登錄的賬號(業務主鍵),不可重復
password: 密碼,因為可能要加密,所以長度設了較長的255
配置數據庫
1、找到配置文件application.properties
# 配置端口號為8081
server.port=8081# 配置數據庫
# 配置驅動
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 若連接的是云數據庫則將localhost改為云端ip
spring.datasource.url=jdbc:mysql://localhost:3306/summer?serverTimezone=UTC
# Mysql用戶
spring.datasource.username=root
# Mysql對應用戶密碼
spring.datasource.password=123456
2、輸入數據庫相關配置信息(此處配置了項目端口號為8081,可不配置,默認端口號為8080)
注意:配置url處summer改為你的數據庫名稱
現在運行項目就能成功了
3、在IDEA中連接數據庫,非必要步驟,連了開發方便些
配置如下
配置時區與配置文件中的一致:
點擊Test connection測試一下,如遇提示請下載:
下載后再點擊,成功如下:
現在可以在IDEA中管理數據庫了:
在說項目的目錄結構之前,我們先來聊一聊后端的架構大概是什么樣的,方便我們對目錄結構的理解:
??數據持久層的作用是在java對象與數據庫之間建立映射,也就是說它的作用是將某一個Java類對應到數據庫中的一張表。在我們的項目中,就將創建一個實體類User映射到數據庫的user表,表中的每個字段對應于實體類的每個屬性。而之前配置的JPA的作用就是幫助我們完成類到數據表的映射。
??repository: 存放一些數據訪問類(也就是一些能操縱數據庫的類)的包,比如存放能對user表進行增刪改查的類
??domain:存放實體類的包,比如User類,其作為對應數據庫user表的一個實體類
??業務邏輯層的作用是處理業務邏輯。比如在本項目中,我們就在業務邏輯層實現登錄注冊的邏輯,像是判斷是否有用戶名重復,密碼是否正確等邏輯
??service: 存放業務邏輯接口的包
??serviceImpl: 存放業務邏輯實現類的包,其中的類實現service中的接口
??控制層的作用是接收視圖層的請求并調用業務邏輯層的方法。比如視圖層請求登錄并發來了用戶的賬號和密碼,那么控制層就調用業務邏輯層的登錄方法,并將賬號密碼作為參數傳入,在將結果返回給視圖層。
??controller: 存放控制器的包。比如UserController
??視圖層的作用是展現數據,由于本項目寫的是純后端,就不展開解釋視圖層了。
注意:根據架構我們可以發現,最佳的開發方式是自底向上開發,因為包之間的調用是上層調用下層,所以下層先實現能保證實現多少測試多少
需要創建domain、repository、service、serviceImpl、controller、utils、config目錄,如圖所示:
這里再說下utils和config
utils: 存放工具類,一些自己封裝的工具
config: 存放配置類,一些配置如登錄攔截器,安全配置等
根據框架特點,我們將自底向上開發,所以將按照 實體類-dao-service-serviceImpl-controller 的順序逐步開發。
所有類或接口的目錄位置,如圖所示,根據圖來創建,藍色C圖標是java類文件,綠色I圖標是java接口文件:
實現User實體類
1、在domain中創建User.java
2、創建對應user表中字段的屬性
其中注意要添加@Table(name = “user”)和@Entity注解
@Table(name = “user”) 說明此實體類對應于數據庫的user表
@Entity 說明此類是個實體類
主鍵uid上要加上@Id與@GeneratedValue(strategy = GenerationType.IDENTITY)注解
3、為屬性生成get,set方法
將光標移至要插入get, set方法的位置
右鍵-generate-getter and setter
選中所有屬性-OK
最后得到User.java,也可以復制,至此User實體類就創建好啦,如果要實現其他表的實體類也類似。
package summer.summerdemo.domain;import javax.persistence.*;@Table(name = "user")
@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private long uid;private String uname;private String password;public long getUid() {return uid;}public void setUid(long uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
實現UserDao
1、在repository包中創建UserDao接口
2、首先要添加注解@Repository
接口要繼承JpaRepository,這樣JPA就能幫助我們完成對數據庫的映射,也就是說接口里寫的方法只要符合格式可以不需要實現SQL語句就能直接用了。
如果JPA沒有提供你想要的方法,可以自定義SQL語句
由于我們只實現登錄注冊功能,所以只要有根據賬號密碼查詢用戶和插入用戶信息的方法就行了,這里我們已經實現了根據用戶名密碼查找用戶的方法,而插入用戶信息的方法save(object o)JPA已經幫我們實現了,可以直接調用,這里就不需要寫了。
注意: 這里接口方法的命名要按照JPA提供的命名格式,比如findBy, deleteBy等等,且要求駝峰命名法。如果自定義查詢方法可以不遵守這個規則
package summer.summerdemo.repository;import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import summer.summerdemo.domain.User;@Repository
public interface UserDao extends JpaRepository<User, Long> {User findByUname(String uname);User findByUnameAndPassword(String uname, String password);
}
實現UserService
1、在service包中創建UserService接口
2、添加登錄注冊需要用到的業務邏輯方法
package summer.summerdemo.service;import summer.summerdemo.domain.User;public interface UserService {/*** 登錄業務邏輯* @param uname* @param password* @return*/User loginService(String uname, String password);/*** 注冊業務邏輯* @param user* @return*/User registerService(User user);
}
實現UserServiceImpl
1、在serviceImpl包中創建UserServiceImpl類
2、添加需要實現的方法
添加implements UserService
此時會報錯,但沒關系,只是因為方法還沒實現。
鼠標懸停在紅色波浪線有一個紅色燈泡的圖標出現,點擊它,自動生成需要實現的方法(也可復制后面貼出來的代碼)
全選:
生成后如下:
3、實現登錄業務邏輯
因為要用到UserDao中的方法,所以先通過@Resource注解幫助我們實例化UserDao對象
4、實現注冊業務邏輯
5、添加@Service注解
package summer.summerdemo.service.serviceImpl;import summer.summerdemo.domain.User;
import summer.summerdemo.repository.UserDao;
import summer.summerdemo.service.UserService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao;@Overridepublic User loginService(String uname, String password) {User user = userDao.findByUnameAndPassword(uname, password);if(user != null){user.setPassword("");}return user;}@Overridepublic User registerService(User user) {if(userDao.findByUname(user.getUname())!=null){return null;}else{User newUser = userDao.save(user);if(newUser != null){newUser.setPassword("");}return null;}}
}
實現工具類Result
工具類Result的作用是作為返回給前端的統一后的對象。也就是說返回給前端的都是Result對象,只是對象中的屬性不太一樣,這樣方便前端固定接收格式。
package summer.summerdemo.utils;public class Result<T> {private String code;private String msg;private T data;public String getCode() {return code;}public void setCode(String code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Result(){}public Result(T data){this.data = data;}public static Result success(){Result result = new Result<>();result.setCode("0");result.setMsg("成功");return result;}public static <T> Result<T> success(T data){Result<T> result = new Result<>(data);result.setCode("0");result.setMsg("成功");return result;}public static <T> Result<T> success(T data, String msg){Result<T> result = new Result<>(data);result.setCode("0");result.setMsg(msg);return result;}public static Result error(String code, String msg){Result result = new Result<>();result.setCode(code);result.setMsg(msg);return result;}
}
可以看出Result是個模板類,因此想要返回什么數據類型給前端都行,如Result,要是沒看懂沒關系,看到下面就知道怎么用了。因為里面有很多靜態方法,可以直接用類名.方法名調用。
實現UserController
1、在controller包中創建UserController類
2、添加@RestController與@RequestMapping(“/user”)注解,注入UserService
注解
3、實現登錄的控制
4、實現注冊的控制
@RequestMapping中的"/user"是這個控制器類的基路由
@PostMapping(“/login”)表示處理post請求,路由為/user/login
@PostMapping(“/register”)表示處理post請求,路由為/user/register
package summer.summerdemo.controller;import summer.summerdemo.domain.User;
import summer.summerdemo.service.UserService;
import summer.summerdemo.utils.Result;import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;import javax.annotation.Resource;@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate UserService userService;@PostMapping("/login")public Result<User> loginController(@RequestParam String uname, @RequestParam String password){User user = userService.loginService(uname, password);if(user != null){return Result.success(user,"登錄成功!");}else{return Result.error("123","賬號或密碼錯誤!");}}@PostMapping("/register")public Result<User> registerController(@RequestBody User newUser){User user = userService.registerService(newUser);if(user != null){return Result.success(user,"注冊成功!");}else{return Result.error("456","用戶名已存在!");}}
}
處理跨域訪問問題
跨域問題可以簡單理解成如果你的前端項目的IP地址和端口號和后端的IP地址和端口號不一樣,就會導致前端無法獲取到數據,這是一個規定。而在前后端分離開發的項目中,前后端項目的端口號一般都是不一樣的,假設我們這個項目的前端端口號是 8080,后端端口號是 8081,就會造成跨域訪問的問題,跨域訪問的問題可以在前端解決也可以在后端解決,后端只要加上一個配置文件就行了
1 、在config文件下創建全局跨域配置類GlobalCorsConfig.java
注意:SpringBoot2.4.0 以前下方 allowedOriginPatterns 需要被allowedOrigins代替
package summer.summerdemo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class GlobalCorsConfig {@Beanpublic WebMvcConfigurer corsConfigurer() {return new WebMvcConfigurer() {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") //添加映射路徑,“/**”表示對所有的路徑實行全局跨域訪問權限的設置.allowedOriginPatterns("*") //開放哪些ip、端口、域名的訪問權限 SpringBoot2.4.0以后allowedOrigins被allowedOriginPatterns代替.allowCredentials(true) //是否允許發送Cookie信息.allowedMethods("GET", "POST", "PUT", "DELETE") //開放哪些Http方法,允許跨域訪問.allowedHeaders("*") //允許HTTP請求中的攜帶哪些Header信息.exposedHeaders("*"); //暴露哪些頭部信息(因為跨域訪問默認不能獲取全部頭部信息)}};}
}
2、接下來就是運行項目,成功如下: