springboot基础案例(二)

文章目录

  • 前言
  • 一.需求分析: 分析这个项目含有哪些功能模块
  • 二.库表设计(概要设计): 1.分析系统有哪些表 2.分析表与表关系 3.确定表中字段(显性字段 隐性字段(业务字段))
    • 2.1 创建一个库: ems-thymeleaf
    • 2.2 创建 2张表
    • 三.编码(环境搭建)
      • 1.创建一个springboot项目 项目名字: ems-thymeleaf
      • 2.修改配置文件为 application.yml pom.xml
      • 3.修改端口 9999 项目名: ems-thymeleaf
      • 4.springboot整合thymeleaf使用
      • 5.springboot整合mybatis
      • 6.导入项目页面
      • 7.配置thymeleaf模版controller统一请求
    • 四.编码(业务代码开发)
      • 1.验证码实现
      • 2.用户注册实现
      • 3.用户登录实现
      • 3.员工列表实现
      • 4.增加员工信息
      • 5.更新员工的实现
      • 6.删除员工的实现

前言

一.需求分析: 分析这个项目含有哪些功能模块

	用户模块:
		注册
		登录
		验证码
		安全退出
		真是用户
	员工模块:
		添加员工+上传头像
		展示员工列表+展示员工头像
		删除员工信息+删除员工头像
		更新员工信息+更新员工头像

二.库表设计(概要设计): 1.分析系统有哪些表 2.分析表与表关系 3.确定表中字段(显性字段 隐性字段(业务字段))

2.1 创建一个库: ems-thymeleaf

2.2 创建 2张表

1.用户表 user
id username realname password gender

CREATE TABLE `employee` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(60) DEFAULT NULL COMMENT '员工姓名',
  `salary` double(10,2) DEFAULT NULL COMMENT '员工工资',
  `birthday` datetime DEFAULT NULL COMMENT '员工生日',
  `photo` varchar(200) DEFAULT NULL COMMENT '头像路径',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2.员工表 employee
id name salary birthday photo

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(40) DEFAULT NULL COMMENT '用户名',
  `realname` varchar(60) DEFAULT NULL COMMENT '真实姓名',
  `password` varchar(40) DEFAULT NULL COMMENT '密码',
  `gender` tinyint(1) unsigned DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

三.编码(环境搭建)

1.创建一个springboot项目 项目名字: ems-thymeleaf

在这里插入图片描述

2.修改配置文件为 application.yml pom.xml

修改poml版本为 springboot版本为2.7.14
在这里插入图片描述

把application.properties修改为application.yml
在这里插入图片描述

3.修改端口 9999 项目名: ems-thymeleaf

在这里插入图片描述

4.springboot整合thymeleaf使用

a.引入依赖

<!--		引入thymeleaf-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

b.配置文件中指定thymeleaf相关配置

spring:
  thymeleaf:
    prefix: classpath:/templates/  #指定thymeleaf模板前缀目录
    suffix: .html                  #指定模板的后缀
    cache: false                    #是否开启thymeleaf缓存 默认值是true开启缓存  在开发过程中推荐使用false

c.编写控制器测试

@Controller
@RequestMapping("demo")
public class DemoController {

    private static final Logger log = LoggerFactory.getLogger(DemoController.class);

    @RequestMapping("demo")
    public String demo(Model model){
        log.debug("demo ok");
        model.addAttribute("msg","hello thymeleaf");
        return "demo";
    }


}

d.最后访问
在这里插入图片描述

5.springboot整合mybatis

a.引入依赖
mysql、druid、mybatis-springboot-stater

<!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>

        <!--druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.4</version>
        </dependency>

        <!--myabtis-springboot-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

b.配置文件

# 数据库的配置
# 数据库的配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ems-thymeleaf?characterEncoding=UTF-8
    username: root
    password: 123456

#配置mybatis
mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml
  type-aliases-package: com.demo.entity

# 日志配置
logging:
  level:
    root: info
    com.demo: debug

6.导入项目页面

