综合实践:JPA+Thymeleaf 增删改查

ops/2024/10/11 13:22:27/
htmledit_views">

目录

构建项目

1.创建项目

2.pom.xml文件,依赖项

模型开发

1.实体类

2.Mapper

3.MyBatis Mapper SQL

4.Service层

功能实现

登录

列表

新增

删除


构建项目

1.创建项目

2.pom.xml文件,依赖项

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version><relativePath /> <!-- lookup parent from repository --></parent><groupId>com.bdqn</groupId><artifactId>JPA-html" title=Thymeleaf>Thymeleaf</artifactId><version>0.0.1-SNAPSHOT</version><name>JPA-html" title=Thymeleaf>Thymeleaf</name><description>JPA-html" title=Thymeleaf>Thymeleaf</description><properties><html" title=java>java.version>21</html" title=java>java.version></properties><dependencies><!-- 引入SpringBoot的Web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>6.3.3</version></dependency><!-- 引入JSP引擎依赖,SpringBoot内置Tomcat没有此依赖 --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId></dependency><!-- 引入JSTL标签库依赖 --><dependency><groupId>html" title=java>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!-- 引入MyBatis-Plus支持(不需要再引入MyBatis包) --><dependency><groupId>com.baomidou</groupId><artifactId>html" title=mybatis>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.7</version></dependency><!-- 引入Druid数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.20</version></dependency><!-- 引入MySQL驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- 引入Lombok完成实体类自动Getter/Setter --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 引入Slf4j日志依赖 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId></dependency><!-- 引入SpringBoot测试依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.4.1</version></dependency><!-- 配置处理依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!-- 配置热部署 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- thymeleaf依赖布局 --><dependency><groupId>nz.net.ultraq.thymeleaf</groupId><artifactId>thymeleaf-layout-dialect</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

模型开发

1.实体类

User

