Spring Boot:Web应用开发之增删改查的实现

Spring Boot

  • 前言
  • 实现增删改查功能

在这里插入图片描述

前言

增删改查功能作为 Web 应用中的基础且重要的组成部分,是基本的数据库操作,也是实现业务逻辑和功能的关键要素。下面简单介绍使用 Spring Boot 实现增删改查的功能。

实现增删改查功能

在上一章 Spring Boot:Web应用开发之登录与退出的实现 文章的案例基础上,进行实现增删改查的功能。

简单示例:
首先,创建一个 PublicTemplate.html ,将 html 的公共代码抽离到这页面上,方便其他页面进行复用(使用方式:th:replace=“模版名称::模版⽚段名称”

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>公共页面-抽离与复用</title>
</head>
<body><!-- th:fragment 属性来定义被包含的模版⽚段,以供其他模版使用。模版⽚段名称为 top --><div class="header" th:fragment="header">主页面的头部区域</div><div class="center"><!-- 通用侧边栏区域 --><div class="sidebar" th:fragment="sidebar"><!-- 增强效果设置:th:class="${isActive=='Main.html'?'active':''}" 当切换到该页面时,内容设定为 active 的样式 --><a href="#" th:class="${isActive=='Main.html'?'active':''}" th:href="@{Main.html}">主页</a> <br><a href="#" th:class="${isActive=='UserList.html'?'active':''}" th:href="@{UserList.html}">用户列表</a> <br><a th:href="@{/logout.html}">退出</a></div></div><div class="footer" th:fragment="footer">主页面的脚部区域</div>
</body>
</html>

创建需要用到的页面,有公共的代码便使用 th:replace 调用

Main.html:主页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>MainDemo</title><!--  存放 css 文件默认在 static 目录下 --><link rel="stylesheet" type="text/css" th:href="@{/css/PublicCss.css}">
</head>
<body><!-- th:replace 替换整个标签到引入的文件。使用方式——th:replace="模版名称::模版⽚段名称" --><div th:replace="PublicTemplate::header"></div><dic class="center"><!-- 增强效果设置:(isActive='Main.html') --><div th:replace="PublicTemplate::sidebar(isActive='Main.html')"></div><div class="main">主页面内容</div></dic><div th:replace="PublicTemplate::footer"></div>
</body>
</html>

UserList.html:显示用户列表页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>UserListDemo</title><!--  存放 css 文件默认在 static 目录下 --><link rel="stylesheet" type="text/css" th:href="@{/css/PublicCss.css}">
</head>
<body><!-- th:replace 替换整个标签到引入的文件。使用方式——th:replace="模版名称::模版⽚段名称" --><div th:replace="PublicTemplate::header"></div><dic class="center"><div th:replace="PublicTemplate::sidebar(isActive='UserList.html')"></div><div class="main"><form th:action="UserSearch.html" method="post"><input type="text" name="searchByUsername" /><input type="submit" value="查询" /><a th:href="@{/UserAdd.html}">添加</a></form><table><tr><td>id</td><td>账号</td><td>密码</td><td>注册时间</td><td>地址</td><td>操作</td></tr><tr th:each="user:${users}"><td th:text="${user.id}"></td><td th:text="${user.username}"></td><td th:text="${user.password}"></td><td th:text="${user.regDate}"></td><td th:text="${user.address}"></td><td><a th:href="@{/UserDelete.html(id=${user.id})}" onclick="return confirm('确定要删除吗?')">删除</a><a th:href="@{/UserUpdate.html(id=${user.id})}">修改</a></td></tr></table></div></dic><div th:replace="PublicTemplate::footer"></div></body>
</html>

UserAdd.html:添加用户页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>UserAddDemo</title>
</head>
<body><form th:action="@{/UserAdd.html}" method="post">账号:<input type="text" name="username"/> <br>密码:<input type="text" name="password"/> <br>地址:<select name="address.id"><option th:value="${address.id}" th:each="address:${addresses}">[[${address.addressInfo}]]</option></select> <br><input type="submit" th:value="添加"></form>
</body>
</html>

UserUpdate.html:修改用户页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>UserUpdateDemo</title>
</head>
<body><div class="main"><form th:action="@{/UserUpdate.html}" method="post"><input type="hidden" name="id" th:value="${user.id}">账号:<input type="text" name="username" th:value="${user.username}"/> <br>密码:<input type="text" name="password" th:value="${user.password}"/> <br>注册时间:<input type="text" name="regDate" th:value="${#dates.format(user.regDate,'yyyy-MM-dd HH:mm:ss')}"/> <br>地址:<select name="address.id"><option th:value="${address.id}" th:selected="${user.address.id == address.id}" th:each="address:${addresses}">[[${address.addressInfo}]]</option></select> <br><input type="submit" th:value="修改"></form></div>
</body>
</html>

然后,在 User 实体类上使用 @DateTimeFormat 注解指定日期样式(否则在修改注册时间时,会出现类型转换问题),再创建一个 Address 类
在这里插入图片描述

package cn.edu.SpringBootWebDemo.Entity;import jakarta.persistence.*;@Entity
@Table(name = "address")
public class Address {private int id;private String addressInfo; // 地址详情@Id@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增public int getId() {return id;}public void setId(int id) {this.id = id;}@Column(name = "address_info") // 指定字段名public String getAddressInfo() {return addressInfo;}public void setAddressInfo(String addressInfo) {this.addressInfo = addressInfo;}@Overridepublic String toString() {return "Address{" +"id=" + id +", addressInfo='" + addressInfo + '\'' +'}';}
}

随之,在 UserDao 接口上声明一个模糊查询方法,在 AddressDao 接口上直接继承 JpaRepository<实体类,主键类型> 即可
在这里插入图片描述
在这里插入图片描述

接着,在 Service 包内创建一个 UserService 接口,声明增删改查方法,并创建一个 UserServiceImpl 实现类实现该接口方法; AddressService 接口与 AddressServiceImpl 实现类同理

UserService 接口:

package cn.edu.SpringBootWebDemo.Service;import cn.edu.SpringBootWebDemo.Entity.User;import java.util.List;public interface UserService {public User login(User user);//增删改查public void add(User user);public void delete(int id);public void update(User user);public User get(int id);public List<User> getALLUsers();public List<User> getByUsernameLike(String string);
}

UserServiceImpl 实现类:

package cn.edu.SpringBootWebDemo.Service;import cn.edu.SpringBootWebDemo.Dao.UserDao;
import cn.edu.SpringBootWebDemo.Entity.User;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service("userService")
@Transactional // 放在类上,类上的所有方法都支持事务;也可以只放在一个方法上,只指定那个方法支持事务
public class UserServiceImpl implements UserService{@Autowiredprivate UserDao userDao;@Overridepublic User login(User user) {// 根据用户名查询有没有对应的账号User user1 = userDao.getByUsername(user.getUsername());// 判断是否为空或密码错误,登录失败返回 nullif (user1 == null) return null;if(!user1.getPassword().equals(user.getPassword())) return null;// 返回 User 对象,登录成功return user1;}@Overridepublic void add(User user) {userDao.save(user);}@Overridepublic void delete(int id) {userDao.deleteById(id);}@Overridepublic void update(User user) {userDao.saveAndFlush(user);}@Overridepublic User get(int id) {return userDao.findById(id).get();}@Overridepublic List<User> getALLUsers() {return userDao.findAll();}@Overridepublic List<User> getByUsernameLike(String string) {return userDao.getByUsernameLike(string);}
}

AddressService 接口:

package cn.edu.SpringBootWebDemo.Service;import cn.edu.SpringBootWebDemo.Entity.Address;import java.util.List;public interface AddressService {public void add(Address address);public void delete(int id);public void update(Address address);public Address get(int id);public List<Address> getAllAddress();
}

AddressServiceImpl 实现类:

package cn.edu.SpringBootWebDemo.Service;import cn.edu.SpringBootWebDemo.Dao.AddressDao;
import cn.edu.SpringBootWebDemo.Entity.Address;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class AddressServiceImpl implements AddressService{@Autowiredprivate AddressDao addressDao;@Overridepublic void add(Address address) {addressDao.save(address);}@Overridepublic void delete(int id) {addressDao.deleteById(id);}@Overridepublic void update(Address address) {addressDao.saveAndFlush(address);}@Overridepublic Address get(int id) {return addressDao.findById(id).get();}@Overridepublic List<Address> getAllAddress() {return addressDao.findAll();}
}

再在 Controller 包内的 UserController 控制类上处理用户相关的 HTTP 请求

package cn.edu.SpringBootWebDemo.Controller;import cn.edu.SpringBootWebDemo.Entity.Address;
import cn.edu.SpringBootWebDemo.Entity.User;
import cn.edu.SpringBootWebDemo.Service.AddressService;
import cn.edu.SpringBootWebDemo.Service.UserService;
import jakarta.servlet.http.HttpSession;
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.PostMapping;import java.util.Date;
import java.util.List;@Controller
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate AddressService addressService;@GetMapping("/Login.html")public String login(HttpSession httpSession){// 成功登录后不能再返回登录页面,而是跳转到主页boolean flag = httpSession.getAttribute("loginUser")==null?true:false;if (flag){return "Login";}else {return "redirect:/Main.html";}}@GetMapping("/Main.html")public String main(){return "Main";}// 判断登录@PostMapping("/Login.html")public String login(User user, HttpSession httpSession, Model model){// 控制层——接受页面的账号和密码。调用服务层的 login 方法,判断登录是否成功。// 成功将返回的 user 对象保存到 session 的域空间;反之返回一个错误提示。User user1 = userService.login(user);if(user1 != null) {// 将返回的 user 对象保存到 session 的域空间,页面跳转到主页中httpSession.setAttribute("loginUser",user1);return "redirect:/Main.html";}else {// 登录失败,返回错误提示model.addAttribute("loginError","用户名或密码错误!");return "Login";}}// 退出@GetMapping("/logout.html")public String logout(HttpSession httpSession){// 通过 invalidate 方法清空 httpSession 里的内容httpSession.invalidate();return "redirect:/Login.html";}// 显示用户@GetMapping("/UserList.html")public String userlist(Model model){List<User> users = userService.getALLUsers();model.addAttribute("users",users);System.out.println(users);return "UserList";}// 模糊查询用户@PostMapping("/UserSearch.html")// 接受的参数,searchByUsername 名字与页面 input 标签的 name 属性值一致public String userSearch(String searchByUsername,Model model){List<User> users = userService.getByUsernameLike("%" + searchByUsername + "%");model.addAttribute("users",users);return "UserList";}// 先获取所有的地址信息,再进行添加用户@GetMapping("/UserAdd.html")public String addUser(Model model){List<Address> addresses = addressService.getAllAddress();model.addAttribute("addresses",addresses);return "UserAdd";}@PostMapping("/UserAdd.html")public String addUser(User user){user.setRegDate(new Date());userService.add(user);return "redirect:/UserList.html";}// 修改实现:1.点击修改按钮,打开修改页面@GetMapping("/UserUpdate.html")public String updateUser(Model model,Integer id){// 获取指定用户信息User user = userService.get(id);model.addAttribute("user",user);// 获取指定地址信息List<Address> addresses = addressService.getAllAddress();model.addAttribute("addresses",addresses);return "UserUpdate";}// 2.修改实现@PostMapping("/UserUpdate.html")public String updateUserAchieve(User user){userService.update(user);return "redirect:/UserList.html";}// 删除用户@GetMapping("/UserDelete.html")public String deleteUser(Integer id){userService.delete(id);return "redirect:/UserList.html";}
}

最后,在 SpringBootWebDemoApplication 启动类上使用 @EnableTransactionManagement 注解开启事务,并启动 Spring Boot 进行测试

package cn.edu.SpringBootWebDemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;@EnableTransactionManagement // 开启事务
@SpringBootApplication
public class SpringBootWebDemoApplication {// 获取事务管理器类型
//    @Bean
//    public Object testBean(PlatformTransactionManager platformTransactionManager){
//        System.out.println("事务管理器类型:" + platformTransactionManager.getClass().getName());
//        return new Object();
//    }// 指定事务管理器,设置后会覆盖默认的事务管理器
//    @Bean
//    public PlatformTransactionManager manager(DataSource dataSource){
//        return new DataSourceTransactionManager(dataSource);
//    }public static void main(String[] args) {SpringApplication.run(SpringBootWebDemoApplication.class, args);}}

结果如图:
1.登录,进入主页
在这里插入图片描述

2.点击用户列表,进入显示用户列表页面
在这里插入图片描述

3.在显示用户列表页面上,进行模糊查询,输入 “刘” 点击查询
在这里插入图片描述
模糊查询结果:
在这里插入图片描述

4.在显示用户列表页面上,点击添加,进入添加页面,输入用户信息,点击添加用户
在这里插入图片描述
添加用户结果:
在这里插入图片描述

5.在显示用户列表页面上,点击修改,进入修改页面,修改用户信息,点击修改用户
在这里插入图片描述
修改用户结果:
在这里插入图片描述

6.在显示用户列表页面上,点击删除,弹出确认窗口,点击确定
在这里插入图片描述
删除用户结果:
在这里插入图片描述

Web 应用开发案例中的主要目录结构:
在这里插入图片描述

PublicCss.css:设置页面样式的文本文件

body{background-image: url("../img/background-image.png");background-attachment: fixed;background-size: cover;background-repeat: no-repeat;
}.header{text-align: center;height: 90px;line-height: 90px;width: 100%;border: 2px black solid;
}.center{width: 100%;height: 450px;
}.center .sidebar{width: 120px;height: 550px;float: left;border: 2px black solid;
}.center .main{width: 100%;height: 550px;border: 2px black solid;
}table{border-collapse: collapse;
}th, td {border: 1px silver solid;padding: 0.3em 1em;
}.footer{text-align: center;height: 90px;line-height: 90px;width: 100%;border: 2px black solid;
}/* 增强效果设置 */
.active{color: darkturquoise;text-decoration: none;
}

background-image.png:页面背景图片
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2981229.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

安装无法完成。安装Autodesk产品时出现错误103

解决方法如下 打开autoremove&#xff0c;点击扩展功能&#xff0c;输入103&#xff0c;点击搜索 注意 修复过程根据情况可能会很慢 等待提示修复成功&#xff0c;再尝试重新安装软件。 软件每周六选择其他方式登录免费使用

海康Visionmaster-常见问题排查方法-启动失数

问题2&#xff1a;VM无法启动&#xff0c;报错&#xff1a;参数错误&#xff1b;  问题原因&#xff1a;客户电脑环境异常导致代理启动失败。  解决方法&#xff1a;安装运行时库&#xff0c;并测试代理能否正常启动,步骤如下&#xff1a; ① 尝试双击代理进程&#xff…

Linux之yum和vim的使用

一、yum的使用 yum 后面跟install要安装的文件名&#xff1a; 若你要安装的文件已经存在&#xff0c;则会出现&#xff1a; 要删除文件&#xff1a; yum remore文件名即可删除 在我们安装完lrzsz之后&#xff0c;可以用rz指令和sz指令&#xff1a; rz指令可以从window窗口中…

【Linux开发实用篇】Webmin和宝塔

可视化工具 Webmin宝塔 Webmin Webmin是功能强大的基于Web的Linux/Unix管理工具 下载地址&#xff1a;http://download.webmin.com/download/yum/ 使用wget指令下载&#xff1a;http://download.webmin.com/download/yum/webmin-1.700-1.noarch.rpm 然后进行安装&#xff1a; …

第07-5章 传输层详解

7.1 传输层概述 分段及封装应用层送来的数据&#xff1a;应用层以字节流的形式给传输层传输数据&#xff0c;传输层会把字节流分段&#xff0c;并给每段封装 由应用程序产生应用进程&#xff0c;由应用进程产生进程端口号&#xff0c;由端口号提供相应的服务 如何查看本…

项目实践---贪吃蛇小游戏(下)

对于贪吃蛇小游戏&#xff0c;最主要的还是主函数部分&#xff0c;这里就和大家一一列举出来&#xff0c;上一章已经写过头文件了&#xff0c;这里就不多介绍了。 首先就是打印桌面&#xff0c;也就是背景&#xff0c;则对应的代码为&#xff1a; void SetPos(short x, short …

(四)Servlet教程——Maven的安装与配置

1.在C盘根目录下新建一个Java文件夹,该文件夹用来放置以下步骤下载的Maven&#xff1b; 2. 下载Maven的来源有清华大学开源软件镜像站和Apache Maven的官网&#xff0c;由于清华大学开源软件镜像站上只能下载3.8.8版本以上的Maven&#xff0c;我们选择在Apache Maven的官网上下…

VulnHub靶机 DC-8 打靶实战 详细渗透过程

VulnHub靶机 DC-8 打靶 详细渗透过程 目录 VulnHub靶机 DC-8 打靶 详细渗透过程一、将靶机配置导入到虚拟机当中二、渗透测试流程主机发现端口扫描Web渗透SQL注入登录后台反弹shell提权 一、将靶机配置导入到虚拟机当中 靶机地址&#xff1a; https://www.vulnhub.com/entry/…

Docker容器概念介绍与基本管理

前言 在软件开发和部署环境中&#xff0c;使用 Docker 等容器技术可以帮助团队实现快速、一致、可靠的应用程序部署&#xff0c;提高开发效率和应用程序的可移植性。 目录 一、虚拟化产品介绍 1. 云服务模型 1.1 IaaS 1.2 PaaS 1.3 SaaS 1.4 DaaS 2. 产品介绍 2.1 虚…

BUUCTF---[SWPU2019]神奇的二维码

1、下载附件是一张二维码&#xff0c;拿去扫描得到了flag 2、拿去提交是错的&#xff08;不会这么简单哈哈哈&#xff09;&#xff0c;常规操作在kali中分析 3、分离发现图片里面有东西 4、查看txt&#xff0c;发现里面有一串字符&#xff0c;解码后为 5、查看文档&#xff0c…

「ChatGPT」掀起新一轮AI热潮!超越GPT-4 Turbo,商汤日日新大升级!

目录 拳打 GPT-4 Turbo &#xff0c;脚踢 DALLE 3 端侧大模型&#xff0c;唯快不破 AI 应用落地需要一个即插即用的大模型超市 并不存在 AI 这个行业&#xff0c;只有 AI行业&#xff0c;强调 AI 需要与传统产业合作&#xff0c;这种关系是结合与赋能&#xff0c;而不是颠覆…

【提示学习论文】BlackVIP: Black-Box Visual Prompting for Robust Transfer Learning论文原理

BlackVIP: Black-Box Visual Prompting for Robust Transfer Learning BlackVIP:稳健迁移学习的黑盒视觉提示 问题 黑盒白盒&#xff1f; 黑盒和白盒的概念与对预训练模型内部参数的了解程度相关。黑盒指的是对预训练模型的参数和结构缺乏详细了解&#xff0c;通常只能通过使…

Python自学之路--001:Python + PyCharm安装图文详解教程

目录 1、概述 2、Python解释器 2.1、下载 2.2、Python安装 2.3、Python环境变量配置&#xff0c;必选项 3、PyCharm安装 3.1、PyCharm下载 3.2、PyCharm安装 4、建一个Hello World 5、Phcarm设置 5.1、Phcarm汉化 5.2、Phcarm工具栏显示在顶部 5.3、Phcarm通过pip安…

[2021年最新]国产时序性数据TDenige入门

一、TDenige简介 TDengine&#xff1a;是涛思数据面对高速增长的物联网大数据市场和技术挑战推出的创新性的大数据处理产品&#xff0c;它不依赖任何第三方软件&#xff0c;也不是优化或包装了一个开源的数据库或流式计算产品&#xff0c;而是在吸取众多传统关系型数据库、NoS…

25计算机考研院校数据分析 | 复旦大学

复旦大学(fudan University)&#xff0c;简称"复旦”&#xff0c;位于中国上海&#xff0c;由中华人民共和国教育部直属&#xff0c;中央直管副部级建制&#xff0c;位列985工程、211工程、双一流A类&#xff0c;入选“珠峰计划"、"111计划""2011计划…

zabbix自动发现和自动注册

一、zabbix自动发现 1.1 确保客户端上的zabbix-agent2服务器状态正常 1.2 在web页面删除原有的客户端主机 1.3 在服务端和客户端上配置hosts 1.4 web端配置自动发现 二、zabbix自动注册 2.1 环境配置 2.2 修改zabbix-agent2配置文件 过滤非#或非&#xffe5;开头的内容 2.3 we…

应用实战|只需几步,即可享有外卖订餐小程序

本示例是一个简单的外卖查看店铺点菜的外卖微信小程序&#xff0c;小程序后端服务使用了MemFire Cloud&#xff0c;其中使用到的MemFire Cloud功能包括&#xff1a; 其中使用到的MemFire Cloud功能包括&#xff1a; 云数据库&#xff1a;存储外卖微信小程序所有数据表的信息。…

解决Linux CentOS 7安装了vim编辑器却vim编辑器不起作用、无任何反应

文章目录 前言一、解决vim不起作用&#xff08;卸载重新安装&#xff09;1.重新安装vim2.测试vim是否能正常使用 二、解决vim: error while loading shared libraries: /lib64/libgpm.so.2: file too short报错三、解决vim编辑器不能使用方向键和退格键问题 remove vim-common …

【S32DS RTD实战】-1.5-S32DS使用Post-Build调用第三方插件-自动对生成的s19,Hex,Bin文件二次编辑

<--返回「Autosar_MCAL高阶配置」专栏主页--> 案例背景&#xff1a; 在《【S32DS RTD实战】-1.3-S32K3工程生成S19&#xff0c;BIN&#xff0c;Hex文件&#xff0c;以及Post-build steps的妙用_s32ds如何生成s19或hex文件-CSDN博客https://blog.csdn.net/qfmzhu/articl…

C++“流”风格日志系统实战-课程简介

一个能快速提升C复杂代码设计的学习项目&#xff0c;一个能迅速让C面试官会心一笑的简历项目&#xff0c;一个能在实际项目中使用的项目……学习什么是流&#xff1f;如何利用抽象层面的流编写适用面更广的代码&#xff1f; 每天在用的cout和cin 它们是什么类型&#xff1f;最后…