参考这个环境配置:ssm框架的简单整合!!!(配置环境)-CSDN博客
思路:建立好环境后,我们要根据Spring MVC三层架构的思想建立项目结构。
AccountController:
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.controller;
import com.by.pojo.Account;
import com.by.service.AccountService;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* <p>Project: SpringMVC - AccountController</p>
* <p>Powered by scl On 2024-01-10 16:28:10</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@RequestMapping("/loginAccount")
public String login(HttpServletRequest request) {
Integer id = (Integer) request.getAttribute("id");
String userName = request.getAttribute("userName").toString();
String password= request.getAttribute("password").toString();
return "selectAccount";
}
/**
* 查询
*
* @param model
* @return
*/
@RequestMapping("/selectAccount")
public String selectAccount(Model model) {
List<Account> accountList = accountService.selectAccount();
model.addAttribute("accountList", accountList);
return "select_Account";
}
/**
* 添加前的跳转页面
*
* @return
*/
@RequestMapping("/toAccount")
public String toAccount() {
return "add_Account";
}
/**
* 添加页面
*
* @param account
* @param img
* @param request
* @return
* @throws IOException
*/
@RequestMapping("/addAccount")
public String addAccount(Account account, MultipartFile img, HttpServletRequest request) throws IOException {
if (!img.isEmpty()){
//获取上传目录
String realPath = request.getSession().getServletContext().getRealPath("uploads");
//判断文件是否存在
File file = new File(realPath);
if (!file.exists()) {
file.mkdirs();
}
//上传
String filename = img.getOriginalFilename();
img.transferTo(new File(realPath, filename));
account.setHead(filename);
}
accountService.addAccount(account);
return "redirect:selectAccount";
}
/**
* 根据id删除
*
* @param id
* @return
*/
@GetMapping("/deleteAccount/{id}")
public String deleteAccount(@PathVariable Integer id) {
accountService.deleteAccount(id);
return "redirect:/account/selectAccount";
}
/**
* 数据回显
*
* @param id
* @param model
* @return
*/
@RequestMapping("/upAccount/{id}")
public String upAccount(@PathVariable Integer id, Model model) {
Account account = accountService.selectAccountById(id);
model.addAttribute("account", account);
return "update_Account";
}
/**
* 修改
*/
@RequestMapping("/updateAccount/{id}")
public String updateAccount(@PathVariable Integer id, Account account, MultipartFile img, HttpServletRequest request) throws IOException {
if (!img.isEmpty()){
//获取上传路径
String realPath = request.getSession().getServletContext().getRealPath("uploads");
//判断目录是否存在
File file = new File(realPath);
if (!file.exists()) {
file.mkdirs();
}
//上传
String filename = img.getOriginalFilename();
img.transferTo(new File(realPath, filename));
account.setHead(filename);
}
account.setId(id);
accountService.updateAccount(account);
return "redirect:/account/selectAccount";
}
}
LoginController:
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.controller;
import com.by.pojo.User;
import com.by.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <p>Project: SpringMVC - LoginController</p>
* <p>Powered by scl On 2024-01-11 10:00:36</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
@Controller
@RequestMapping("/account")
public class LoginController {
@Autowired
private LoginService loginService;
@PostMapping("/loginAccount")
public String loginAccount(User user) {
User userDome = loginService.login(user);
if (userDome!=null)return "redirect:selectAccount";
else return "redirect:/index.jsp";
}
}
AccountService:
package com.by.service;
import com.by.pojo.Account;
import com.by.pojo.User;
import java.util.List;
/**
* <p>Project: SpringMVC - AccountService</p>
* <p>Powered by scl On 2024-01-10 16:32:52</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public interface AccountService {
List<Account> selectAccount();
void addAccount(Account account);
void deleteAccount(Integer id);
Account selectAccountById(Integer id);
void updateAccount(Account account);
}
AccountServiceImpl:
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.service;
import com.by.mapper.AccountMapper;
import com.by.pojo.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* <p>Project: SpringMVC - AccountServiceImpl</p>
* <p>Powered by scl On 2024-01-10 16:33:40</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
@Service
@Transactional
public class AccountServiceImpl implements AccountService{
@Autowired
private AccountMapper accountMapper;
@Override
public List<Account> selectAccount() {
List<Account> accountList= accountMapper.selectAccount();
return accountList;
}
@Override
public void addAccount(Account account) {
accountMapper.addAccount(account);
}
@Override
public void deleteAccount(Integer id) {
accountMapper.deleteAccount(id);
}
@Override
public Account selectAccountById(Integer id) {
return accountMapper.selectAccountById(id);
}
@Override
public void updateAccount(Account account) {
accountMapper.updateAccount(account);
}
}
LoginService:
package com.by.service;
import com.by.pojo.User;
/**
* <p>Project: SpringMVC - LoginService</p>
* <p>Powered by scl On 2024-01-11 10:26:40</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public interface LoginService {
User login(User user);
}
LoginServiceImpl:
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.service;
import com.by.mapper.LoginMapper;
import com.by.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>Project: SpringMVC - LoginServiceImpl</p>
* <p>Powered by scl On 2024-01-11 10:27:13</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
@Service
@Transactional
public class LoginServiceImpl implements LoginService {
@Autowired
private LoginMapper loginMapper;
@Override
public User login(User user) {
return loginMapper.login(user);
}
}
AccountMapper:
package com.by.mapper;
import com.by.pojo.Account;
import java.util.List;
/**
* <p>Project: SpringMVC - AccountMapper</p>
* <p>Powered by scl On 2024-01-10 16:34:53</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public interface AccountMapper {
List<Account> selectAccount();
void addAccount(Account account);
void deleteAccount(Integer id);
Account selectAccountById(Integer id);
void updateAccount(Account account);
}
AccountMapper.xml:
<?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="com.by.mapper.AccountMapper">
<insert id="addAccount" parameterType="com.by.pojo.Account">
insert into account
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name!=null and name!=''">
name,
</if>
<if test="money!=null ">
money,
</if>
<if test="date!=null ">
date,
</if>
<if test="head!=null and head!='' ">
head,
</if>
</trim>
<trim prefix="values(" suffix=")" suffixOverrides=",">
<if test="name!=null and name!=''">
#{name},
</if>
<if test="money!=null ">
#{money},
</if>
<if test="date!=null ">
#{date},
</if>
<if test="head!=null and head!='' ">
#{head},
</if>
</trim>
</insert>
<update id="updateAccount" parameterType="com.by.pojo.Account">
update account
<set>
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="money!=null ">
money=#{money},
</if>
<if test="date!=null ">
date=#{date},
</if>
<if test="head!=null and head!='' ">
head=#{head},
</if>
</set>
where id =#{id}
</update>
<delete id="deleteAccount" parameterType="java.lang.Integer">
delete
from account
where id = #{id}
</delete>
<select id="selectAccount" resultType="com.by.pojo.Account">
select *
from account
</select>
<select id="selectAccountById" parameterType="java.lang.Integer" resultType="com.by.pojo.Account">
select *
from account
where id = #{id};
</select>
</mapper>
LoginMapper:
package com.by.mapper;
import com.by.pojo.User;
/**
* <p>Project: SpringMVC - LoginMapper</p>
* <p>Powered by scl On 2024-01-11 10:28:21</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public interface LoginMapper {
User login(User user);
}
LoginMapper.xml:
<?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="com.by.mapper.LoginMapper">
<select id="login" parameterType="com.by.pojo.User" resultType="com.by.pojo.User">
select * from user where username=#{username} and password=#{password}
</select>
</mapper>
Account:
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.pojo;
import java.util.Date;
/**
* <p>Project: SpringMVC - Account</p>
* <p>Powered by scl On 2024-01-10 16:31:18</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public class Account {
private Integer id;
private String name;
private Double money;
private Date date;
private String head;
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
", date=" + date +
", head='" + head + '\'' +
'}';
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
User:
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.pojo;
/**
* <p>Project: SpringMVC - User</p>
* <p>Powered by scl On 2024-01-11 10:23:01</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public class User {
private Integer id ;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
}
这里还用到了自定义的日期转换格式:(converter包下的DateConverter)
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* <p>Project: SpringMVC - DateConverter</p>
* <p>Powered by scl On 2024-01-10 19:39:59</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
return format.parse(source);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
全局异常处理页面:GlobalException:
/*
* Copyright (c) 2020, 2024, All rights reserved.
*
*/
package com.by.exception;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <p>Project: SpringMVC - GlobalException</p>
* <p>Powered by scl On 2024-01-10 21:15:16</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
@Component
public class GlobalException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
/**
* 1.发邮件、发信息
* 2.跳转到错误页面
*/
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg",e.getMessage());
modelAndView.setViewName("exception");
return modelAndView;
}
}
add_Account.jsp:
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2024/1/10
Time: 19:09
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/account/addAccount" method="post" enctype="multipart/form-data">
账号:<input type="text" name="name"><br>
存款:<input type="text" name="money"><br>
日期:<input type="text" name="date"><br>
头像:<input type="file" name="img"><br>
<input type="submit" value="保存">
</form>
</body>
</html>
exception.jsp:
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2024/1/10
Time: 21:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
上传文件不能为空:${msg}
</body>
</html>
<style>
body{
background-image: url("https://img.zcool.cn/community/011b7b57f8b52aa84a0d304f567ff0.png@2o.png");
}
</style>
select_Account.jsp:
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2024/1/10
Time: 16:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>查询所有账户</h2>
<a href="/account/toAccount" style="text-decoration: none;font-size: 20px;color: brown">添加</a>
<table width="100%" border="1" cellspacing="0" cellpadding="0">
<tr style="background: antiquewhite ">
<th>id</th>
<th>name</th>
<th>money</th>
<th>date</th>
<th>head</th>
<th>delete</th>
</tr>
<c:forEach var="account" items="${accountList}">
<tr style="text-align: center">
<td>${account.id}</td>
<td>${account.name}</td>
<td>${account.money}</td>
<td><fmt:formatDate value="${account.date}" pattern="yyyy-MM-dd"></fmt:formatDate></td>
<td><img src="/uploads/${account.head}" height="40px" width="70px" style="display: block;
margin: auto;"></td>
<td><a href="/account/deleteAccount/${account.id}" style="text-decoration: none;color: burlywood ">删除</a>
/
<a href="/account/upAccount/${account.id}" style="text-decoration: none;color: burlywood">修改</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
update_Acount.jsp:
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2024/1/10
Time: 21:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/account/updateAccount/${account.id}" method="post" enctype="multipart/form-data">
账号:<input type="text" name="name" value="${account.name}"><br>
存款:<input type="text" name="money" value="${account.money}"><br>
<fmt:formatDate value="${account.date}" pattern="yyyy-MM-dd" var="dateTiem"></fmt:formatDate>
日期:<input type="text" name="date" value="${dateTiem}"><br>
头像:<img src="/uploads/${account.head}" height="40px" width="70px"><br>
<input type="file" name="img" value="${account.head}"><br>
<input type="submit" value="修改">
</form>
</body>
</html>
index.jsp:
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2023/8/14
Time: 9:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>用户登录</title>
<link rel="stylesheet" href="index_log.css"/>
<link href="https:/cdn.staticfile.org/layui/2.8.0/css/layui.css" rel="stylesheet">
<style type="text/css">
* {
/*初始化 清除页面元素的内外边距*/
padding: 0;
margin: 0;
/*盒子模型*/
box-sizing: border-box;
}
body {
/*弹性布局 让页面元素垂直+水平居中*/
display: flex;
justify-content: center;
align-items: center;
/*让页面始终占浏览器可视区域总高度*/
height: 100vh;
/*背景渐变色*/
background: linear-gradient(#141e30, #243b55);
/* background-image: url("https://img0.baidu.com/it/u=2635618108,3973101288&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=281"); */
background-repeat: no-repeat;
}
.login {
/*弹性布局 让子元素称为弹性项目*/
display: flex;
/*让弹性项目垂直排列 原理是改变弹性盒子的主轴方向
父元素就是弹性盒子 现在改变后的主轴方向是向下了*/
flex-direction: column;
/*让弹性项目在交叉轴方向水平居中 现在主轴的方向是向下
交叉轴的方向是与主轴垂直 交叉轴的方向是向右*/
align-items: center;
width: 400px;
padding: 40px;
background-color: rgba(0, 0, 0, 0.2);
box-shadow: 0 15px 25px rgba(0, 0, 0, 0.4);
}
.login h2 {
color: #fff;
margin-bottom: 30px;
}
.login .login_box {
/*相对定位*/
position: relative;
width: 100%;
}
.login .login_box input {
/*清除input框自带的边框和轮廓*/
outline: none;
border: none;
width: 100%;
padding: 10px 0;
margin-bottom: 30px;
color: #fff;
font-size: 16px;
border-bottom: 1px solid #fff;
/*背景颜色为透明色*/
background-color: transparent;
}
.login .login_box label {
position: absolute;
top: 0;
left: 0;
padding: 10px 0;
color: #fff;
/*这个属性的默认值是auto 默认是这个元素可以被点击
但是如果我们写了none 就是这个元素不能被点击,就好像它可见但是不能用
可望而不可及*/
/*这个就是两者的区别*/
pointer-events: none;
/*加个过度*/
transition: all 0.5s;
}
/*: focus 选择器是当input获得焦点是触发的样式 + 是相邻兄弟选择器
去找与input相邻的兄弟label*/
/*:valid 选择器是判断input 框的内容是否合法,如果合法会执行下面的属性代码,
不合法就不会执行,我们刚开始写布局的时候给input框写了required 我们删掉看对比
当没有required的话 input框的值就会被认为一直合法,所以一直都是下方的样式,
但是密码不会,密码框的值为空,那么这句话就不合法,required不能为空
当我们给密码框写点东西的时候才会执行以下代码
*/
.login .login_box input:focus + label,
.login .login_box input:valid + label {
top: -20px;
color: #03e9f4;
font-size: 12px;
}
.login a {
/*overflow: hidden;*/
position: relative;
padding: 10px 20px;
color: #03e9f4;
/*取消a表现原有的下划线*/
text-decoration: none;
/*同样加个过渡*/
transition: all 0.5s;
}
.login a:hover {
color: #fff;
border-radius: 5px;
background-color: #03e9f4;
box-shadow: 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4, 0 0 100px #03e9f4;
}
.login a span {
position: absolute;
}
.login a span:first-child {
top: 0;
left: -100%;
width: 100%;
height: 2px;
/*to right 就是往右边 下面的同理*/
background: linear-gradient(to right, transparent, #03e9f4);
/*动画 名称 时长 linear是匀速运动 infinite是无限次运动*/
animation: move1 1s linear infinite;
}
.login a span:nth-child(2) {
right: 0;
top: -100%;
width: 2px;
height: 100%;
background: linear-gradient(transparent, #03e6f4);
/*这里多了个0.25s其实是延迟时间*/
animation: move2 1s linear 0.25s infinite;
}
.login a span:nth-child(3) {
right: -100%;
bottom: 0;
width: 100%;
height: 2px;
background: linear-gradient(to left, transparent, #03e9f4);
animation: move3 1s linear 0.5s infinite;
}
.login a span:last-child {
left: 0;
bottom: -100%;
width: 2px;
height: 100%;
background: linear-gradient(#03e9f4, transparent);
animation: move4 1s linear 0.75s infinite;
}
/*写一下动画 */
@keyframes move1 {
0% {
left: -100%;
}
50%,
100% {
left: 100%;
}
}
@keyframes move2 {
0% {
top: -100%;
}
50%,
100% {
top: 100%;
}
}
@keyframes move3 {
0% {
right: -100%;
}
50%,
100% {
right: 100%;
}
}
@keyframes move4 {
0% {
bottom: -100%;
}
50%,
100% {
bottom: 100%;
}
}
#mybutton {
background: transparent;
border-width: 0px;
outline: none;
font-size: 22px;
color: white;
}
</style>
</head>
<body>
<form action="/account/loginAccount" method="post">
<div class="login">
<h2>用户登录</h2>
<div class="login_box">
<!-- required就是不能为空 必须在css效果中有很大的作用 -->
<input type="text" name='username' id='name' required/> <label for="name">用户名</label>
</div>
<div class="login_box">
<input type="password" name='password' id='pwd' required="required">
<label for="pwd">密码</label>
</div>
<a href="/account/loginAccount"> <input type="submit" value="登录" id="mybutton"> <span></span>
<span></span> <span></span> <span></span>
</a>
</div>
</form>
</body>
<script>
layui.use(function () {
var form = layui.form;
var layer = layui.layer;
// 提交事件
form.on('submit(demo-login)', function (data) {
var field = data.field; // 获取表单字段值
// 显示填写结果,仅作演示用
layer.alert(JSON.stringify(field), {
title: '当前填写的字段值'
});
// 此处可执行 Ajax 等操作
// …
return false; // 阻止默认 form 跳转
});
});
</script>
</html>