html" title=java>java">@Data
@ToString
@TableName("sys_user")
public class User implements Serializable {@TableId(type = IdType.AUTO)@TableField("usr_id")private Long usrId;private String usrName;private String usrPassword;@TableField("usr_role_id")private long usrRoleId;@TableField(exist = false)private Role role; // 角色信息private Integer usrFlag;public User(String usrName, String usrPassword, long usrRoleId, Integer usrFlag) {this.usrName = usrName;this.usrPassword = usrPassword;this.usrRoleId = usrRoleId;this.usrFlag = usrFlag;}}

Role

html" title=java>java">@Data
@ToString
@TableName("sys_role")
@JsonIgnoreProperties(value = {"hibernateLazyInitializer","handler"})
public class Role implements Serializable {@TableId(type = IdType.AUTO)private Long roleId;private String roleName;private String roleDesc;private Long roleFlag;
}

2.Mapper

UserMapper

html" title=java>java">public interface UserMapper extends BaseMapper<User> {User login(@Param("usrName") String usrName, @Param("usrPassword")String usrPassword);Page<User> userPage(@Param("roleId")Long roleId, @Param("usrName") String usrName, Page<User> page);User getUserByName(String usrName);int add(User user);int del(Long usrId);User getUser(Long usrId);}

3.MyBatis Mapper SQL

html" title=java>java">    <!-- 映射器 --><resultMap id="loginMap" type="com.bdqn.pojo.User"><id column="usr_id" property="usrId" /><association property="role" html" title=java>javaType="com.bdqn.pojo.Role"><id column="role_id" property="roleId" /><result column="role_name" property="roleName" /><result column="role_desc" property="roleDesc" /><result column="role_flag" property="roleFlag" /></association></resultMap><!-- 添加 --><insert id="add">insertsys_user (usr_name,usr_password,usr_role_id,usr_flag)values (#{usrName},#{usrPassword},#{usrRoleId},#{usrFlag})</insert><!-- 删除 --><delete id="del">deletefrom sys_userwhere usr_id = #{usrId}</delete><!-- 登录 --><select id="login" resultMap="loginMap">select *from sys_user uleft join sys_role r on u.usr_role_id = r.role_idwhere u.usr_name = #{usrName}and u.usr_password = #{usrPassword}</select><!-- 根据角色和姓名查询列表及分页 --><select id="userPage" resultMap="loginMap">select a.*,b.* from sys_user aleft join sys_role b on a.usr_role_id=b.role_id<where><if test="usrName!=null">and a.usr_name like CONCAT('%' , #{usrName} , '%')</if><if test="roleId != null and roleId!=0">and a.usr_role_id=#{roleId}</if></where></select><!-- 查询姓名是否重复 --><select id="getUserByName" resultType="com.bdqn.pojo.User">select *from sys_userwhere usr_name = #{usrName}</select><!-- 根据Id查询个人信息 --><select id="getUser" resultType="com.bdqn.pojo.User">select *from sys_userwhere usr_id = #{usrId}</select>

4.Service层

html" title=java>java">@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {@Resourceprivate UserMapper userMapper;@Overridepublic User login(String usrName, String usrPassword) {return userMapper.login(usrName, usrPassword);}@Overridepublic User getUser(Long usrId) {return userMapper.getUser(usrId);}@Overridepublic Page<User> userPage(Long roleId, String usrName, Page<User> page){return userMapper.userPage(roleId,usrName,page);}@Overridepublic User getUserByName(String usrName) {return userMapper.getUserByName(usrName);}@Overridepublic int add(User user) {return userMapper.add(user);}@Overridepublic int del(Long usrId) {return userMapper.del(usrId);}}

功能实现

登录

html"><!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>登录</title><!-- css --><link th:href="@{/css/bootstrap.min.css}" href="../static/css/bootstrap.min.css" rel="stylesheet" /><link th:href="@{/css/font-awesome.min.css}" href="../static/css/font-awesome.min.css" rel="stylesheet"><link th:href="@{/css/nprogress.css}" href="../static/css/nprogress.css" rel="stylesheet"><link th:href="@{/css/green.css}" href="../static/css/green.css" rel="stylesheet"><link th:href="@{/css/bootstrap-progressbar-3.3.4.min.css}" href="../static/css/bootstrap-progressbar-3.3.4.min.css" rel="stylesheet"><link th:href="@{/css/jqvmap.min.css}" href="../static/css/jqvmap.min.css" rel="stylesheet" /><link th:href="@{/css/dropzone.min.css}" href="../static/css/dropzone.min.css" rel="stylesheet"><link th:href="@{/css/custom.min.css}" href="../static/css/custom.min.css" rel="stylesheet"></head>
<body class="login">
<div><a class="hiddenanchor" id="signup"></a><a class="hiddenanchor" id="signin"></a><div class="login_wrapper"><div class="animate form login_form"><section class="login_content"><form action="/doLogin" th:action="@{/doLogin}" method="post"><h1>欢迎登陆</h1><div><span th:text="${message }" style="color: #ff0000"></span></div><div><input type="text" class="form-control" name="usrName" placeholder="用户名" required="" /></div><div><input type="password" class="form-control" name="usrPassword" placeholder="密码" required="" /></div><div><button type="submit" class="btn btn-success">登    录</button><button type="reset" class="btn btn-default">重    置</button></div><div class="clearfix"></div><div class="separator"><div class="clearfix"></div><br /><div><p>©2019 All Rights Reserved 腾跃科技</p></div></div></form></section></div></div>
</div>
</body>
</html>
html" title=java>java">    @PostMapping("/doLogin")public String doLogin(String usrName, String usrPassword, Model model, HttpSession session) {User user = userService.login(usrName, usrPassword);if (user != null) {session.setAttribute("loginUser", user);return "redirect:/main";} else {model.addAttribute("msg", "用户名或密码错误,登录失败!");return "/login";}}

列表

html"><!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{main}"xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
>
<head><title>用户管理</title><link th:href="@{/localcss/crmlist.css}" href="../../static/localcss/crmlist.css" rel="stylesheet">
</head>
<body>
<div layout:fragment="content"><div class=""><div class="clearfix"></div><div class="row"><div class="col-md-12"><div class="x_panel"><div class="x_title"><h2>用户管理 <i class="fa fa-user"></i><small>- 您可以通过搜索或者其他的筛选项对用户的信息进行编辑、删除等管理操作。^_^</small></h2><div class="clearfix"></div></div><div class="x_content"><form method="post" action="/user/list" th:action="@{/user/list}"><input type="hidden" name="pageIndex" value="1" /><ul><li><div class="form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12">用户名称</label><div class="col-md-6 col-sm-6 col-xs-12"><input name="usrName" type="text" th:value="${usrName}"class="form-control col-md-6 col-xs-12" value=""></div></div></li><li><div class="form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12">角色</label><div class="col-md-6 col-sm-6 col-xs-12"><select name="roleId" id="roleId" class="form-control"><option value="0">--请选择--</option><option th:selected="${role.roleId eq roleId}" th:each="role : ${roles}"th:value="${role.roleId}" th:text="${role.roleName}" value="">角色1</option></select></div></div></li><li><button type="submit" class="btn btn-primary"> 查&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;询</button></li></ul></form></div></div></div><div class="col-md-12 col-sm-12 col-xs-12"><div class="x_panel"><div class="x_content"><p class="text-muted font-13 m-b-30"></p><div id="datatable-responsive_wrapper"class="dataTables_wrapper form-inline dt-bootstrap no-footer"><div class="row"><div class="col-sm-12"><!-- <a href="/user/add" th:href="@{/user/add}" shiro:hasPermission="用户添加" class="btn btn-success btn-sm">新增用户信息</a> --><a href="/user/add" th:href="@{/user/add}" class="btn btn-success btn-sm">新增用户信息</a><table id="datatable-responsive"class="table table-striped table-bordered dt-responsive nowrap dataTable no-footer dtr-inline collapsed"cellspacing="0" width="100%" role="grid"aria-describedby="datatable-responsive_info" style="width: 100%;"><thead><tr role="row"><th class="sorting_asc" tabindex="0"aria-controls="datatable-responsive" rowspan="1" colspan="1"aria-label="First name: activate to sort column descending"aria-sort="ascending">编号</th><th class="sorting" tabindex="0"aria-controls="datatable-responsive" rowspan="1" colspan="1"aria-label="Last name: activate to sort column ascending">用户名</th><th class="sorting" tabindex="0"aria-controls="datatable-responsive" rowspan="1" colspan="1"aria-label="Last name: activate to sort column ascending">角色</th><th class="sorting" tabindex="0"aria-controls="datatable-responsive" rowspan="1" colspan="1"aria-label="Last name: activate to sort column ascending">操作</th></tr></thead><tbody><tr role="row" class="odd" th:each="user : ${userPager.records}"><td tabindex="0" class="sorting_1" th:text="${user.usrId}">usrId</td><td th:text="${user.usrName}">usrName</td><td th:text="${user.role.roleName}">roleName</td><td><div class="btn-group"><button type="button" class="btn btn-danger">点击操作</button><button type="button" class="btn btn-danger dropdown-toggle"data-toggle="dropdown" aria-expanded="false"><span class="caret"></span><span class="sr-only">Toggle Dropdown</span></button><ul class="dropdown-menu" role="menu"><li><a class="editInfo"href="/user/edit?usrId=1"th:href="@{/user/edit(usrId=${user.usrId})}"data-toggle="tooltip"data-placement="top" title=""data-original-title="编辑">编辑</a></li><li><a class="delInfo" id="del" href="#"th:onclick="|doDel(this,${user.usrId})|"data-toggle="tooltip" data-placement="top" title=""data-original-title="删除">删除</a></li></ul></div></td></tr></tbody></table></div></div><div class="row"><div class="col-sm-5"><div class="dataTables_info" id="datatable-responsive_info"role="status" aria-live="polite">共<span th:text="${userPager.getTotal() }">1</span>条记录<span th:text="${userPager.current }">1</span>/<spanth:text="${userPager.pages }">1</span>页</div></div><div class="col-sm-7"><div class="dataTables_paginate paging_simple_numbers"id="datatable-responsive_paginate"><ul class="pagination"><li class="paginate_button previous" th:if="${userPager.current gt 0}"><ahref="html" title=java>javascript:page_nav(document.forms[0],1);"aria-controls="datatable-responsive" data-dt-idx="0"tabindex="0">首页</a></li><li class="paginate_button" th:if="${userPager.current gt 1}"><a href="#"th:onclick="'html" title=java>javascript:page_nav(document.forms[0],'+${userPager.current - 1 }+');'"aria-controls="datatable-responsive"data-dt-idx="1"tabindex="0">上一页</a></li><li class="paginate_button "th:if="${(userPager.current) lt userPager.pages}"><ahref="#"th:onclick="'html" title=java>javascript:page_nav(document.forms[0],'+${userPager.current + 1 }+');'"aria-controls="datatable-responsive" data-dt-idx="1"tabindex="0">下一页</a></li><li class="paginate_button next"th:if="${(userPager.current) lt userPager.total}"><ahref="#"th:onclick="'html" title=java>javascript:page_nav(document.forms[0],'+${userPager.pages }+');'"aria-controls="datatable-responsive" data-dt-idx="7"tabindex="0">最后一页</a></li></ul></div></div></div></div></div></div></div></div></div>
</div>
</body>
<script layout:fragment="js" th:inline="html" title=java>javascript">// 获取项目路径/*<![CDATA[*/var ctxPath = /*[[@{/}]]*/ '';/*]]>*/function doDel(obj, usrId) {if (confirm("你确定需要删除该用户信息吗?")) {$.ajax({type: "POST",url: ctxPath + "user/del/" + usrId,/*data: {"usrId": usrId},*/dataType: "json",success: function (data) {// alert(JSON.stringify(data)); // {"result":"true"}if (data.result === "true") { // 删除成功:移除删除行alert("删除成功!");$(obj).parents("tr").remove();// window.location.href = project_name() + "/user/list";}},error: function (data) {alert("对不起,删除失败!");}});}}
</script>
</html>

html" title=java>java">    @RequestMapping(value = "/list")public String list(Model model, Long roleId, String usrName, Long pageIndex) {List<Role> roles = roleService.list();pageIndex = pageIndex == null ? 1 : pageIndex;Page<User> userPager = new Page<>();userPager.setCurrent(pageIndex);userPager = userService.userPage(roleId, usrName, userPager);model.addAttribute("roleId", roleId);model.addAttribute("usrName", usrName);model.addAttribute("roles", roles);model.addAttribute("userPager", userPager);return "user/list";}

新增

html"><!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" layout:decorate="~{main}"xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head><title>用户添加</title><link th:href="@{/localcss/crmlist.css}" href="../static/localcss/crmadd.css" rel="stylesheet">
</head>
<body>
<div layout:fragment="content"><div class=""><div class="clearfix"></div><div class="row"><div class="col-md-12 col-sm-12 col-xs-12"><div class="x_panel"><div class="x_title"><h2>新增用户信息 <i class="fa fa-user"></i></h2><div class="clearfix"></div></div><div class="x_content"><div class="clearfix"></div><form class="form-horizontal form-label-left" th:action="@{/user/save}" action="/user/save" method="post"><div class="item form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12" for="usrName"> 用户名 <span class="required">*</span></label><div class="col-md-6 col-sm-6 col-xs-12"><input id="usrName" class="form-control col-md-7 col-xs-12"data-validate-length-range="10" data-validate-words="1" name="usrName" required="required"placeholder="请输入用户名" type="text"></div></div><div class="item form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12" for="usrPassword"> 密码 <span class="required">*</span></label><div class="col-md-6 col-sm-6 col-xs-12"><input id="usrPassword" class="form-control col-md-7 col-xs-12"data-validate-length-range="10" data-validate-words="1" name="usrPassword" required="required"placeholder="请输入密码" type="password"></div></div><div class="item form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12" for="roleId"> 用户角色 <span class="required">*</span></label><div class="col-md-6 col-sm-6 col-xs-12"><select name="usrRoleId" id="roleId" class="form-control" required="required"><option th:each="role:${roles}" th:value="${role.roleId}" th:text="${role.roleName}" value="">角色</option></select></div></div><div class="item form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12" for="usrFlag"> 角色状态</label><div class="col-md-6 col-sm-6 col-xs-12"><input id="usrFlag" name="usrFlag" type="checkbox" value="1">(是否启用)</div></div><div class="form-group"><div class="col-md-6 col-md-offset-3"><button id="send" type="submit" class="btn btn-success">保存</button><button type="button" class="btn btn-primary" id="back">返回</button><br /><br /></div></div></form></div></div></div></div>
</div>
</div>
</body>
<script layout:fragment="js" th:inline="html" title=java>javascript">// 获取项目路径/*<![CDATA[*/var ctxPath = /*[[@{/}]]*/ '';/*]]>*/$(document).ready(function () {$("#back").on("click", function () {window.history.back();});$("#usrName").on("blur", function () {$.ajax({type: "GET",url: ctxPath + "user/check",data: {"usrName": $("#usrName").val(),},dataType: "json",success: function (data) {// alert(JSON.stringify(data)); // {"result":"true"}if (data.result === "true") { // 检查有重复:返回"true"alert("用户名重复了!");// $("#usrName").focus();}},error: function (data) {alert("对不起,检查失败!");}});});});
</script>
</html>

html" title=java>java">    @RequestMapping("/add")public String add(Model model) {List<Role> roles = roleService.list();model.addAttribute("roles", roles);return "user/add";}@RequestMapping("/save")public String save(User user) {if (user.getUsrFlag()==null){user.setUsrFlag(0);}int add = userService.add(user);if (add>0){return "redirect:/user/list";}else{return "user/add";}}

删除

html" title=java>java">function doDel(obj, usrId) {if (confirm("你确定需要删除该用户信息吗?")) {$.ajax({type: "POST",url: ctxPath + "user/del/" + usrId,/*data: {"usrId": usrId},*/dataType: "json",success: function (data) {// alert(JSON.stringify(data)); // {"result":"true"}if (data.result === "true") { // 删除成功:移除删除行alert("删除成功!");$(obj).parents("tr").remove();// window.location.href = project_name() + "/user/list";}},error: function (data) {alert("对不起,删除失败!");}});}}

html" title=java>java">    @ResponseBody@RequestMapping("/del/{usrId}")public Map del(@PathVariable Long usrId) {Map map = new HashMap();int add = userService.del(usrId);if (add>0){map.put("result", "true");}else{map.put("result", "false");}return map;}


http://www.ppmy.cn/ops/117174.html

相关文章

快速排序(C语言实现)

目录 基本概念 Hoare版本 动图演示 思路 代码实现&#xff1a; 性能分析 取Key优化 三数取中法选择基准&#xff08;Median-of-Three Partitioning&#xff09; 实现步骤 代码实现 挖坑法 基本步骤 动图 示例说明 代码实现 前后指针法 动图示范 思路 代码实…

docker的核心概念整理:docker-compose

docker-compose 理解一个服务&#xff0c;我们尝试将自己代入&#xff0c;开发者的角色去思考 这个服务&#xff0c;为什么叫这个名字&#xff1f; docker是什么意思&#xff1f; 英文的意思是码头工人 码头工人的主要工作之一 是把货物搬至集装箱&#xff0c; 进而货轮…

【线程】POSIX信号量---基于环形队列的生产消费者模型

信号量概念 这篇文章是以前写的&#xff0c;里面讲了 System V的信号量的概念&#xff0c;POSIX信号量和SystemV信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步。 信号量的概念 POSIX信号量的接口 初始化…

用户反馈与商品改进:API返回值中的用户声音

在产品设计和迭代过程中&#xff0c;用户反馈是极其宝贵的信息来源。它可以帮助团队了解用户在使用产品时的真实体验、遇到的问题以及改进建议。当通过API&#xff08;应用程序编程接口&#xff09;收集和处理用户反馈时&#xff0c;确保API能够有效地返回“用户声音”&#xf…

Android APN type 配置和问题

问题/疑问 如果APN配置了非法类型(代码没有定义的),则APN匹配加载的时候最终结果会是空类型。 那么到底是xml解析到数据库就是空type呢?还是Java代码匹配的时候映射是空的呢? Debug Log 尝试将原本的APN type加入ota或者新建一条ota type APN,检查log情况。 //Type有…

Docker 安装 Apache(图文教程)

Apache HTTP服务器(简称Apache)是一个开源的、跨平台的Web服务器软件,由Apache软件基金会开发和维护。Apache HTTP服务器是世界上最流行的Web服务器软件之一,被广泛用于互联网上的网站和应用程序。 一、拉取镜像 docker pull httpd:latest二、运行容器 Apache的默认端口是…

VSCode#include头文件时找不到头文件:我的解决方法

0.前言 1.在学习了Linux之后&#xff0c;我平常大部分都使用本地的XShell或者VSCode连接远程云服务器写代码&#xff0c;CentOS的包管理器为我省去了不少繁琐的事情&#xff0c;今天使用vscode打开本地目录想写点代码发现#include头文件后&#xff0c;下方出现了波浪线&#…

Linux安装vim+jdk+tomcat

1、常用软件 1、vim vim是一款功能强大&#xff0c;好用的编辑器&#xff0c;尤其适合程序员。 1、安装 yum -y install vim* yum 安装命令 -y是不需要用户手动输入是否确认安装 install代表安装&#xff0c;vim是要安装的软件 安装完成后执行vim 2、vim三种模式 普通模式…