Spring Boot最好的学习方法就是实战训练,今天我们用很短的时间启动我们第一个Spring Boot应用,并且连接我们的MySQL数据库. 我将假设读者为几乎零基础,在实战讲解中会渗透Spring框架中的一些知识点,并提供相关官方文档链接, 让我们一起在实战中高效学习。
在这个实战学习中, 我们将使用Spring Boot
与MySQL
数据库构建一个简单的登陆系统,功能包含注册账户和登陆两个功能,并用Spring Boot
官方推荐使用的thymeleaf
模板来生成简单的前端页面。 我们将使用Spring Boot
与MySQL
数据库构建一个简单的登陆系统,功能包含注册账户和登陆两个功能,并用Spring Boot
官方推荐使用的thymeleaf
模板来生成简单的前端页面。
看完该文章, 你将学会:
- 使用MySQL shell工具连接到MySQL server, 创建一个用户, 并创建一个数据库.
- 学习在Spring中配置并连接到你的MySQL数据库.
- 学习并掌握Jpa的Entity, Repository的使用方法.
配置MySQL数据库
第一步我们需要将MySQL数据库下载到电脑里, 下载地址: 下载MySQL完整工具包
在页面中点击红线框住的部分:
点进去, 拉到页面下方, 点击红框部分右侧的download
:
下载后, 按照安装包提示的步骤操作, 安装完毕后, 你会获得几个新应用, 我们只用其中一个, 它是:
它是MySQL的命令行工具, 我们用它来操作我们的MySQL数据库.
但是我们不直接点开它, 我们在Windows自带的Command Prompt中使用它.
- 打开Command Prompt, 输入:
mysql -u root -p
进入Mysql命令行工具, 会提示你输入密码:
输入在安装过程中设置的密码, 进入mysql命令行工具.
- 创建一个MySQL用户, 在命令行中输入命令(其实是SQL语句):
CREATE USER 'niudai'@'localhost' IDENTIFIED BY 'niudai';
这个语句的目的是创建一个用户名为'niudai', 登陆密码为'niudai'的MySQL数据库管理员, 用这个账号可以管理我们的数据库, 也就是说如果你要管理数据库, 你必须要有这么一个账号.
- 再输入如下语句:
CREATE DATABASE springdb;
熟悉SQL语言的同学应该很熟悉上面这句, 就是创建一个名为springdb
的数据库, 这个数据库就是我们的Spring Boot应用要连接的.
- 赋予刚创建的用户名为"niudai"的用户管理
springdb
数据库的所有权限:
GRANT ALL ON springdb.* TO 'niudai'@'localhost';
创建一个Spring Boot应用
https://start.spring.io/这是Spring官网的依赖,把你所需要的依赖打包下载到本地,然后用idea打开即可。
我们所需要的四个依赖, 全是Spring Boot官方支持的库, 知识点讲解:
Thymeleaf
是现代服务端的Java模板引擎, 我们用它来生成HTML页面.JPA
是Java Persistence API, 也就是Java持久层API, 它的本质是一套将Java的对象映射到数据库中的关系表的标准, 而Spring-Boot
的JPA
依赖包含一个重要子依赖, 你一定听过它的名字:Hibernate
. 它是JPA
的具体实现, 也是Spring Boot
的默认JPA
实现.官方文档相关知识点阅读MySQL
是用来实现从Java到MySQL连接的一个中间件.Web
是Spring Boot
重要核心组件, 网络应用的必须品, 它包含了Tomcat
容器,Spring MVC
等核心组件.
所以我们也可以看到Spring Boot
其实相当于一个依赖打包器, 比如网络模块, 大家都需要Tomcat
容器, 也需要Spring MVC
框架, 那索性就放到一个包里, 也就是Web
包, 这样一个依赖就解决了问题.
配置application.properties文件
application.properties
文件的作用有点类似于pom
, 但也不太一样, pom
是管理你应用和其他库的依赖关系,
而application.properties
则是去设置, 或是配置这些依赖, 是Spring应用的重要组成部分.
该文件可以在maven工程的src/main/java/resources/applicatio.properties
下找到.
在该文件中输入如下属性:
spring.datasource.username=niudai
spring.datasource.password=niudai
spring.datasource.url=jdbc:mysql://localhost:3306/springdb
spring.jpa.hibernate.ddl-auto=create
讲解:
第三行的url
就是我们数据库的地址, 3306
是MySQL默认的本地端口, 而springdb
正是我们之前创建的数据库.
第一行和第二行声明了我们之前创建的用户名密码和账户名, 都为niudai
第四行的create
为开发模式, 就是每次应用启动都重新创建一个新表, 原有的表会清空, 开发结束后可以将其设置为none
.
声明了这些之后, 启动应用后, Spring
会自动用上述的信息连接并登陆你的MySQL
中名为springdb
的数据库.
创建你的Entity(编写代码开始)
什么是Entity
呢? 说白了就是会被映射到数据库中的Java Object
, 比如我们将要创建的User
类.
在src/main/java/
下创建一个文件User.java
:
package org.springframework.gsloggingdatamysql; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class User { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Integer id; private String name; private String email; private String password; @Override public String toString() { return "{" + " id='" + getId() + "'" + ", name='" + getName() + "'" + ", email='" + getEmail() + "'" + ", password='" + getPassword() + "'" + "}"; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getEmail() { return this.email; } public void setEmail(String email) { this.email = email; } }
加了@Entity
注解, Spring
框架会得知这个类是一个Entity
, Hibernate
会把这个类映射到数据库中的关系表, 这个关系表的列与User
的所有属性一一对应.
相当于SQL语言中的:
CREATE TABLE User(id int, name varchar(255), email varchar(255), password varchar(255));
创建UserRepository
如果说User代表每个用户, 或是用户的信息, 那么UserRepository就代表储存这些用户的"库", 我们创建一个UserRepository.java
, 注意它是一个接口, 也就是Interface
, 而不是Class
. 继承JpaRepository接口也可以。
package org.springframework.gsloggingdatamysql; import java.util.List; import org.springframework.data.repository.CrudRepository; public interface UserRepository extends CrudRepository<User, Integer> { List<User> findByEmail(String email); void deleteByEmail(String email); }
你可能会疑惑这只是一个接口, 并没有具体实现, 如何完成对User信息的储存, 但事实上你只需声明这个接口, 剩下的交给Spring
, 它会自动为你进行它的实现.
该类继承了CrudRepository
, 也就是支撑"增删改查"的一个Repository, 你可以在别的地方直接调用这个接口的方法, 方法名有规范, 比如你想通过邮箱查找, 那你就使用findByEmail(String email)
方法, Spring
会自动帮你将findByEmail
转换成SQL语言中的`SELECT * FROM UserRepository WHERE email = 'email'
创建你的UserController
Controller
是接受用户的url
请求, 将url
映射到某个具体的方法, 处理url
请求, 再返回一个Model
的东西, 是Spring MVC
中的C
层.
知识点: Spring MVC中的三层分别是Model
, View
, Controller
. 当用户向你的服务器发送了请求后, 比如HTTP请求, Controller
先将请求映射到某个方法上, 方法根据该请求进行相应处理, 返回Model
, 这个Model
可以被理解成一个抽象的数据模型, 它储存了网页必须包含的信息, 但是它不是网页本身, Model
会被送到View
层, 也就是用户界面层, View
层将自己本身的模板和Model
内部的数据结合成为完整的一个页面, 作为response
返还给用户, 用户便看到了你的页面,.
但是现在随着前后端的分离, View
层的意义已经不大,作为后端开发, 主要专注于Model
和Controller
.
创建一个文件: UserController.java
:
package org.springframework.gsloggingdatamysql; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class UserController { private static final Logger log = LoggerFactory.getLogger(UserController.class); @Autowired private UserRepository userRepository; @GetMapping(path="/add") // Map ONLY GET REQUESTs. public @ResponseBody String addNewUser (@RequestParam String name , @RequestParam String email, @RequestParam String password, User user) { // @ResponseBody means the returned String is a response, not a view name. user.setName(name); user.setEmail(email); user.setPassword(password); userRepository.save(user); log.info(user.toString()+" saved to the repo"); return "Saved"; } /** * 登陆方法, 用户输入邮箱和密码, 查询数据库检验是否有该账户,如果有, * 返回原先页面 ,登陆成功。 * @param email 用户邮箱 * @param password 用户密码 * @param model Spring MVC中的Model,用来储存经过controller处理后的信息,再由View层渲染 * 得到前端页面。 * @return */ @GetMapping(path = "/login") public String login(@RequestParam String email, @RequestParam String password, Model model) { List<User> users = userRepository.findByEmail(email); // 如果数据库中未查到该账号: if (users == null) { log.warn("attempting to log in with the non-existed account"); return "该用户不存在"; } else { User user = users.get(0); if (user.getPassword().equals(password)) { // 如果密码与邮箱配对成功: model.addAttribute("name", user.getName()); log.warn(user.toString()+ " logged in"); } else { // 如果密码与邮箱不匹配: model.addAttribute("name", "logging failed"); log.warn