static 存放静态资源
在这里插入图片描述

templates 目录 存放模板文件
在这里插入图片描述

7.配置thymeleaf模版controller统一请求

因为我们thymeleaf模板开发,要访问静态资源的时候,我们必须建controller请求,这样比较麻烦,我们可以统一配置,具体操作如下:

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    通过这里面配置: 不需要为每一个访问thymeleaf模板页面单独开发一个controller请求了
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //viewController 请求路径    viewName: 跳转视图
        registry.addViewController("login").setViewName("login");
        registry.addViewController("register").setViewName("regist");
    }
}

四.编码(业务代码开发)

1.验证码实现

在这里插入图片描述
Controller代码如下:

 @RequestMapping("generateImageCode")
    public void generateImageCode(HttpSession session, HttpServletResponse response) throws IOException {
        //1.生成4位随机数
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //2.保存到session作用域
        session.setAttribute("code",code);
        //3.根据随机数生成图片 && 4.通过response响应图片  && 5.设置响应类型
        response.setContentType("image/png");
        ServletOutputStream os = response.getOutputStream();
        VerifyCodeUtils.outputImage(220,60, os,code);
    }
}

前端页面改的位置
在这里插入图片描述

2.用户注册实现

在这里插入图片描述
Controller

  @RequestMapping("register")
    public String register(User user, String code,HttpSession session){
        log.debug("用户名: {},真是姓名: {},密码: {},性别: {},",user.getUsername(),user.getRealname(),user.getPassword(),user.getGender());
        log.debug("用户输入验证码: {}",code);

        try {
            //1.判断用户输入验证码和session中验证码是否一致
            String sessionCode = session.getAttribute("code").toString();
            if(!sessionCode.equalsIgnoreCase(code))throw new RuntimeException("验证码输入错误!");
            //2.注册用户
            userService.register(user);
        } catch (RuntimeException e) {
            e.printStackTrace();
            return "redirect:/register"; //注册失败回到注册
        }
        return  "redirect:/login";  //注册成功跳转到登录
    }

实体类

public class User {
    private Integer id;
    private String username;
    private String realname;
    private String password;
    private Boolean gender;
    }

Service

public class UserService {
    /**
     * 注册用户
     */
    private UserMapper userMapper;
    @Autowired
    public UserService(UserMapper userMapper){
        this.userMapper=userMapper;

    }
    public void register(User user) {
        //1.根据用户名查询数据库中是否存在改用户
        User userDB = userMapper.findByUserName(user.getUsername());
        //2.判断用户是否存在
        if(!ObjectUtils.isEmpty(userDB)) throw new RuntimeException("当前用户名已被注册!");
        //3.注册用户&明文的密码加密  特点: 相同字符串多次使用md5就行加密 加密结果始终是一致
        String newPassword = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
        user.setPassword(newPassword);
        userMapper.save(user);
    }
}

