Spring Boot +Vue 项目实战笔记(三):数据库的引入
这一篇的主要内容是引入数据库并实现通过数据库验证用户名与密码。
一、引入数据库
之前说过数据库的采用是 MySQL,算是比较主流的选择,从性能和体量等方面都比较优秀,当然也有一些弊端,但数据库不是我们这里讨论的重点,暂时能用就行。
1.安装数据库
我的 MySQL 版本是 5.7,官方下载页面是
https://dev.mysql.com/downloads/mysql/5.7.html#downloads
安装教程我随便搜了一篇,可以参考
https://blog.csdn.net/ma524654165/article/details/77855431
目前最新的版本是 8.0,也可以下载最新版本,使用最新版本需要做三处修改:
一、修改后端项目 pom.xml
的 mysql 依赖配置
二、为数据库设置一个长密码,而不能用简单的 admin
等
三、修改 mysql 的时区为 +8:00
操作 MySQL 有很多种方式,可以用官方的 Command Line Client、Workbench,也可以用其它的一些界面化软件,比如 Navicat 等。如果之前没有接触过数据库,可以先用 Navicat,比较直观。安装方法参照这个博文:
https://blog.csdn.net/wypersist/article/details/79834490
我真是个好人啊,到处推荐别人的文章。。。
2.使用 Navicat 创建数据库与表
下面的内容主要针对初次使用数据库的读者,有经验的读者可以直接执行下面的 sql 语句,记得先新建一个数据库,名称最好叫 white_jotter,方便以后的配置。
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', '123');
按照上面贴出来的教程安装完 MySQL 和 Navicat 后,打开 Navicat,点击连接 -> MySQL,新建数据库连接
在弹出的界面中配置相关信息,如果之前安装数据库是按照上面的教程来的话,连接名随便起一个,主机名、端口、用户名都不用修改,密码是 root,其实我习惯设置成 admin,但看上面的教程是 root,这个项目无所谓,但记住实际的项目千万不要设置这么简单的密码,有不少企业的数据库密码还真就是 admin,被脱裤了才反应过来。。。
输入之后可以点击测试连接按钮测试一下,然后确定。
双击在左侧出现的连接 WJ,就打开了这个连接。安装完 MySQL 会有几个默认的数据库,这些不要动,我们在连接(即 WJ)上右键新建一个数据库,命名为 white_jotter,字符集选择 UTF-8,排序规则选择 utf8_general_ci 即可。
创建之后左侧就会出现一个名为 white_jotter 的数据库,双击它,点击“表”,然后点击“新建表”按钮,就进入了表设计界面。
为了完成登录验证,我们需要一个用户表,一般命名为 user,表里面暂定设计 3 个字段,分别是 id、username、password。
表设计界面默认有一个“栏位”,我们可以在这个栏位中加入第一个需要的字段,即用户的 id,其设置如下
箭头指向的地方不要漏了。最后那把小钥匙的意思是主键,可以点击上面的主键按钮或者直接点击这个空白的栏位设置。
然后再添加第二、三个栏位,配置如下:
最后点击保存,把表命名为 user,这样我们就有了第一张表。之后也可以在对象界面中选中表并点击“设计表”按钮重新设计。
接下来,我们双击 user 表,进入表中,添加一行用户信息,id 为 1,账号是 admin,密码是 123,也可以随便按照自己喜好添加。
可以看到下面自动执行了一条 SQL 语句。这里多说一句,真实的项目中,用户信息可不能这么存,直接把账号密码写上去太危险了,一般的做法是存储密码等信息的 hash 值。
OK,到现在为止,数据库的操作就完成了。
二、使用数据库验证登录
上一篇中我们直接在后端的控制器中用如下语句判断了用户名和密码的正确性:
if (!Objects.equals("admin", username) || !Objects.equals("123456", requestUser.getPassword())) {
String message = "账号密码错误";
System.out.println("test");
return new Result(400);
} else {
return new Result(200);
}
使用数据库验证的逻辑其实也类似,大概是如下过程:
第一步,获得前端发送过来的用户名和密码信息
第二步,查询数据库中是否存在相同的一对用户名和密码
第三步,如果存在,返回成功代码(200),如果不存在,返回失败代码(400)
这里的语句很简单,但在修改之前还需要一些准备工作。
1.项目相关配置
打开我们的后端项目 wj
,首先修改 pom.xml
,配置我们需要的依赖。为了方便以后的开发,我直接把我的配置粘贴上来,大家可以把原来的所有配置删除掉,再粘贴我的。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.evan</groupId>
<artifactId>wj</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>wj</name>
<description>White Jotter - Your Mind Palace</description>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- springboot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot tomcat 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- springboot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- elastic search -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- 用了 elasticsearch 就要加这么一个,不然要com.sun.jna.Native 错误 -->
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>
<!-- thymeleaf legacyhtml5 模式支持 -->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
<!-- 测试支持 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- tomcat的支持.-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.23</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version> 4.12</version>
</dependency>
<!-- commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- hsqldb -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
粘贴过去之后,IDE 会弹出提示,点击 Import Changes 或 Enable Auto-Import 都可以。
接下来就等待依赖的自动安装。过程可能比较长。如果自动安装的过程没有执行,可以在 pom.xml
上右键,选择 Maven -> Reimport 。
配置完依赖后,还需要配置数据库。打开 src\main\resources\application.properties
,在原来的基础上,添加如下语句
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/white_jotter?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = none
注意端口、数据库名、用户名、密码要与你想使用的数据库一致。
2.登录控制器
配置完成后,我们就可以完善登录控制器了。
User 类
首先,我们修改 User 类代码如下,以建立对数据库的映射。
package com.evan.wj.pojo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
@Entity
@Table(name = "user")
@JsonIgnoreProperties({"handler","hibernateLazyInitializer"})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
int id;
String username;
String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
上面使用了一些注解,其中
@Entity 表示这是一个实体类
@Table(name=“user”) 表示对应的表名是 user
为了简化对数据库的操作,我们使用了 Java Persistence API(JPA),对于 @JsonIgnoreProperties({ “handler”,“hibernateLazyInitializer” }),解释起来比较复杂,下面的话看不懂可以忽略:
因为是做前后端分离,而前后端数据交互用的是 json 格式。 那么 User 对象就会被转换为 json 数据。 而本项目使用 jpa 来做实体类的持久化,jpa 默认会使用 hibernate, 在 jpa 工作过程中,就会创造代理类来继承 User ,并添加 handler 和 hibernateLazyInitializer 这两个无须 json 化的属性,所以这里需要用 JsonIgnoreProperties 把这两个属性忽略掉。
UserDAO
Data Access Object(数据访问对象,DAO)即用来操作数据库的对象,这个对象可以是我们自己开发的,也可以是框架提供的。这里我们通过继承 JpaRepository
的方式构建 DAO。
首先新建一个 package,命名为 dao
,然后创建 Java Class,命名为 UserDAO
,选择种类为 Interface
代码如下
package com.evan.wj.dao;
import com.evan.wj.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserDAO extends JpaRepository<User,Integer> {
User findByUsername(String username);
User getByUsernameAndPassword(String username,String password);
}
这里关键的地方在于方法的名字。由于使用了 JPA,无需手动构建 SQL 语句,而只需要按照规范提供方法的名字即可实现对数据库的增删改查。
如 findByUsername
,就是通过 username
字段查询到对应的行,并返回给 User 类。
这里我们构建了两个方法,一个是通过用户名查询,一个是通过用户名及密码查询。
UserService
新建 package,命名为 service
,新建 Java Class,命名为 UserService
,代码如下
package com.evan.wj.service;
import com.evan.wj.dao.UserDAO;
import com.evan.wj.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
UserDAO userDAO;
public boolean isExist(String username) {
User user = getByName(username);
return null!=user;
}
public User getByName(String username) {
return userDAO.findByUsername(username);
}
public User get(String username, String password){
return userDAO.getByUsernameAndPassword(username, password);
}
public void add(User user) {
userDAO.save(user);
}
}
这里实际上是对 UserDAO
进行了二次封装,一般来讲,我们在 DAO 中只定义基础的增删改查操作,而具体的操作,需要由 Service 来完成。当然,由于我们做的操作原本就比较简单,所以这里看起来只是简单地重命名了一下,比如把 “通过用户名及密码查询并获得对象” 这种方法命名为 get
。
LoginController
登录控制器是我们功能的核心部分,尽管它十分简单。逻辑上面已经讲过了,具体的实现,就是通过 UserService
提供的 get
方法查询数据库,如果返回的对象为空,则验证失败,否则就验证成功。代码如下
package com.evan.wj.controller;
import com.evan.wj.pojo.User;
import com.evan.wj.result.Result;
import com.evan.wj.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;
@Controller
public class LoginController {
@Autowired
UserService userService;
@CrossOrigin
@PostMapping(value = "/api/login")
@ResponseBody
public Result login(@RequestBody User requestUser) {
String username = requestUser.getUsername();
username = HtmlUtils.htmlEscape(username);
User user = userService.get(username, requestUser.getPassword());
if (null == user) {
return new Result(400);
} else {
return new Result(200);
}
}
}
这个没有其它要说的,忘记了怎么回事的话可以回过头看下上一篇文章
Vue.js + Spring Boot 前后端分离项目实践(三):前后端结合测试(登录页面开发)
我们的项目会在很长一段时间内采取这种简单的三层架构(DAO + Service + Controller),希望大家能慢慢体会这三个模块的分工。这里我简单总结一下,先有个初步印象:
- DAO 用于与数据库的直接交互,定义增删改查等操作
- Service 负责业务逻辑,跟功能相关的代码一般写在这里,编写、调用各种方法对 DAO 取得的数据进行操作
- Controller 负责数据交互,即接收前端发送的数据,通过调用 Service 获得处理后的数据并返回
在实践中我们倾向于让 Controller 显得清凉一些,以方便代码的阅读者寻找分析功能的入口。但由于教程中各个层的迭代并不是同步的,可能会暂时舍弃这个原则,后期会逐渐重构。
3.测试
同时运行前端项目 wj-vue
与后端项目 wj
,访问 http://localhost:8080/#/login
,输入用户名 admin
,密码 123456
,我去,没进去!没进去就对了,因为数据库中 admin
的密码式 123
啊。
重新输入密码 123
,成功进入 localhost:8080/#/index
OK,截至目前,前后端、数据库之间的关系都打通了。下一篇我打算讲讲怎么做表面功夫,即通过 Element 优化前端的界面。
Spring Boot +Vue 项目实战笔记(三):数据库的引入的更多相关文章
- Spring Boot +Vue 项目实战笔记(二):前后端结合测试(登录页面开发)
前言:关于开发环境 每位 Coder 都有自己偏好的开发工具,从大的方面划分主要有文本编辑器流和 IDE 流两种,我有一段时间也喜欢用编辑器(Sublime Text.Vim),但对我来说开发效率确实 ...
- Spring Boot +Vue 项目实战笔记(一):使用 CLI 搭建 Vue.js 项目
前言 从这篇文章开始,就进入真正的实践了. 在前端项目开发中,我们可以根据实际情况不同程度地使用 Vue.利用 Vue CLI(或写成 vue-cli,即 Vue 脚手架)搭建出来的项目,是最能体现 ...
- Spring Boot 揭秘与实战(三) 日志框架篇 - 如何快速集成日志系统
文章目录 1. 默认的日志框架 logback2. 常用的日志框架 log4j 1.1. 日志级别 1.2. 日志文件 3. 源代码 Java 有很多日志系统,例如,Java Util Logging ...
- 一文搞定Spring Boot + Vue 项目在Linux Mysql环境的部署(强烈建议收藏)
本文介绍Spring Boot.Vue .Vue Element编写的项目,在Linux下的部署,系统采用Mysql数据库.按照本文进行项目部署,不迷路. 1. 前言 典型的软件开发,经过" ...
- 从零开始Vue项目实战(三)-项目结构
目录结构 ├── README.md 项目介绍 ├── index.html 入口页面 ├── build 构建脚本目录 │ ├── build-server.js 运行本地构建服务器,可以访问构建后 ...
- 【慕课网实战】Spark Streaming实时流处理项目实战笔记三之铭文升级版
铭文一级: Flume概述Flume is a distributed, reliable, and available service for efficiently collecting(收集), ...
- webpack+vue项目实战(四,前端与后端的数据交互和前端展示数据)
地址:https://segmentfault.com/a/1190000010063757 1.前言 今天要做的,就是在上一篇文章的基础上,进行功能页面的开发.简单点说呢,就是与后端的数据交互和怎么 ...
- Github点赞超多的Spring Boot学习教程+实战项目推荐!
Github点赞接近 100k 的Spring Boot学习教程+实战项目推荐! 很明显的一个现象,除了一些老项目,现在 Java 后端项目基本都是基于 Spring Boot 进行开发,毕竟它这 ...
- 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了
折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...
随机推荐
- WEB安全新玩法 [8] 阻止订单重复提交
交易订单的重复提交虽然通常不会直接影响现金流和商品流,但依然会给网站运营方带来损害,如消耗系统资源.影响正常用户订单生成.制造恶意用户发起纠纷的机会等.倘若订单对象是虚拟商品,也有可能造成实际损失.订 ...
- 图像旋转的FPGA实现(一)
继续图像处理专题,这次写的是图像旋转.若要说小分辨率的图像旋转倒也简单,直接将原始图像存储在BRAM中,然后按照旋转后的位置关系取出便是.但是对于高分辨的图像(720P及以上)就必须得用DDR3或者D ...
- python爬虫--案例分析之针对简单的html文件
python爬虫常用的库:Python 库(urllib.BeautifulSoup.requests.scrapy)实现网页爬虫 python爬虫最简单案例分析: 对一个html文件进行分解,获取 ...
- 使用Elastic Job的时候报“Job conflict with register center”,如何处理?
昨天,有群友反应根据之前这篇<使用Elastic Job实现定时任务>文章编写测试定时任务的时候,报了类似下面的这个错误: Caused by: org.apache.shardingsp ...
- (opencv09)cv2.getStructuringElement()构造卷积核
(opencv09)cv2.getStructuringElement()构造卷积核 rectkernel = cv2.getStructuringElement(shape, ksize, anch ...
- CMS垃圾收集器——重新标记和浮动垃圾的思考
<深入理解java虚拟机 第二版 JVM高级特性与最佳实践>里面提到 CMS 垃圾收集器. CMS 垃圾收集器的垃圾回收分4个步骤: 初始标记(initial mark) 有 STW 并发 ...
- 云平台制作(1)-OPC Client取数模块的制作
近来由于工程需要,基于OPC DA 2.0搭建通用的取数模块,与远程webscoket服务端连接,并传输数据.在网上找了些资料,修改相应网友公开的源代码,基本达到要求,特供大家参考. 1.实体类 us ...
- artDialog 简单几种用法
$('#btn1').click(function(){ artDialog({title:'图片查看', content:'<img width="817" ...
- vulnhub-靶机Lampiao
目标信息:攻击机IP地址:192.1681.10 Lampiao靶机IP地址:192.168.1.12 DC-1靶机IP地址:192.168.1.7 目的:获取靶机root权限和靶机设置的所有flag ...
- 天梯赛 L1-058 6翻了
传送门:https://pintia.cn/problem-sets/994805046380707840/problems/1111914599408664577 这道字符串题,只是天梯赛L1的题, ...