1. 环境的准备

数据库

DROP TABLE IF EXISTS `employee`;
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;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
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;

SET FOREIGN_KEY_CHECKS = 1;

1.1 引入依赖

pom.xml:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

application.yaml
1) thymeleaf的设置

        spring:
          thymeleaf:
            cache: false  # 关闭缓存
            prefix: classpath:/templates/ #指定模板位置
            suffix: .html #指定后缀

注意:thymeleaf 必须添加上:xmlns:th="http://www.thymeleaf.org">

<html lang="en" xmlns:th="http://www.thymeleaf.org">

2) 路径配置:

server:
  port: 9999
  servlet:
    context-path: /ems-thymeleaf

3) spring 相关配置

spring:

  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html

  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: 1234
  web:
    resources:
      static-locations: classpath:/static/,file:${photo.file.dir} #暴露哪些资源可以通过项目名访问

4) mybatis

mybatis:
  mapper-locations: classpath:com/baizhi/mapper/*.xml
  type-aliases-package: com.baizhi.entity
  • 注意:在 resource下面创建”com/baizhi/mapper/*.xml“时候,一点要用“/”, 不能用“.”
  • type-aliases-package:给实体类别取别名,之前的在mybatis中,每次都需要com.xx.Student, 这里这样可以统一默认别名设置。
  • 可以在主程序上面添加@MapperScan("com.baizhi.dao") 来统一设置 Mapper;或者在Mapper上添加 @Mapper来实现

1. Dao层

x.2 用户登录

创建 UserController 类,专门用于处理 User相关的请求。

@Controller
@RequestMapping("/user")
public class UserController {

}

验证码

    // 生成验证码
    @RequestMapping("/generateImageCode")
    public void generateImageCode(HttpSession session, HttpServletResponse response) throws IOException {
        // 1.  生成 4 位的随机数
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //2.保存到session作用域
        session.setAttribute("code",code);
        // 4.设置相应类型
        response.setContentType("image/png");
        // 相应
        ServletOutputStream os = response.getOutputStream();
        VerifyCodeUtils.outputImage(220,60,os,code);
    }

在 regist.html 中添加验证码

<img id="num" src="@{/user/generateImageCode}" />

同时添加可以换图片的功能:

验证码:
<img id="num" th:src="@{/user/generateImageCode}" />
<a href="javascript:;" onclick="changeImageCode()">换一张</a>
<script>
     function changeImageCode(){
        document.getElementById('num').src = '[[@{/user/generateImageCode}]]?'+(new Date()).getTime()
    }
</script>

注册
在 UserController 中, 设置 regist:

//用户注册
    @RequestMapping("/regist")
    public String regist(User user, String code, HttpSession session){
        //Ctrl + Alt + t
        // 1. 判断用户的输入的验证码和session中的一致
        try {
            String sessionCode = session.getAttribute("code").toString();
            if( !sessionCode.equalsIgnoreCase(code))
                throw new RuntimeException("验证码错误");
            // 如果验证码一致,就正常注册
            userServiceImp.register(user);
        } catch (RuntimeException e) {
            e.printStackTrace();
            // 重返 regist 界面
            return "redirect:/regist";
        }
        // 注册成功, 返回 login 界面
        return "redirect:/login";
    }

登录
在UserController里面:

//用户登录
    @RequestMapping("/toLogin")
    public String login(String username, String password, HttpSession session){
        try {
            // 1. 调用Service 层进行登录
            User user = userServiceImp.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);
        System.out.println(username);

        if( ObjectUtils.isEmpty(user))
            throw new RuntimeException("用户名不正确");
        // 2. 比较密码
        String s = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        if( !user.getPassword().equals(s))
            throw new RuntimeException("密码错误");
        return user;
    }

x.3 员工信息

展示所有员工信息:

@Controller
@RequestMapping("employee")
public class EmployeeController {

    @Autowired
    private EmployeeServiceImp employeeService;
    // 员工列表
    @RequestMapping("lists")
    public String list(Model model){
        List<Employee> allEmployees = employeeService.getAllEmployees();
        model.addAttribute("employeeList", allEmployees);
        return "emplist";
    }
}

文件上传
在数据库中,图片保存的是地址;

    1. 首先在项目下创建 photo 目录,用于保存上传的图片
    1. 在 yaml 文件中配置文件夹的路径信息:

      photo:
        file:
          dir: # photo的绝对路径
    1. 一般项目无法直接访问 photo目录,可以利用spring.web.resources.static-locations 来保留该文件夹:

      spring: 
        web:
          resources:
           static-locations: classpath:/static/,file:${photo.file.dir} #暴露哪些资源可以通过项目名访问
    1. 文件时候,在 form表单还需满足:1)提交的方法method为post, 2)enctype提交方式为multipart/form-data
  • 在EmployeeController 中,保存员工的信息为
    // 保存员工信息
    // Employee 用来接受员工的信息,MultipartFile用来接受图形的变量
    @RequestMapping("/save")
    public String saveEmployee(Employee employee, MultipartFile img) throws IOException {

        String originalFilename = img.getOriginalFilename();

        // 1.  处理头像文件的上传和修改文件名称
        String fileNamePrefix = new SimpleDateFormat("yyyyMMddHHmmssSSS").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";
    }

前端页面显示,可以:

<img th:src="@{/}+ ${employee.photo}" width="60">

更新员工列表
在所有员工的列表中去跳转:

    // 修改更新
    @RequestMapping("/toUpdateEmployee")
    public String toUpdateEmployee(int id,Model model){
        // 1. 根据 id 查询
        Employee employee = employeeService.getById(id);
        // 2.  保存在
        model.addAttribute("employee", employee);
        return "updateEmp";
    }

其中,前端传参,可以使用 thymeleaf的语法:

<a th:href="@{/employee/toUpdateEmployee(id=${employee.id})}">更新</a>

在toUpdateEmployee后面括号里面加上各种参数,thymeleaf会自动拼接。

在updateEmp中,表单数据提交到 /employee/update的请求中去:

// 接受Employee的信息和 头像的信息
    @RequestMapping("/update")
    public String update(Employee employee, MultipartFile img) throws IOException {
        //1. 首先判断头像是否为空
        if( !img.isEmpty() ){  // 加入用户更新头像
            // 先删除旧的头像
            String oldPhotoPath = employeeService.getById(employee.getId()).getPhoto();
            File file = new File(realPath, oldPhotoPath);
            if ( file.exists()){
                file.delete();   // 如果存在首先先删除
            }
            // 2. 处理新的图片
            String prefix = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            String suffix = img.getOriginalFilename().substring(img.getOriginalFilename().lastIndexOf("."));
            String newFileName = prefix + suffix;
            img.transferTo(new File(realPath, newFileName));
            // 修改名称
            employee.setPhoto(newFileName);
        }
        // 更新员工表
        employeeService.updateEmployee(employee);
        return "redirect:/employee/lists";  // 查询成功,跳转到员工列表
    }

逻辑为:
1)先判断头像图片,即:img.isEmpty() 来判断图片更新的问题。
2)如果有图片先删除以前的图片,在更新现在的图片
3)去update

在updateEmp界面中:首先保证method为post,enctype为multipart/form-data:

<form th:action="@{/employee/update}" method="post" enctype="multipart/form-data">

同时设置隐藏域:

<input type="hidden" name="id" th:value="${employee.id}">
<input type="text" class="inputgri" name="name" th:value="${employee.name}"/>
<input type="hidden" th:value="${employee.photo}" name="photo">

用来提交表单数据。

更新删除

    // 删除员工
    @RequestMapping("/delete")
    public String delete(Integer id){
        // 首先查询到 photo
        String photo = employeeService.getById(id).getPhoto();
        //删除
        employeeService.deleteEmployee(id);
        //
        File file = new File(realPath, photo);
        if ( file.exists())
            file.delete();

        return "redirect:/employee/lists";
    }
  • 如果要删除员工,就要同时删除数据库里面的记录和服务器上的图片

安全退出
主要清除Session:

    // 安全退出
    @RequestMapping("/logout")
    public String logout(HttpSession session){
        session.invalidate();
        return "redirect:/login";
    }

phang
1 声望3 粉丝

« 上一篇
SpringBoot&Mybatis
下一篇 »
VerifyCodeUtils