Mapper

    <!--findByUserName-->
    <select id="findByUserName" parameterType="String" resultType="User">
        select id,username,realname,password,gender from `user`
        where username = #{username}
    </select>

    <!--save-->
    <insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        insert into `user` values(#{id},#{username},#{realname},#{password},#{gender})
    </insert>

3.用户登录实现

在这里插入图片描述
Controller

 @RequestMapping("login")
    public String login(String username,String password,HttpSession session){
        log.debug("本次登录用户名: {}",username);
        log.debug("本地登录密码: {}",password);
        try {
            //1.调用业务层进行登录
            User user = userService.login(username,password);
            //2.保存用户信息
            session.setAttribute("user",user);
        } catch (Exception e) {
            e.printStackTrace();
            return "redirect:/login";//登录失败回到登录界面
        }
        return "redirect:/employee/lists";//登录成功之后,跳转到查询所有员工信息控制器路径
    }

Service

 public User login(String username, String password) {
        //1.根据用户名查询用户
        User user = userMapper.findByUserName(username);
        if(ObjectUtils.isEmpty(user)) throw new RuntimeException("用户名不正确!");
        //2.比较密码
        String passwordSecret = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        if(!user.getPassword().equals(passwordSecret)) throw new RuntimeException("密码输入错误!");
        return user;
    }

Mapper

    <!--findByUserName-->
    <select id="findByUserName" parameterType="String" resultType="User">
        select id,username,realname,password,gender from `user`
        where username = #{username}
    </select>

3.员工列表实现

在这里插入图片描述
实体类

public class Employee {
    private Integer id;
    private String name;
    private Double salary;
    private Date birthday;
    private String photo;//头像路径
    }

Controller

 @RequestMapping("lists")
    public String lists(Model model){
        log.debug("查询所有员工信息");
        List<Employee> employeeList=employeeService.lists();
        model.addAttribute("employeeList",employeeList);

        return "emplist";
    }

Service

public List<Employee> lists(){
        return employeeMapper.lists();
    }

Mapper

 <!--lists-->
    <select id="lists" resultType="Employee">
        select id,name,salary,birthday,photo from `employee`
    </select>

4.增加员工信息

在这里插入图片描述

Controller

 @RequestMapping("save")
    public String save(Employee employee, MultipartFile img) throws IOException {
        log.debug("姓名:{}, 薪资:{}, 生日:{} ", employee.getName(), employee.getSalary(), employee.getBirthday());
        String originalFilename = img.getOriginalFilename();
        log.debug("头像名称: {}", originalFilename);
        log.debug("头像大小: {}", img.getSize());
        log.debug("上传的路径: {}",realpath);
        //1.处理头像的上传&& 修改文件名
        String fileNamePrefix = new SimpleDateFormat("yyyyMMddHHmmsssSSS").format(new Date());
        String fileNameSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName=fileNamePrefix+fileNameSuffix;
        img.transferTo(new File(realpath,newFileName));
        //2.保存员工信息
        employee.setPhoto(newFileName);
        employeeService.save(employee);
        return "redirect:/employee/lists";
    }

Service

 public void save(Employee employee) {
    employeeMapper.save(employee);
    }

Mapper

    <insert id="save" parameterType="Employee" useGeneratedKeys="true" keyProperty="id">
        insert into `employee` values (#{id},#{name},#{salary},#{birthday},#{photo})
    </insert>

5.更新员工的实现

在这里插入图片描述

Controller

 /**
     * 更新员工信息
     * @param employee
     * @param img
     * @return
     */
    @RequestMapping("update")
    public String update(Employee employee,MultipartFile img) throws IOException {
        log.debug("更新之后员工信息: id:{},姓名:{},工资:{},生日:{},", employee.getId(), employee.getName(), employee.getSalary(), employee.getBirthday());
        //1.判断是否更新头像
        boolean notEmpty = !img.isEmpty();
        log.debug("是否更新头像: {}", notEmpty);
        if (notEmpty) {
            //1.删除老的头像 根据id查询原始头像
            String oldPhoto = employeeService.findById(employee.getId()).getPhoto();
            File file = new File(realpath, oldPhoto);
            if (file.exists()) file.delete();//删除文件
            //2.处理新的头像上传
            String originalFilename = img.getOriginalFilename();
            String newFileName = uploadPhoto(img, originalFilename);
            //3.修改员工新的头像名称
            employee.setPhoto(newFileName);
        }
        //2.没有更新头像直接更新基本信息
        employeeService.update(employee);
        return "redirect:/employee/lists";//更新成功后,跳转到所有员工列表
    }
    //上传头像方法
    private String uploadPhoto(MultipartFile img, String originalFilename) throws IOException {
        String fileNamePrefix = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        String fileNameSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName = fileNamePrefix + fileNameSuffix;
        img.transferTo(new File(realpath, newFileName));
        return newFileName;
    }

Service

  public void update(Employee employee) {
        employeeMapper.update(employee);
    }

Mapper

 <update id="update" parameterType="Employee" >
        update `employee` set name=#{name},salary=#{salary},birthday=#{birthday},photo=#{photo}
        where id = #{id}
    </update>

6.删除员工的实现

Controller

    @RequestMapping("delete")
    public String delete(Integer id){
        log.debug("删除的员工id: {}",id);
        //1.删除数据
        String photo = employeeService.findById(id).getPhoto();
        employeeService.delete(id);
        //2.删除头像
        File file = new File(realpath, photo);
        if (file.exists()) file.delete();
        return "redirect:/employee/lists";//跳转到员工列表
    }

Service

public void delete(Integer id) {
        employeeMapper.delete(id);
    }

Mapper

  <!--delete-->
    <delete id="delete" parameterType="Integer">
        delete from `employee` where id = #{id}
    </delete>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu环境下安装部署Nginx(有网)

本文档适用于在Ubuntu20.04系统下部署nginx 一、使用apt-get命令安装nginx 注&#xff1a;以下命令都是在root用户下使用 1. 检查是否存在apt命令 apt –version 说明&#xff1a;出现版本号就说明当前环境存在apt 2. 更新apt命令 apt update 3. 安装nginx apt-get in…

【保姆级教程|YOLOv8改进】【7】多尺度空洞注意力(MSDA),DilateFormer实现暴力涨点

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

Minecraft 上 An Existing Connection Was Forcibly Closed by the Remote Host 错误

本篇文章介绍了使用 Minecraft 时出现远程主机错误强制关闭现有连接的原因和解决方案。 Minecraft 上 Java.IO.IOException: An Existing Connection Was Forcibly Closed by the Remote Host 原因 Minecraft 是一款使用 Java 开发的流行游戏。 由于其流行&#xff0c;服务器…

jxls 2.4.5 —— 动态导出excel 表头与数据

文章目录 前言依赖引入制作导出模板测试类导出效果注意事项 前言 再之前的博客中&#xff0c;介绍了jxls的基础使用。但导出表头属于写死的&#xff0c;并未采取动态渲染。 本次进行动态渲染操作&#xff0c;动态渲染表头和填充数据。 依赖引入 springboot测试项目中&#…

AdaBoost算法

Boosting是一种集成学习方法&#xff0c;AdaBoost是Boosting算法中的一种具体实现。 Boosting方法的核心思想在于将多个弱分类器组合成一个强分类器。这些弱分类器通常是简单的模型&#xff0c;比如决策树&#xff0c;它们在训练过程中的错误会被后续的弱分类器所修正。Boosti…

多元回归分析:理论与应用

多元回归分析是一种统计方法&#xff0c;用于研究两个或多个自变量&#xff08;解释变量&#xff09;与一个因变量&#xff08;响应变量&#xff09;之间的关系。这种分析允许研究者评估多个因素对结果变量的影响&#xff0c;是社会科学、经济学、生物医学和工程等多个领域中常…

SolidWorks学习笔记——入门知识1

目录 1、固定最近文档 2、根据需要自定义菜单栏 3、根据需要增添选项卡 4、命令搜索框 5、鼠标右键长按快速切换视图 6、鼠标笔势 自定义鼠标笔势 1、固定最近文档 图1 固定最近文档 2、根据需要自定义菜单栏 图2 根据需要自定义菜单栏 3、根据需要增添选项卡 图3 根据…

Linux介绍和命令使用

目录 目录 一、Linux简介 1.1 主流操作系统 1.2 Linux 发展历史 1.3 Linux系统版本 二、Linux安装 三、Linux 目录结构 四、Linux常用命令 4.1 基础常用命令说明 4.2 Linux 命令使用技巧 4.3 Linux 命令格式 4.4 进阶重点常用命令 4.4.1 拷贝移动命令 4.4.2 打包…

09 AB 10串口通信发送原理

通用异步收发传输器&#xff08; Universal Asynchronous Receiver/Transmitter&#xff0c; UART&#xff09;是一种异步收发传输器&#xff0c;其在数据发送时将并行数据转换成串行数据来传输&#xff0c; 在数据接收时将接收到的串行数据转换成并行数据&#xff0c; 可以实现…

springboot项目热部署实现(Spring Boot DevTools方式)

文章目录 Spring Boot DevTools简介Spring Boot DevTools原理spring Boot Devtools优缺点Spring Boot DevTools集成步骤第一步&#xff1a;添加maven依赖第二步&#xff1a;IDEA热部署配置 Spring Boot DevTools简介 Spring Boot DevTools是Spring Boot提供的一个开发工具&…

二维数组的使用

一、二维数组的使用 动态初始化静态初始化 1、动态初始化 2、静态初始化

【Git版本控制 05】多人协作

目录 一、邀请开发用户 二、新建远程分支 三、拉取远程分支 四、推送远程分支 五、合并远程分支 六、多分支协作 一、邀请开发用户 在windows环境下&#xff0c;再clone同⼀个项⽬仓库&#xff0c;来模拟⼀起协作开发的另⼀名⼩伙伴。 际开发中&#xff0c;每个⽤⼾都有…

【flink状态管理(三)】StateBackend的整体设计、StateBackend创建说明

文章目录 一. 状态后端概述二. StateBackend的整体设计1. 核心功能2. StateBackend的UML3. 小结 三. StateBackend的加载与初始化1. StateBackend创建概述2. StateBackend创建过程 一. 状态后端概述 StateBackend作为状态存储后端&#xff0c;提供了创建和获取KeyedStateBacke…

【51单片机】实现一个动静态数码管显示项目(超全详解&代码&图示)(5)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY…

vue项目打包部署到flask等后端服务里面,实现前后端不分离部署,解决空白页面和刷新页面not fount问题

1. 编译模式一定要设置为esnext&#xff0c;否则会报错&#xff1a; Strict MIME type checking is enforced for module scripts per HTML spec.Expected a JavaScript module script but the server responded with a MIME type of "text/plain". 具体解释可以看vi…

牛客网SQL进阶127: 月总刷题数和日均刷题数

官网链接&#xff1a; 月总刷题数和日均刷题数_牛客题霸_牛客网现有一张题目练习记录表practice_record&#xff0c;示例内容如下&#xff1a;。题目来自【牛客题霸】https://www.nowcoder.com/practice/f6b4770f453d4163acc419e3d19e6746?tpId240 0 问题描述 基于练习记录表…

PyTorch深度学习实战(23)——从零开始实现SSD目标检测

PyTorch深度学习实战&#xff08;23&#xff09;——从零开始实现SSD目标检测 0. 前言1. SSD 目标检测模型1.1 SSD 网络架构1.2 利用不同网络层执行边界框和类别预测1.3 不同网络层中默认框的尺寸和宽高比1.4 数据准备1.5 模型训练 2. 实现 SSD 目标检测2.1 SSD300 架构2.2 Mul…

深度学习的新进展:解析技术演进与应用前景

深度学习的新进展&#xff1a;解析技术演进与应用前景 深度学习&#xff0c;作为人工智能领域的一颗璀璨明珠&#xff0c;一直以来都在不断刷新我们对技术和未来的认知。随着时间的推移&#xff0c;深度学习不断迎来新的进展&#xff0c;这不仅推动了技术的演进&#xff0c;也…

Vue中路由守卫的详细应用

作为一名web前端开发者&#xff0c;我们肯定经常使用Vue框架来构建我们的项目。而在Vue中&#xff0c;路由是非常重要的一部分&#xff0c;它能够实现页面的跳转和导航&#xff0c;提供更好的用户体验。然而&#xff0c;有时我们需要在路由跳转前或跳转后执行一些特定的逻辑&am…

vue3项目中的404页面

vue3项目中的404页面 春节前的最后一篇技术博客了 写了不少vue项目&#xff0c;发现一直没有正确处理404页面。404页面的出现有这么几种可能&#xff1a; 错误输入了页面地址路由连接跳转时&#xff0c;某些路由已经不存在了&#xff0c;而程序员并没有正确处理 也就是说40…