提示:此项目仅作为本博主的学习笔记记录,不作为商品售卖,文中某个方法或单词或许会因为马虎写错,但本文重点讲的是思路,资源可找博主私聊
文章目录
前言
CRUD是指在数据库中进行的基本操作,即创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete)。
在编程中,这些操作对应着对数据库中数据的增删改查。
提示:此项目我用的是idea工具,具体的一些配置可以看下面的链接
计算机专业、软件技术、工程等软件专业同学电脑必配环境
如果想从零开始写请看下面的SpringBoot项目构建方式链接
SpringBoot项目构建方式
开始会有个初始压缩包,在这个初始压缩包内写代码
进入初始项目后看到项目结构:
用户看的是View层视图层,数据从Controller/Action层过来
Controller控制器通过接收前端传过来的参数进行业务操作,在返回一个指定的路径或者数据表直接调用Service,Service调用Mapper
Service层, 存放业务逻辑处理,也是一些关于数据库处理的操作,但不是直接和数据库打交道,他有接口还有接口的实现方法,在接口的实现方法中需要导入mapper层,mapper层是直接跟数据库打交道的,他也是个接口,只有方法名字,具体实现在mapper.xml文件里,service是供我们使用的方法
Service的 impl 文件将Mapper和Service进行整合
Model层=entity层=pojo层,存放我们的实体类,与数据库中的属性值基本保持一致,与Mapper层连接
mapper层=dao层,对数据库进行数据持久化操作(把数据放到持久化的介质中,同时提供增删改查操作), 他的方法语句直接针对数据库操作 。
mapper的接口对应resources下的xml文件,它只有方法名,封装了对数据库进行的数据持久化操作。
其中还有个core文件夹,里面放的是工具类包括一些拦截器
提示:以下是本篇文章正文内容,下面案例可供参考
本文SpringBoot 框架代码编写流程(看个人习惯,无硬性标准)
1、画页面 HTML
2、编写控制层代码的方法:Action / Controller
3、编写数据持久层代码:Mapper + Mapper.xml(数据库)
4、编写业务层代码:Service + Impl
5、完善控制层代码的方法:Action / Controller
关于Thymeleaf 前端
目前Java比较流行的模板引擎有Thymeleaf和Freemarker,Thymeleaf的话更适合当前的人员分工问题,回忆一下以前的Jsp页面,必须要动态渲染才能看到真实的效果,写页面的和写后端的分工不太明确 。
Thymeleaf是动静分离的,页面中的动态标签是需要传递有数据的时候才会渲染,不然就是原本默认的静态的样子 。
Thymeleaf 快速入门
Thymeleaf 官网
后台做逻辑会有个绑定,传到前端设计的页面上,后台如果传过来数据就会用后台数据,如果后台没有数据,也能用静态的形式展示出来
common文件夹介绍
LoginInterceptor登录拦截器,用于阻止未登录用户访问系统
CrossOriginInterceptor拦截器
在MyInterceptorConfig配置,interceptor实际上也是一种filter的实现 ,这里注册CrossOriginInterceptor拦截器,注册LoginInterceptor拦截器。并且所有路径都被拦截,除了静态不拦截路径
//拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
WebMvcConfigurer.super.addInterceptors(registry);
// 注册CrossOriginInterceptor拦截器
registry.addInterceptor(new CrossOriginInterceptor());
// 注册LoginInterceptor拦截器
InterceptorRegistration registration = registry.addInterceptor(new LoginInterceptor());
registration.addPathPatterns("/**"); // 所有路径都被拦截
registration.excludePathPatterns( // 添加不拦截路径
"/", // 首页
"/user/login", // 登录
"/user/addUser", // 注册
"/user/checkUsername", // 检查用户名
"/**/*.html", // html静态资源
"/**/*.js", // js静态资源
"/**/*.css", // css静态资源
"/test/**" // css静态资源
);
}
关于首页静态资源
所有静态资源都需要thymeleaf接管
可以在resources下创建目录处理静态资源,目录优先级是:resources > static(默认)> public
测试:将静态资源文件放到resources/static/public或者**/****目录下资源都可以被访问, 比如在static下创建1.js文件,可以被访问localhost:8080/springbootdemo/1.js
模板引擎: 将 html 页面放在 resources/templates 包下 ,在templates目录下的所有页面,可以通过controller来跳转。
项目里使用了thymeleaf,所以得在pom.xml文件里加入thymeleaf 相关依赖
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
<!--------- 或者 --------->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
一、SpringBoot整合Mybatis
1、添加Mybatis的起步依赖
整合MyBatis
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
添加数据库驱动坐标
<!-- MySQL连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2、添加数据库连接信息
application-dev.yaml中添加数据量的连接信息,因为在application.yaml中配置了active: dev,所以生产环境application-pro.yaml不用管,只需要改application-dev.yaml
代码如下(示例):
# 开发环境
spring:
#数据源配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/staff?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
username: root
password: root
hikari:
maximum-pool-size: 2
minimum-idle: 2
#mybatis配置
mybatis:
#mapper配置文件
config-location: classpath:mybatis-config.xml
mapper-locations: classpath:mapper/*.xml
type-aliases-package: cn.springbootdemo.model
3、创建实体Bean
接下来创建model层的User实体类
第一种:创建User实体类
我用的是这种
把数据库表里的字段定义一下变量,鼠标右键生成 get、set方法,重写toString方法
package cn.springbootdemo.model;
public class User {
private int userid;
private String username;
private String password;
private String realname;
private String birthdate;
private String gender;
private String interest;
private String degree;
private String intro;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
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;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
public String getBirthdate() {
return birthdate;
}
public void setBirthdate(String birthdate) {
this.birthdate = birthdate;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getInterest() {
return interest;
}
public void setInterest(String interest) {
this.interest = interest;
}
public String getDegree() {
return degree;
}
public void setDegree(String degree) {
this.degree = degree;
}
public String getIntro() {
return intro;
}
public void setIntro(String intro) {
this.intro = intro;
}
@Override
public String toString() {
return "User [userid=" + userid + ", username=" + username + ", password=" + password + ", realname=" + realname
+ ", birthdate=" + birthdate + ", gender=" + gender + ", interest=" + interest + ", degree=" + degree
+ ", intro=" + intro + "]";
}
}
第二种:创建User实体类
另外(为了方便使用先把lombok导入,在pom.xml中文件中加)
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
User实体类
package cn.springbootdemo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data //加了这个注解get、set方法就不用写了
@NoArgsConstructor
@AllArgsConstructor //无参构造和全参构造可以不加
public class User {
private int userid;
private String username;
private String password;
private String realname;
private String birthdate;
private String gender;
private String interest;
private String degree;
private String intro;
@Override //重写toString
public String toString() {
return "User [userid=" + userid + ", username=" + username + ", password=" + password + ", realname=" + realname
+ ", birthdate=" + birthdate + ", gender=" + gender + ", interest=" + interest + ", degree=" + degree
+ ", intro=" + intro + "]";
}
}
4、编写Mapper
注意:@Mapper标记该类是一个mybatis的mapper接口,可以被spring boot自动扫描到spring上下文中
与启动类同一级别创建mapper文件夹并创建UserMapper接口
package cn.springbootdemo.mapper;
import cn.springbootdemo.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper//使用@Mapper注解,表示这是操作数据库的mapper,SpringBoot自动扫描
//也可以在启动类里使用MapperScan("cn.springbootdemo.mapper")注解,参数是包名,一个效果
// Dao层,所以可以使用@Repository,当然也可以使用Component注解,不写也OK
@Repository
public interface UserMapper {
void addUser(User user);//注册
}
5、配置Mapper映射文件
在resources文件夹下创建mapper文件夹,并创建UserMapper.xml文件
Mybatis中文文档官网:https://mybatis.net.cn/getting-started.html
其中:
1、namespace命名空间必须与@Mapper注解的Mapper接口的全类名一致
这里的全类名要去UserMapper.java里面去找://全类名: cn.springbootdemo.mapper.UserMapper
其中cn.springbootdemo.mapper
就是第一行package后面的包
然后UserMapper
是这个.java的接口名
2、xml文件名必须与@Mapper注解的接口名一致
3、标签中的 id必须与@Mapper注解的的接口中的方法名一致,且参数一致
这里需要确认:整合对应application-dev.yaml里type-aliases-package别名扫描包、mapper-locations 定义mapper位置 ,即加载Mybatis映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.springbootdemo.mapper.UserMapper">
<insert id="addUser" parameterType="User">
insert into demo_users
values(null,#{username},#{password},#{realname},#{birthdate},#{gender},#{interest},#{degree},#{intro})
</insert>
</mapper>
接下来写service,定义一个UserService接口
@Service
public interface UserService {
int addUser(User user);
List<User> getUserList(User user);
}
然后对应着写接口的实现类UserServiceImpl
但是service.impl下的两个文件是有层级关系的,我们把UserService放在上一层
最后:
6、定义controller
定义service(以addUser为例) service.impl.UserServiceImpl
刚才在UserMapper.java中有个addUser注册方法,然后这个注册方法映射到UserMapper.xml里面执行了SQL语句
@Service //使用@Service注解,SpringBoot自动扫描
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper mapper;
@Override
public int addUser(User user) {
//默认执行成功
mapper.addUser(user);
return 0;
}
}
7、创建UserAction类
@Controller
@RequestMapping("/user")
public class UserAction {
@Autowired
private UserService userService;
@RequestMapping("/addUser")
public String addUser(User user, Map<String,String> m) {
int f = userService.addUser(user);
if (f == 0) {
m.put("msg","注册成功");
}
return "login";
}
}
现在我们运行一下看看结果
其中出生日期这里是可以选时间的,这里用了一个日期的校验,在home.html里
点击确定后显示的页面:
点击登录显示页面:
回到数据库可视化页面可以看到我刚刚加的这条数据:
如果数据库里没有更新数据,那就去数据库配置里面看:
数据库名字或密码改没改
二、做首页
①、新建HomeAction类
首先在action文件夹内新建HomeAction类
SpringBoot中Controller控制层重要注解
@Controller
@RequestMapping("/") //URL
public class HomeAction {
@RequestMapping("/")// 直接访问http://localhost:8080/
public String home(){
return "home";
}
@RequestMapping("/login")// 访问http://localhost:8080/login
public String login(){
return "login";
}
}
现在应该能显示首页了
②、将页面转化为Thymeleaf形式
现在是单纯的HTML页面,接下来把他转化为Thymeleaf形式,首先加入thymeleaf模板
<!doctype html>
<html lang="ch" xmlns:th="http://www.thymeleaf.org">
</html>
我们回到首页home.html
把第2行的<html>
改成<html lang="ch" xmlns:th="http://www.thymeleaf.org">
把第18行的本地文件
<link rel="stylesheet" type="text/css" media="all" href="../static/daterangepicker/daterangepicker.css" />
改成Thymeleaf形式的:
<link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}" />
同样在22行把script src
里面的内容也改成Thymeleaf形式的:<script th:src="@{/js/functions.js}"></script>
接下来把我们把from表单中的确定按钮的onclick事件去掉(大约在172行),然后把类型button
改成submit
,当点击确定的时候就相当于把后台服务器 type类型进行提交
//原来代码:
<button class="btn btn-primary" type="button" onclick="addUser()">确定</button>
//更改代码:
<button class="btn btn-primary" type="submit">确定</button>
当我们点击确定的时候,我们得把表单目的地址写上,回到 from表单起点位置(大约在41行),当点确定的时候需要对表单进行一个提交
//原来代码:
<form class="form" id="regForm"
//更改代码:
<form class="form" id="regForm" th:method="post" th:action="@{/user/addUser}">
现在就把home页面改造成了Thymeleaf形式了
home.html文件中用到了cdn加速(内容分发网络) 知识
就是一个文件在全国各地都有服务器,可以用cdn的技术进行就近分配,以速度最优为原则;也有图片优化等等。需要的话可以进下面网址找相应版本
cdn加速
③、javascript的编写
这里说的是验证的功能,做表单的时候一定要进行校验,小心被攻击,尤其是SQL注入的时候
<script type="text/javascript">
$(function () {
$("#regForm").bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
username: {
message: '用户名验证失败',
validators: {
notEmpty: {
message: '用户名不能为空'
}
}
},
password: {
message: '密码验证失败',
validators: {
notEmpty: {
message: '密码不能为空'
}
}
},
password1: {
message: '密码确认验证失败',
validators: {
notEmpty: {
message: '密码确认不能为空'
}
}
},
realname: {
message: '姓名验证失败',
validators: {
notEmpty: {
message: '姓名不能为空'
}
}
}
}
});
});
$(document).ready(function () {
$("#regForm #username").blur(checkName);
});
function checkName() {
var username = $("#regForm #username").val();
if (username) {
$.post("./user/checkUsername",
{username: username},
function (data) {
if (data.result == "yes") {
$("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
} else {
$("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
}
});
/* $.ajax({
url : "${pageContext.request.contextPath}/user/checkName",
type : "post",
// data表示发送的数据
data :JSON.stringify({username:username}),
// 定义发送请求的数据格式为JSON字符串
contentType : "application/json;charset=UTF-8",
//定义回调响应的数据格式为JSON字符串,该属性可以省略
dataType : "json",
//成功响应的结果
success : function(data){
if(data.result){
$("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
}else{
$("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
}
}
}); */
}
}
</script>
完整的home.html代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Insert title here</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello, Bootstrap Table!</title>
<!-- 最新 Bootstrap4 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
<!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
<script src="https://cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<!-- DaterangePicker -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}"/>
<!-- BootStrapValidator -->
<link rel="stylesheet"
href="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/css/bootstrapValidator.min.css">
<script type="text/javascript"
src="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
<script th:src="@{/js/functions.js}"></script>
<script type="text/javascript">
$(function () {
$("#regForm").bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
username: {
message: '用户名验证失败',
validators: {
notEmpty: {
message: '用户名不能为空'
}
}
},
password: {
message: '密码验证失败',
validators: {
notEmpty: {
message: '密码不能为空'
}
}
},
password1: {
message: '密码确认验证失败',
validators: {
notEmpty: {
message: '密码确认不能为空'
}
}
},
realname: {
message: '姓名验证失败',
validators: {
notEmpty: {
message: '姓名不能为空'
}
}
}
}
});
});
$(document).ready(function () {
$("#regForm #username").blur(checkName);
});
function checkName() {
var username = $("#regForm #username").val();
if (username) {
$.post("./user/checkUsername",
{username: username},
function (data) {
if (data.result == "yes") {
$("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
} else {
$("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
}
});
/* $.ajax({
url : "${pageContext.request.contextPath}/user/checkName",
type : "post",
// data表示发送的数据
data :JSON.stringify({username:username}),
// 定义发送请求的数据格式为JSON字符串
contentType : "application/json;charset=UTF-8",
//定义回调响应的数据格式为JSON字符串,该属性可以省略
dataType : "json",
//成功响应的结果
success : function(data){
if(data.result){
$("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
}else{
$("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
}
}
}); */
}
}
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="text-center">
<a type="button" class="btn btn-outline-info" th:href="@{/user/getUserListWithPage}">查看所有用户信息</a>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-md-10 offset-md-1">
<form class="form" id="regForm" th:method="post" th:action="@{/user/addUser}">
<div class="modal-header">
<h4 class="modal-title">请填写注册信息</h4>
</div>
<div class="modal-body">
<div class="form-group row">
<div class="col-md-2">
<label for="username">用户名</label>
</div>
<div class="col-md-6">
<input type="text" id="username" name="username"
class="form-control input-sm" placeholder="用户名" required/> <span
id="result"></span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="password">密码</label>
</div>
<div class="col-md-6">
<input type="password" id="password" name="password"
class="form-control input-sm" placeholder="密码" required/>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="password1">密码确认</label>
</div>
<div class="col-md-6">
<input type="password" id="password1" name="password1"
class="form-control input-sm" placeholder="密码确认" required/>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="realname">姓名</label>
</div>
<div class="col-md-6">
<input type="text" id="realname" name="realname"
class="form-control input-sm" placeholder="姓名"/>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="birthdate">出生日期</label>
</div>
<div class="col-md-6">
<input type="text" id="birthdate" name="birthdate"
class="form-control input-sm">
<script type="text/javascript"
src="./daterangepicker/require.js"
data-main="./daterangepicker/main.js"></script>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="gender">性别</label>
</div>
<div class="col-md-6">
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" name="gender"
value="1" checked> <label class="form-check-label"
for="gender">男</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" name="gender"
value="0"> <label class="form-check-label"
for="gender">女</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="interest">爱好</label>
</div>
<div class="col-md-6">
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="旅游">
<label class="form-check-label" for="interest">旅游</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="登山">
<label class="form-check-label" for="interest">登山</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="健身">
<label class="form-check-label" for="interest">健身</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="上网">
<label class="form-check-label" for="interest">上网</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="游泳">
<label class="form-check-label" for="interest">游泳</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="degree">学历</label>
</div>
<div class="col-md-6">
<select id="degree" name="degree" class="form-control">
<option value="0" selected>--请选择--</option>
<option value="1">高中</option>
<option value="2">专科</option>
<option value="3">本科</option>
<option value="4">研究生</option>
</select>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="intro">自我介绍</label>
</div>
<div class="col-md-6">
<textarea name="intro" rows="5" cols="20" class="form-control"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="text-center">
<button class="btn btn-primary" type="submit">确定</button>
<button class="btn btn-secondary" type="reset">重置</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
1、注册页面的完善(增)
接下来我们把注册功能完善下,因为用户注册后不可能去看数据库,我们要有个显示页面,显示注册成功还是失败,而且在注册时我们是默认他是注册成功的,实际情况下注册的用户名是一不一样? 注册完后还有个返回首页,注册成功后要有个登录功能
1、我们先写注册失败的代码,在UserAction里面:
public String addUser(User user, Map<String,String> m) {
int f = userService.addUser(user);
if (f == 0) {
m.put("result","yes");
m.put("msg","注册成功");
}else if(f==1){
m.put("result","no");
m.put("msg","注册失败,用户名重复");
}else {
m.put("result","no");
m.put("msg", "注册失败,数据库错误");
}
return "login";
}
我们之前写得 f==0,f在userService里来的,userService这有个addUser方法
之前addUser只是返回0,现在我们让他返回1或2
2、我们回到UserService:
UserService已经有一个addUser接口了,他具体的实现在UserServiceImpl内
我们就去看UserServiceImpl,在这里面我们要加一些其他的方法
比如先看注册失败,用户名重复,这个错误
在里面加个try catch语句,如果有错误就用catch语句捕获这个Exception异常并打印
3、我们先判断这个数据库有没有这个用户,对数据库进行一个查询操作
在mapper包下的UserMapper接口中加入下面代码
//查询有没有这个用户:0011
int existUser(User user);///1、使用count查以0011为名字的用户
User existsUser(User user);//2、查以0011为名字的用户
接下来去UserMapper.xml里面写数据库查询操作语句
先写第一个:使用count查以0011为名字的用户
<select id="existUser" parameterType="User" resultType="int">
select count(*) from demo_users where username = #{username}
</select>
<!--第一个:使用count查以0011为名字的用户,上面的username是变量-->
但是查询语句对不对呢?这时候可以打开idea内显示图形化页面,然后把查询语句复制进去验证
值得注意的是:select count(*) from demo_users where username = #{username}
中的 #{username}
是个变量
比如说我们查询以0011为名字的:select count(*) from demo_users where username = '0011'
count这里返回1,说明有一个用户的名字是0011
当然count也可以不做统计,把以0011做名字的用户返回回来:select * from demo_users where username = '0011'
下面接着写第二个:查以0011为名字的用户
<select id="existsUser" parameterType="User" resultType="User">
select userid,username from demo_users where username=#{username} and password=#{password}
</select>
<!--第二个:查以0011为名字的用户,username和password是变量,
在图形化页面中的查询语句是:select userid,username from demo_users where username='0011' and password='0011'
-->
4、现在我们就可以在UserServiceImpl 里面写 try catch语句了,当然前面写得默认注册成功就要删掉了
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper mapper;
@Override
public int addUser(User user) {
// 默认执行成功
// mapper.addUser(user);
// return 0;
try{
//如果你的数据库没有这个用户返回0,否则返回1
if(mapper.existUser(user)==0){
return 0; //用户不存在,可以注册
}else{
return 1; //用户存在,不可注册
}
}catch (Exception e){
e.printStackTrace();
return 2; //如果报错返回2
}
}
@Override
public List<User> getUserList(User user) {
return null;
}
}
5、现在注册功能就写得差不多了,但是在UserAction中我们写的是返回login页面,我们应该让他返回到 result结果页面
我是复制的home.html,再粘贴到user文件夹下,重命名为:result.html
所以在UserAction最后一行返回login改成:return "user/result";
把 result.html里面的代码改成:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Insert title here</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello, Bootstrap Table!</title>
<!-- 最新 Bootstrap4 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
<!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
<script src="https://cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<!-- DaterangePicker -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}"/>
<!-- BootStrapValidator -->
<link rel="stylesheet"
href="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/css/bootstrapValidator.min.css">
<script type="text/javascript"
src="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
<script th:src="@{/js/functions.js}"></script>
</head>
<body style="margin: 200px">
<div class="container-fluid">
<div class="row">
<div class="m-auto">
<p class = "text-success" th:if="${result=='yes'}"><span th:text="${msg}"></span></p>
<p class = "text-danger" th:if="${result=='no'}"><span th:text="${msg}"></span></p>
</div>
</div>
</div>
</body>
</html>
这时候我们再重新运行下,再注册一个数据库里有的名字
点击确定后:
6、现在注册不成功的结果出来了,但是页面太简单了,起码有个跳转加个超链接,不可能让用户按左上角返回箭头返回,无论注册成功与否都要有个超链接,让他跳转一下
所以接着写result.html页面:
<div class = "row">
<div class="m-auto">
<a th:href="@{/}">返回首页</a>
<a th:href="@{/user/getUserList}">查看所有用户</a>
</div>
</div>
然后就多了这两个超链接,点进去后他们显示的页面也分别放在了下面
在点查看用户的时候显示的是:
{“login”:“请先登录”,“redirUrl”:“/user/getUserList”}
要求先登录,跳转的路径是/user/getUserList,假如要在做其他的东西,必须要把login这个功能做了,否则他都会拦截
在common文件夹里有个LoginInterceptor.java(拦截器功能)
在新的页面中可以看到:他的要求就是请先登录
2、登录功能(查)
我们先把LoginInterceptor.java(拦截器功能)里面最后几行注释掉,这几行是输出流的功能
需要注释的代码:
我们在这注释代码下面做一个跳转到登录页面的功能:
arg0.getRequestDispatcher("login").forward(arg0,arg1);
再运行下:
还是先显示注册页面,添加信息
然后这次点击查看所有用户
然后就跳转到 login页面了
注册前的检测
这个功能就是在你注册这个用户前检测数据库有没有这个用户名
这个功能的实现的逻辑在home.html页面内
1、我们回到UserAction里写checkUsername这个函数
@ResponseBody
@RequestMapping("/checkUsername")
public Map<String, String> checkUsername(User user) {
System.out.println("checkUsername=================" + user);
boolean f = userService.checkUsername(user); //可以注册
Map<String, String> m = new HashMap<String,String>();
if (f) {
m.put("result", "yes");
m.put("msg", "");
} else {
m.put("result", "no");
m.put("msg", "对不起,该用户名已存在,请更换");
}
System.out.println("checkUsername : " + m);
return m;
}
2、这时候我们可以看到checkUsername
这里有个报错,我们把鼠标放上去后点击红色的提示,在UserService里面创建这个checkUsername方法
,它会自动生成
自动生成的那行代码的意思是:根据用户名判断是否有该用户,如果没有则可以注册
3、这时候UserServiceImpl
类中有个报错,我们【Alt+回车】导入这个方法即可
然后在这里面写个简单的逻辑:
如果existUser(user)==0
就是没有注册,如果 !=0 就是已经注册了
@Override
public boolean checkUsername(User user) {
if(mapper.existUser(user)==0){
return true;
}else{
return false;
}
}
运行截图:
登录功能的编写
1、我们现在统一一下 login.html页面
完整的 login.html代码
里面就是一个表单和俩按钮
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Insert title here</title>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title></title>
<!-- 最新 Bootstrap4 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
<!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
<script src="https://cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<script th:src="@{/js/functions.js}"></script>
<script type="text/javascript" th:inline="javascript">
$(document).ready(
function () {
$('#loginFormModal').modal();
}
);
</script>
</head>
<body>
<div class="modal fade" id="loginFormModal" role="dialog" aria-hidden="true" aria-labelledby="myModalLabel">
<div class="modal-dialog">
<div class="modal-content"> <!-- 对loginForm这个表单进行提交,提交方式是post,提交路径是/user/login -->
<form class="form-signin" id="loginForm" th:method="post" th:action="@{/user/login}">
<div class="modal-header">
<h5 class="modal-title" id="myModalLabel">用户登录</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<label for="username" class="sr-only">用户名</label>
<input type="text" id="username" name="username" class="form-control"
placeholder="用户名" required autofocus>
<label for="password" class="sr-only">密码</label>
<input type="password" id="password" name="password" class="form-control"
placeholder="密码" required>
<div class="text-danger" th:text="${login!='yes'?login:''}"></div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="submit" id="loginBtn">登录</button>
<button class="btn btn-secondary" type="button" data-dismiss="modal">关闭窗口</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
我们现在需要写一个http://localhost:8080/springbootdemo/user/login
这样的URL,到这个里面写逻辑
2、我们直接进到action这个页面,写user/login这个逻辑:
- 查数据库有没有这个人
- 如果有就登入,登录信息存起来,跳转到目标页
- 没有还得回到登录页
因为我们在UserMapper接口里面已经定义完了,所以我们先进到UserService接口里面查有没有这个人
3、UserService接口内新增代码:User existsUser(User user);
然后到UserServiceImpl实现类里面【Alt+回车】把这个方法加进来
其实就是向数据库查,查有没有这个人,查询的语句写过了,我们调用一下就行:return mapper.existsUser(user);
4、现在就可以到 action里面写逻辑了
//登录功能
@RequestMapping("/login") //目标地址
public String login(User user, HttpSession session, Map<String, String> m) {
//1、查数据库有没有这个人
User dbUser=userService.existsUser(user);
//2、如果有就登入,登录信息存起来,跳转到目标页
if(dbUser !=null){
session.setAttribute(Constants.LOGIN_USER,dbUser); //存起来
m.put("login","yes");
String redirUrl = (String) session.getAttribute(Constants.ORIGINAL_URL);
return "/redirect"+redirUrl;
}else{
//3、没有还得回到登录页
m.put("login",Constants.LOGIN_ERR);
return "/login";
}
}
其中Constants. 后面的名字在core文件夹下的Constants类里面找,或者在这里面改
运行后查看所有用户后登录:
3、显示用户表格页面(查)
紧接上图,因为user/getUserList还没写,他就是向后台拿所有的用户信息,把所有的用户拿到后存到一个list里面,然后通过前端Thymeleaf把他渲染出来
1、我们接着去UserAction里面去写getUserList
@RequestMapping("/getUserList")
public String getUserList(User user, Map<String, List<User>> m) {
//向数据库查询user信息,存储到list里,再把list放到map里
return "user/userList";
}
2、我们现在还没有 userList页面,需要创建一个
我直接就把 user文件夹下的 result.html复制了一下,重新粘回 user文件夹下,重命名为:userList.html
在这里面随便写点东西,看看能不能返回
在运行程序后,填写注册信息后点击确定,选择查看所有用户
可以看到里面已近有返回了
3、我们接着写UserAction里的逻辑,我们向数据库查,是操作xml文件,在这里面进行数据库的增删改查,对应的Mapper接口文件里定义查询规则
首先在mapper文件夹下的UserMapper里面定义规则 List
List<User> getUserList(User user); //查询数据库里面所有用户信息
4、然后到UserMapper.xml 里面写查询语句:
我们不仅要查全部的,还要有模糊查询(用户名、性别)
<select id="getUserList" parameterType="User" resultType="User">
select * from demo_users
<where>
<if test = "username != null and username != ''">
and username like concat('%',#{username},'%')
<!-- SELECT * FROM demo_users WHERE username LIKE CONCAT('%','a','%')
这条语句是在图形可视化页面查找用户名带a的 -->
</if>
<if test = "gender != null and gender != ''">
and gender = #{gender}
</if>
</where>
</select>
5、接着就在service定义接口,然后在接口实现类把他的逻辑写出来
首先在service文件夹下的UserService接口里面写接口:
List<User> getUserList(User user);//查询用户信息,存到list里
然后在实现类impl文件夹下的UserServiceImpl里面(导包),把返回值改一下:
return mapper.getUserList(user);
6、接着回到controller里面写逻辑
@RequestMapping("/getUserList")
public String getUserList(User user, Map<String, List<User>> m) {
//向数据库查询user信息,存储到list里,再把list放到map里
//Mapper定义规则List<User>,在xml里查询
List<User> userList = userService.getUserList(user);
System.out.println("userList----:"+userList);//sout快捷键
return "user/userList";
}
随后我们运行程序,输入注册信息后点击查看所有用户,再点击登录:
能显示页面
并且回到控制台看到有输出,证明已经从后台已经读到user了,并且存到list了
现在已经拿到userList了,接着存到map里面
在 return “user/userList”; 上面写:
m.put("userList",userList);
System.out.println("m----:"+m);//sout快捷键
随后我们运行程序,输入注册信息后点击查看所有用户,再点击登录:
能显示页面
并且回到控制台看到m也有输出
7、下面就到前端去做userList页面渲染
这里用到了bootstrap表格
<body style="margin: 200px">
<div class="container-fluid" >
<div class="row">
<div class="col-md-12" >
<table class="table table-bordered">
<caption>边框表格布局</caption>
<thead>
<tr>
<th>用户名</th>
<th>真名</th>
<th>生日</th>
<th>性别</th>
<th>兴趣爱好</th>
<th>学历</th>
<th>自我介绍</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tanmay</td>
<td>Bangalore</td>
<td>560001</td>
<td>Tanmay</td>
<td>Bangalore</td>
<td>560001</td>
<td>Tanmay</td>
<td>Bangalore</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
刚才在controller里面已经能从数据库查的数据,这个userList,这个数据拿到后已经能存到map里面了,而且map在做页面跳转的时候通过键值对的形式已经把userList传递给user/userList页面了
我们拿到数据后对userList做循环(对数据做循环):th:each="tag:${user.getTags()}"
所以userList页面里面的body代码改成:
<body style="margin: 200px">
<div class="container-fluid" >
<div class="row">
<div class="col-md-12" >
<table class="table table-bordered">
<caption>边框表格布局</caption>
<thead>
<tr>
<th>序号</th>
<th>用户名</th>
<th>真名</th>
<th>生日</th>
<th>性别</th>
<th>兴趣爱好</th>
<th>学历</th>
<th>自我介绍</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="user,stat:${userList}">
<td th:text="${stat.count}">1</td>
<td th:text="${user.username}">Tanmay</td>
<td th:text="${user.realname}">二哈喇子</td>
<td th:text="${user.birthdate}">2022-09-08</td>
<td th:text="${user.gender == '1'?'男':'女'}">1</td>
<td th:switch="${user.degree}">
<span th:case="'0'">高中</span>
<span th:case="'1'">专科</span>
<span th:case="'2'">本科</span>
<span th:case="'3'">研究生</span>
</td>
<td th:text="${user.intro}">本人积极向上</td>
<td>
<a href="#">修改</a>
<a href="#">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
随后我们运行程序,输入注册信息后点击查看所有用户,看到的显示用户表格页面
模糊查询和返回首页按钮功能
我们继续完善该页面,加入模糊查询和返回首页按钮
模糊查询代码:
放在<div class="row">
之上
<hr>
<div class="row">
<div class="col-md-12">
<form class="form-inline" role="form" id="searchForm" th:method="post" th:action="@{/user/getUserList}">
<div class="form-group col-md-2 offset-1">
<input class="form-control input-sm" type="text" id="username" name="username" placeholder="用户名"
th:value="${param.username}"/>
</div>
<div class="form-group col-md-2">
<select class="form-control input-sm" id="gender" name="gender" >
<option value="">---不限制性别---</option>
<option value="1" th:selected="${#strings.trim(param.gender)=='1'}">男</option>
<option value="0" th:selected="${#strings.trim(param.gender)=='0'}">女</option>
</select>
</div>
<div class="form-group col-md-1">
<button class="btn btn-primary btn-sm" type="submit" >搜索</button>
</div>
</form>
</div>
</div>
<hr>
返回首页按钮代码
放在表格之下
<hr>
<div class="row">
<div class="col-md-12">
<div class="text-center">
<a type="button" class="btn btn-outline-info" th:href="@{/}">返回首页</a>
</div>
</div>
</div>
页面显示:
模糊查询功能实现页面
返回首页功能页面
三、修改用户
在点击修改按钮后(userList页面)→在action里写逻辑:弹出新页面 edit.html →新页面里显示已经有的用户信息→使用表单元素展示(输入框)展示已有信息→修改信息→点击表单的提交→@{/user/updateUser}(方法)→数据库进行更新(service→mapper→xml)→在页面返回结果 result
1、入口地址:userList.html中:
代码如下(示例):
<a th:href="@{/user/getUser(userid=${user.userid})}">修改</a>
2、写修改功能的第一步的Controller层代码:
UserAction.java的getUser()方法:
代码如下(示例):
//查询用户信息,弹出新页面edit.html
@RequestMapping( "/getUser")
public String getUser(String userid,Map<String,String> m) {
//返回跳转地址
return "/user/edit";
}
3、写修改功能的第一步的View层代码:
edit.html: 我是随便写了点,看能不能显示
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Insert title here</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello, Bootstrap Table!</title>
<!-- 最新 Bootstrap4 核心 CSS 文件 -->
<link rel="stylesheet" th:href="@{//cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css}">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script th:src="@{//cdn.staticfile.org/jquery/3.4.1/jquery.min.js}"></script>
<!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
<script th:src="@{//cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js}"></script>
<!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
<script th:src="@{//cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js}"></script>
<!-- DaterangePicker -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}" />
<!-- BootStrapValidator -->
<link rel="stylesheet" th:href="@{/css/bootstrapValidator.css}">
<script type="text/javascript" th:src="@{/js/bootstrapValidator.js}"></script>
<script th:src="@{/js/functions.js}"></script>
<script type="text/javascript" th:src="@{/js/validate.js}"></script>
<script type="text/javascript">
$(document).ready(function() {
validateForm("editForm");
});
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="text-center">
<a type="button" class="btn btn-outline-info" th:href="@{/user/getUserList}">查看所有用户信息</a>
</div>
</div>
</div>
<hr>
</div>
<div class="row">
<div class="col-md-10 offset-md-1">
<form class="form" id="editForm" th:method="post" th:action="@{/user/updateUser}">
<input type="hidden" name="userid" th:value="${user.userid}">
<div class="modal-header">
<h4 class="modal-title">请填写修改信息</h4>
</div>
<div class="modal-body">
<div class="form-group row">
<div class="col-md-2">
<label for="username">用户名</label>
</div>
<div class="col-md-6">
<input type="text" id="username" name="username" th:value="${user.username}"
class="form-control input-sm" placeholder="用户名" required readonly/> <span
id="result"></span>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="password">密码</label>
</div>
<div class="col-md-6">
<input type="password" id="password" name="password" th:value="${user.password}"
class="form-control input-sm" placeholder="密码" required />
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="password1">密码确认</label>
</div>
<div class="col-md-6">
<input type="password" id="password1" name="password1" th:value="${user.password}"
class="form-control input-sm" placeholder="密码确认" required />
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="realname">姓名</label>
</div>
<div class="col-md-6">
<input type="text" id="realname" name="realname"
th:value="${user.realname}" class="form-control input-sm" placeholder="姓名" />
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="birthdate">出生日期</label>
</div>
<div class="col-md-6">
<input type="text" id="birthdate" name="birthdate" th:value="${user.birthdate}"
class="form-control input-sm">
<script type="text/javascript"
src="./daterangepicker/require.js"
data-main="./daterangepicker/main.js"></script>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="gender">性别</label>
</div>
<div class="col-md-6">
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" name="gender"
value="1" th:checked="${user.gender}==1"> <label class="form-check-label"
for="gender">男</label>
</div>
<div class="form-check form-check-inline">
<input type="radio" class="form-check-input" name="gender"
value="0" th:checked="${user.gender}==0"> <label class="form-check-label"
for="gender">女</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="interest">爱好</label>
</div>
<div class="col-md-6">
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="旅游" th:checked="${#strings.contains(user.interest,'旅游')}" >
<label class="form-check-label" for="interest">旅游</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="登山" th:checked="${#strings.contains(user.interest,'登山')}">
<label class="form-check-label" for="interest">登山</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="健身" th:checked="${#strings.contains(user.interest,'健身')}">
<label class="form-check-label" for="interest">健身</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="上网" th:checked="${#strings.contains(user.interest,'上网')}">
<label class="form-check-label" for="interest">上网</label>
</div>
<div class="form-check form-check-inline">
<input type="checkbox" class="form-check-input" name="interest" value="游泳" th:checked="${#strings.contains(user.interest,'游泳')}">
<label class="form-check-label" for="interest">游泳</label>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="degree">学历</label>
</div>
<div class="col-md-6">
<select id="degree" name="degree" class="form-control">
<option value="0" selected>--请选择--</option>
<option value="1" th:selected="${user.degree}==1">高中</option>
<option value="2" th:selected="${user.degree}==2">专科</option>
<option value="3" th:selected="${user.degree}==3">本科</option>
<option value="4" th:selected="${user.degree}==4">研究生</option>
</select>
</div>
</div>
<div class="form-group row">
<div class="col-md-2">
<label for="intro">自我介绍</label>
</div>
<div class="col-md-6">
<textarea name="intro" rows="5" cols="20" class="form-control">[[${user.intro}]]</textarea>
</div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div class="text-center">
<button class="btn btn-primary" type="submit">确定</button>
<button class="btn btn-secondary" type="reset">重置</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
4、写修改功能的第一步的Mapper层代码:
UserMapper.java(接口)的getUser()方法(抽象方法):
User getUser(String userid);
写修改功能的第一步的Mapper层xml代码:
UserMapper.xml(实现文件):
<select id="getUser" resultType="User">
select * from demo_users where userid=#{userid}
</select>
5、写修改功能的第一步的Service层代码:
UserService.java(接口)的 getUser()方法(抽象方法):
User getUser(String userid);
写修改功能的第二步的Service层实现类代码:
UserServiceImpl.java(实现类)的getUser()方法(具体方法):
@Override
public User getUser(String userid) {
return mapper.getUser(userid);
}
6、最后写修改功能的控制层代码:
UserAction.java的getUser()方法:
//查询用户信息,弹出新页面edit.html
@RequestMapping( "/getUser")
public String getUser(String userid,Map<String,User> m) {
System.out.println("getUser-----------------------:");
//调用业务层方法(根据userid查找用户信息)
User user= userService.getUser(userid);
m.put("user",user);
//返回跳转地址
return "/user/edit";
}
7、写修改功能的第二步的Mapper层方法:
UserMapper.java(接口)的updateUser方法(抽象方法):
void updateUser(User user);
UserMapper.xml(实现文件):
<update id="updateUser">
update demo_users set username=#{username},password=#{password},realname=#{realname},
birthdate=#{birthdate},gender=#{gender},interest=#{interest},
degree=#{degree} ,intro=#{intro} where userid=#{userid}
</update>
8、写修改功能的第二步的业务层代码:
UserService的 updateUser方法(抽象方法):
boolean updateUser(User user);
UserServiceImpl的updateUser方法(具体方法):
@Override
public boolean updateUser(User user) {
try{
mapper.updateUser(user);
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
9、最后在action里继续写updateUser方法
@RequestMapping( "/updateUser")
public String updateUser(User user, Map<String, String> m) {
boolean f=userService.updateUser(user);
if(f) {
m.put("result", "yes" ) ;
m.put("msg","恭喜您,修改成功");
}else {
m.put("result","no");
m.put("msg","对不起,修改失败");
}
return "/user/result";
}
页面显示:
我们运行程序,输入注册信息后点击查看所有用户后,看到的显示用户表格页面
显示:修改成功,再点击查看所有用户
四、删除用户
1、首先在UserList.html中加入删除按钮
<a th:href="@{/user/deleteUser(userid=${user.userid}) }" onclick="return confirm('确认删除吗?')">删除</a>
2、写删除功能的Controller层代码:
UserAction.java的deleteUser()方法:
//删除用户信息
@RequestMapping( "/deleteUser")
public String deleteUser(String userid, Map<String,User> m) {
return "/user/result";
}
3、写删除功能的Mapper层代码:
UserMapper.java(接口)的deleteUser()方法(抽象方法):
void deleteUser(User user);
UserMapper.xml(实现文件):
<delete id="deleteUser">
delete from demo_users where userid=#{userid}
</delete>
4、写删除功能的Service层代码:
UserService.java(接口)的deleteUser()方法(抽象方法):
boolean deleteUser(User user);
UserServiceImpl.java(实现类)的deleteUser()方法(具体方法):
@Override
public boolean deleteUser(User user) {
try{
mapper.deleteUser(user);
return true;
}catch (Exception e) {
e.printStackTrace();
return false;
}
}
5、回到action里面继续写删除逻辑
//删除用户信息
@RequestMapping( "/deleteUser")
public String deleteUser(User user, Map<String,String> m) {
boolean f=userService.deleteUser(user);
if(f) {
m.put("result", "yes" ) ;
m.put("msg","恭喜您,用户删除成功");
}else {
m.put("result","no");
m.put("msg","对不起,用户删除失败");
}
return "/user/result";
}
然后会提示数据删除成功
数据没有了
源码获取:
提示:此项目仅作为本博主的学习笔记记录,不作为商品售卖,文中某个方法或单词或许会因为马虎写错,但本文重点讲的是思路
点击此处转到源码地址:
基于Spring Boot框架的员工管理系统的设计与实现
- Gitee提取地址: