springboot学习笔记springboot入门学习(完更)

springboot学习笔记springboot入门学习

技术栈:spring boot,mybatis,thymeleaf,MySQL等

实现的功能:管理员登录,员工的增删查改

工具 版本
JDK 1.8
mysql 8.0
navicat for mysql 11
IDEA 2019.1
maven 3.6.0
springboot 2.2.5

源码地址:springboot-start

1.简单的认识

1.1Spring Boot

Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。

1.2微服务:

微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合;可以通过http的方式进行互通。

2数据库准备

新建数据库

department表

/*
Navicat MySQL Data Transfer

Source Server         : 本地连接
Source Server Version : 80014
Source Host           : localhost:3306
Source Database       : study-springboot

Target Server Type    : MYSQL
Target Server Version : 80014
File Encoding         : 65001

Date: 2020-03-06 15:19:11
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for department
-- ----------------------------
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1017 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- ----------------------------
-- Records of department
-- ----------------------------
INSERT INTO `department` VALUES ('1001', '软件工程');
INSERT INTO `department` VALUES ('1002', '数字媒体');
INSERT INTO `department` VALUES ('1003', '计算机科学');
INSERT INTO `department` VALUES ('1004', '网络工程');
INSERT INTO `department` VALUES ('1005', '信息管理');
INSERT INTO `department` VALUES ('1006', '大数据');
INSERT INTO `department` VALUES ('1007', '信息技术');
INSERT INTO `department` VALUES ('1008', '自动化');
INSERT INTO `department` VALUES ('1009', '通信');
INSERT INTO `department` VALUES ('1010', '英语学');
INSERT INTO `department` VALUES ('1011', '商务英语');
INSERT INTO `department` VALUES ('1012', '旅游学');
INSERT INTO `department` VALUES ('1013', '工商管理');
INSERT INTO `department` VALUES ('1014', '行政管理');
INSERT INTO `department` VALUES ('1015', '经济学');
INSERT INTO `department` VALUES ('1016', '土木建筑');

employee表

/*
Navicat MySQL Data Transfer

Source Server         : 本地连接
Source Server Version : 80014
Source Host           : localhost:3306
Source Database       : study-springboot

Target Server Type    : MYSQL
Target Server Version : 80014
File Encoding         : 65001

Date: 2020-03-06 15:19:18
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ename` varchar(20) COLLATE utf8mb4_general_ci NOT NULL,
  `gender` int(2) NOT NULL,
  `dpid` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`dpid`),
  CONSTRAINT `id` FOREIGN KEY (`dpid`) REFERENCES `department` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=163 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- ----------------------------
-- Records of employee
-- ----------------------------
INSERT INTO `employee` VALUES ('134', '张三1', '1', '1001');
INSERT INTO `employee` VALUES ('135', '李四', '0', '1003');
INSERT INTO `employee` VALUES ('136', '王五', '1', '1005');
INSERT INTO `employee` VALUES ('137', '赵六', '1', '1004');
INSERT INTO `employee` VALUES ('138', '佩奇', '0', '1006');
INSERT INTO `employee` VALUES ('139', '吉吉国王', '1', '1002');
INSERT INTO `employee` VALUES ('140', '露娜', '0', '1001');
INSERT INTO `employee` VALUES ('141', '张伟', '1', '1013');
INSERT INTO `employee` VALUES ('142', '王伟', '1', '1007');
INSERT INTO `employee` VALUES ('143', '王芳', '0', '1014');
INSERT INTO `employee` VALUES ('144', '王秀英', '0', '1005');
INSERT INTO `employee` VALUES ('145', '张明', '0', '1015');
INSERT INTO `employee` VALUES ('146', '王静', '0', '1013');
INSERT INTO `employee` VALUES ('147', '刘洋', '1', '1010');
INSERT INTO `employee` VALUES ('148', '李杰', '1', '1011');
INSERT INTO `employee` VALUES ('149', '张燕', '0', '1008');
INSERT INTO `employee` VALUES ('150', '王秀兰', '0', '1014');
INSERT INTO `employee` VALUES ('151', '李丽', '0', '1015');
INSERT INTO `employee` VALUES ('152', '李霞', '0', '1013');
INSERT INTO `employee` VALUES ('153', '刘敏', '0', '1012');
INSERT INTO `employee` VALUES ('154', '张军', '1', '1009');
INSERT INTO `employee` VALUES ('155', '王品', '1', '1011');
INSERT INTO `employee` VALUES ('156', '张洁', '0', '1007');
INSERT INTO `employee` VALUES ('157', '熊大', '1', '1008');
INSERT INTO `employee` VALUES ('158', '熊二', '1', '1001');
INSERT INTO `employee` VALUES ('162', '光头强', '1', '1015');

loginuser表

/*
Navicat MySQL Data Transfer

Source Server         : 本地连接
Source Server Version : 80014
Source Host           : localhost:3306
Source Database       : study-springboot

Target Server Type    : MYSQL
Target Server Version : 80014
File Encoding         : 65001

Date: 2020-03-04 22:32:17
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for loginuser
-- ----------------------------
DROP TABLE IF EXISTS `loginuser`;
CREATE TABLE `loginuser` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(20) COLLATE utf8mb4_general_ci NOT NULL,
  `password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- ----------------------------
-- Records of loginuser
-- ----------------------------
INSERT INTO `loginuser` VALUES ('1', 'admin', 'admin');
INSERT INTO `loginuser` VALUES ('2', '张三', '1');
INSERT INTO `loginuser` VALUES ('3', '1', '1');

3.搭建程序

在idea里面新建一个springboot项目

3.1 pom.xml


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.2.5.RELEASEversion>
        <relativePath/> 
    parent>
    <groupId>cn.xiaovgroupId>
    <artifactId>springboot-startartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>springboot-startname>
    <description>Demo project for Spring Bootdescription>

    <properties>
        <java.version>1.8java.version>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.1.10version>
        dependency>

        
        <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-thymeleafartifactId>
    dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-jdbcartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>2.1.1version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <scope>runtimescope>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

project>

导入静态资源,主要的几个页面。

3.2 编写JavaBean对象

新建一个domain包,在编写Employee和Department类以及LoginUser类,然后生成get和set方法以及toString方法。

package cn.xiaov.domain;

import java.io.Serializable;

public class Employee implements Serializable {

    private static final long serialVersionUID = -2409001679665488385L;

    private Integer id;
    private String ename;
    private Integer gender;
    private Integer dpid;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public Integer getDpid() {
        return dpid;
    }

    public void setDpid(Integer dpid) {
        this.dpid = dpid;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", ename='" + ename + '\'' +
                ", gender=" + gender +
                ", dpid=" + dpid +
                '}';
    }
}
package cn.xiaov.domain;

import java.io.Serializable;

public class Department implements Serializable {
    private static final long serialVersionUID = 2805528070551144200L;

    private Integer id;
    private String dname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", dname='" + dname + '\'' +
                '}';
    }
}
package cn.xiaov.domain;

import java.io.Serializable;

public class LoginUser implements Serializable {
    private static final long serialVersionUID = -4476776387474146618L;
    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;
    }

    @Override
    public String toString() {
        return "LoginUser{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

3.3 配置application.properties文件

#数据库配置
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/study_ssm
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

#首页
server.servlet.context-path=/

#禁用模板缓存
spring.thymeleaf.cache=false

3.4 扩展MvcConfig

新建一个config包,新建一个MyMvcConfig类

package cn.xiaov.Config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/login.html").setViewName("index");
    }
}

这样就可以访问首页了,在浏览器中输入:http://localhost:8080/index.html或者http://localhost:8080就可以访问到index.html.

4.国际化

重要:先在IDEA中统一设置properties的编码问题!

setting>Editor>File Encodings 将此页面的所有编码改成UTF-8
特别是下面一个properties Files,并勾选后面的Transparent.

在resources下新建一个名为 i18n 的文件夹。

再新建一个login.properties的文件,继续新建login_zh_CN.properties,以及login_en_US.properties文件。

然后新建login.tip,login.username,login.password,login.remember,login.btn。

总而言之,3个文件的内容为:

login.properties

login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名

login_en_US.properties

login.btn=Sign in
login.password=Password
login.remember=Remember me
login.tip=Please sign in
login.username=Username

login_zh_CN.properties

login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名

在application.properties中配置国际化文件类路径:

#国际化文件
spring.messages.basename=i18n.login

更改index.html中form表单的内容。

使用#{}表示与国际化相关的内容。行类直接用th:text=“#{login.username}”,行外用[[#{login.remember}]]

index.html

<form class="form-signin" th:action="@{/user/login}" method="post">
   <img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72">
    <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign inh1>   
   <input type="text" name="username" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus="">
   <input type="password" name="password" class="form-control" placeholder="Password" th:placeholder="#{login.password}" required="">
   <div class="checkbox mb-3">
      <label>
        <input type="checkbox" value="remember-me">[[#{login.remember}]]
      label>
   div>
   <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign inbutton>
   <p class="mt-5 mb-3 text-muted">© 2017-2018p>
   <a class="btn btn-sm">中文a>
   <a class="btn btn-sm">Englisha>
form>

在浏览器中输入:http://localhost:8080/index.html或者http://localhost:8080 如果你的浏览器设置的是中文的话,直接就是中文显示了,如果你的浏览器是英文的话,就是英文界面了。

但是我们想要自己实现中英文切换的语言需求呢。

需要在链接中添加参数

<a class="btn btn-sm" th:href="@{/login.html(l='zh_CN')}">中文a>
<a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">Englisha>

需要在config中新建一个MyLocaleResolver

实现提取地区参数的功能

package cn.xiaov.Config;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        String lang=httpServletRequest.getParameter("l");
        Locale locale=Locale.getDefault();
        if (!StringUtils.isEmpty(lang)){
            //不为空,携带地区参数
            String[] split = lang.split("_");
            locale= new Locale(split[0],split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

    }
}

并将这个组件加入到spring容器中,在MyMvcConfig中添加

@Bean
public LocaleResolver localeResolver(){
    return new MyLocaleResolver();
}

在浏览器中输入:http://localhost:8080 ,点击下方中文会切换到中文,点击下方英文会切换到英文。

5.实现登录功能

在index.html中导入thymeleaf依赖,

xmlns:th=“http://www.thymeleaf.org”

根据thymeleaf的知识修改index.html的内容。

将所有链接换成@{}的形式,例如:

//修改前
<link href="asserts/css/bootstrap.min.css}" rel="stylesheet">
//修改后
<link th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">

在输入框中加入name属性(重要)

将action换成自己需要的action,将请求换成post请求。

编写loginController,在里面调用service层的方法,service层再调用dao层的方法。如果登录成功就将用户名存入session中。

为了避免代码的重复提交,我们在登陆成功后希望直接重定向到dashboard.html页面,所以我们再配置试图解析。在controller中成功返回dashboard,我们可以返回main.xml。

return "redirect:/main.html";

此时我们需要在MyMvcConfig中添加路径映射

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("index");
    registry.addViewController("/login.html").setViewName("index");
    registry.addViewController("/main.html").setViewName("dashboard");
}

这样重定位的main.html就被映射到dashboard.html中了。

代码示例:

index.html


<html lang="en" xmlns:th="http://www.thymeleaf.org">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <meta name="description" content="">
      <meta name="author" content="">
      <title>Signin Template for Bootstraptitle>
      
      <link th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">
      
      <link th:href="@{/asserts/css/signin.css}" rel="stylesheet">
   head>

   <body class="text-center">
      <form class="form-signin" th:action="@{/user/login}" method="post">
         <img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72">
         <h1 class="h3 mb-3 font-weight-normal">Please sign inh1>

         
         <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}">p>
          
         <input type="text" th:name="username" class="form-control" placeholder="Username" required="" autofocus="">
         <input type="password" th:name="password" class="form-control" placeholder="Password" required="">
         <div class="checkbox mb-3">
            <label>
          <input type="checkbox" value="remember-me"> Remember me
        label>
         div>
         <button class="btn btn-lg btn-primary btn-block" type="submit">Sign inbutton>
         <p class="mt-5 mb-3 text-muted">© 2017-2018p>
         <a class="btn btn-sm" th:href="@{/login.html(l='zh_CN')}">中文a>
		 <a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">Englisha>
      form>
   body>
html>

loginController

package cn.xiaov.controller;

import cn.xiaov.domain.LoginUser;
import cn.xiaov.service.LoginUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;
import java.util.List;

@Controller
@RequestMapping("/user")
public class loginController {
    @Autowired
    LoginUserService loginUserService;

    @PostMapping("/login")
    public String login(LoginUser user, Model model, HttpSession session) {
        String username = user.getUsername();
        String password = user.getPassword();
        //用户名为空
        if (StringUtils.isEmpty(username)) {
            model.addAttribute("msg", "用户名为空");
            return "index";
        }
        //密码为空
        if (StringUtils.isEmpty(password)) {
            model.addAttribute("msg", "密码为空");
            return "index";
        }
        //有密码,有账号
        List<LoginUser> users = loginUserService.findByUserName(username);
        //用户名不存在
        if (users == null || users.size() == 0) {
            model.addAttribute("msg", "用户名不存在");
            return "index";
        }
        //超过1个
        if (users.size() > 1) {
            model.addAttribute("msg", "查询错误");
            return "index";
        }

//        密码错误
        if (!password.equals(users.get(0).getPassword())) {
            model.addAttribute("msg", "密码错误");
            return "index";
        }
		//密码正确
        //将姓名添加到session域中
        session.setAttribute("loginUser",username);
        return "redirect:/main.html";
    }
}

LoginUserService接口

package cn.xiaov.service;

import cn.xiaov.domain.LoginUser;

import java.util.List;

public interface LoginUserService {
    List< LoginUser> findByUserName(String username);
}

LoginUserServiceImpl实现类

package cn.xiaov.service.impl;

import cn.xiaov.dao.LoginUserDao;
import cn.xiaov.domain.LoginUser;
import cn.xiaov.service.LoginUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class LoginUserServiceImpl implements LoginUserService {

    @Autowired
    LoginUserDao loginUserDao;

    @Override
    public List< LoginUser> findByUserName(String username) {
        return loginUserDao.findByUserName(username);
    }
}

dao层LoginUserDao

package cn.xiaov.dao;

import cn.xiaov.domain.LoginUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface LoginUserDao {

    @Select("select * from loginuser where username=#{username}")
    List< LoginUser> findByUserName(String username);

}

这样登录功能就大概的实现了。在浏览器中输入:http://localhost:8080/index.html或者http://localhost:8080,填入账号admin,密码admin,就可以登录成功,否者就会登录失败,返回用户名不存在,密码错误等等。虽然现在dashboard.html可能不好看,但是可以访问到是事实了。原因是应该springboot拦截了静态资源,后期可以取消拦截的。设置好main.html后浏览器地址就不再是http://localhost:8080/user/login 了,而是http://localhost:8080/main.html,通过http://localhost:8080/main.html同样可以访问进入的系统。

6.拦截器

但是事实并不是这样,一个系统怎么可能不用登录就可以进去呢,这明显不符合常理,所以我们在登陆前要拦截一部分请求。

在config中新建LoginHandlerInterceptor类

package cn.xiaov.config;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser==null){
            //没有登陆
            request.setAttribute("msg","没有权限");
            request.getRequestDispatcher("/login.html").forward(request,response);
            return false;
        }else{
            //成功登录
            return true;
        }
    }
}

并在MyMvcConfig中加入,设置拦截所有,并排除一部分请求

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
            .excludePathPatterns("/","/login.html","/user/login","/asserts/**");
}

在浏览器中输入:http://localhost:8080 ,输入账号admin,密码admin,可访问主页面。

7.头部导航栏和侧边栏

7.1 在后台主页显示用户名

//从session中拿出
<--更改前
 class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Company namea>
-->
<-- 更改后 -->
<a class="#">[[${session.loginUser}]]a>

7.2 实现注销功能

在html中更改请求路径

<a class="nav-link" th:href="@{/user/logout}">注销a>

在loginController中编写

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

7.3 侧边栏

在侧边栏更改部分中文即可

我这里只实现了员工管理和首页两个模块

8.提取公共模块

在templates文件夹下新建commons文件夹,再新建一个common.html文件和一个common.css。

将nav标签的东西全部提取出来,需要在原来代码使用

<div th:replace="~{commons/common::topbar}">div>

 <div th:replace="~{commons/common::sidebar}">div>

common.html


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

<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
    <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">[[${session.loginUser}]]a>
    <input class="form-control form-control-dark w-100" type="text" th:placeholder="查找" aria-label="Search">
    <ul class="navbar-nav px-3">
        <li class="nav-item text-nowrap">
            <a class="nav-link" th:href="@{/user/logout}">注销a>
        li>
    ul>
nav>


<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">
    <div class="sidebar-sticky">
        <ul class="nav flex-column">
            <li class="nav-item">
                <a class="nav-link active" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-home">
                        <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z">path>
                        <polyline points="9 22 9 12 15 12 15 22">polyline>
                    svg>
                    首页<span class="sr-only">(current)span>
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file">
                        <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z">path>
                        <polyline points="13 2 13 9 20 9">polyline>
                    svg>
                    Orders
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-shopping-cart">
                        <circle cx="9" cy="21" r="1">circle>
                        <circle cx="20" cy="21" r="1">circle>
                        <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6">path>
                    svg>
                    Products
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-users">
                        <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2">path>
                        <circle cx="9" cy="7" r="4">circle>
                        <path d="M23 21v-2a4 4 0 0 0-3-3.87">path>
                        <path d="M16 3.13a4 4 0 0 1 0 7.75">path>
                    svg>
                    员工管理
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-bar-chart-2">
                        <line x1="18" y1="20" x2="18" y2="10">line>
                        <line x1="12" y1="20" x2="12" y2="4">line>
                        <line x1="6" y1="20" x2="6" y2="14">line>
                    svg>
                    Reports
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-layers">
                        <polygon points="12 2 2 7 12 12 22 7 12 2">polygon>
                        <polyline points="2 17 12 22 22 17">polyline>
                        <polyline points="2 12 12 17 22 12">polyline>
                    svg>
                    Integrations
                a>
            li>
        ul>

        <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
            <span>Saved reportsspan>
            <a class="d-flex align-items-center text-muted"
               href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                     stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                     class="feather feather-plus-circle">
                    <circle cx="12" cy="12" r="10">circle>
                    <line x1="12" y1="8" x2="12" y2="16">line>
                    <line x1="8" y1="12" x2="16" y2="12">line>
                svg>
            a>
        h6>
        <ul class="nav flex-column mb-2">
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z">path>
                        <polyline points="14 2 14 8 20 8">polyline>
                        <line x1="16" y1="13" x2="8" y2="13">line>
                        <line x1="16" y1="17" x2="8" y2="17">line>
                        <polyline points="10 9 9 9 8 9">polyline>
                    svg>
                    Current month
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z">path>
                        <polyline points="14 2 14 8 20 8">polyline>
                        <line x1="16" y1="13" x2="8" y2="13">line>
                        <line x1="16" y1="17" x2="8" y2="17">line>
                        <polyline points="10 9 9 9 8 9">polyline>
                    svg>
                    Last quarter
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z">path>
                        <polyline points="14 2 14 8 20 8">polyline>
                        <line x1="16" y1="13" x2="8" y2="13">line>
                        <line x1="16" y1="17" x2="8" y2="17">line>
                        <polyline points="10 9 9 9 8 9">polyline>
                    svg>
                    Social engagement
                a>
            li>
            <li class="nav-item">
                <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
                    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                         stroke-linejoin="round" class="feather feather-file-text">
                        <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z">path>
                        <polyline points="14 2 14 8 20 8">polyline>
                        <line x1="16" y1="13" x2="8" y2="13">line>
                        <line x1="16" y1="17" x2="8" y2="17">line>
                        <polyline points="10 9 9 9 8 9">polyline>
                    svg>
                    Year-end sale
                a>
            li>
        ul>
    div>
nav>
html>

common.css

@-webkit-keyframes chartjs-render-animation {
    from {
        opacity: 0.99
    }
    to {
        opacity: 1
    }
}

@keyframes chartjs-render-animation {
    from {
        opacity: 0.99
    }
    to {
        opacity: 1
    }
}

.chartjs-render-monitor {
    -webkit-animation: chartjs-render-animation 0.001s;
    animation: chartjs-render-animation 0.001s;
}

在浏览器中输入:http://localhost:8080 ,输入账号admin,密码admin,仍然可访问主页面。

9.实现员工列表

新建EmployeeController类

当选中员工管理一栏的时候会查询出所有员工信息。所以在模板页面应该改动如下:

<a class="nav-link" th:href="@{/emps}">

controller收到请求后调用employeeService和departmentService,因为在employee中存放的只有department的id,所以需要在departmentService有一个findById()的方法。在这里一定是departmentService.findById(emp.getDpid());

EmployeeController

package cn.xiaov.controller;

import cn.xiaov.domain.Department;
import cn.xiaov.domain.Employee;
import cn.xiaov.service.DepartmentService;
import cn.xiaov.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class EmployeeController {
    @Autowired
    EmployeeService employeeService;

    @Autowired
    DepartmentService departmentService;

    @RequestMapping("/emps")
    public String toEmpList(Model model) {
        Map<Integer, String> dept = new HashMap<>();

        List<Employee> employees = employeeService.findAll();
        for (Employee emp :
                employees) {
            Department department = departmentService.findById(emp.getDpid());
            dept.put(department.getId(), department.getDname());
        }
        model.addAttribute("emps", employees);
        model.addAttribute("dept", dept);
        return "emp/list";
    }
}

DepartmentService接口

package cn.xiaov.service;

import cn.xiaov.domain.Department;

public interface DepartmentService {
    Department findById(Integer id);
}

DepartmentServiceImpl实现类

package cn.xiaov.service;

import cn.xiaov.domain.Department;

public interface DepartmentService {
    Department findById(Integer id);
}

EmployeeService接口

package cn.xiaov.service;

import cn.xiaov.domain.Employee;

import java.util.List;

public interface EmployeeService {
    List<Employee> findAll();
}

EmployeeServiceImpl实现类

package cn.xiaov.service.impl;

import cn.xiaov.dao.EmployeeDao;
import cn.xiaov.domain.Employee;
import cn.xiaov.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    EmployeeDao employeeDao;

    @Override
    public List<Employee> findAll() {
        return employeeDao.findAll();
    }
}

DepartmentDao接口

package cn.xiaov.dao;

import cn.xiaov.domain.Department;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface DepartmentDao {
    @Select("select * from department where id=#{id}")
    Department findById(Integer id);
}

EmployeeDao接口

package cn.xiaov.dao;

import cn.xiaov.domain.Department;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface DepartmentDao {
    @Select("select * from department where id=#{id}")
    Department findById(Integer id);
}

将会返回两个数据给前端,

model.addAttribute("emps", employees);
model.addAttribute("dept", dept);

就是emps存放查询出来的员工信息,dept存放查询出来的部门信息。

list.html



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

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Dashboard Template for Bootstraptitle>
    
    <link href="asserts/css/bootstrap.min.css" rel="stylesheet">

    
    <link href="asserts/css/dashboard.css" rel="stylesheet">

    <link th:href="@{/commons/common.css}" rel="stylesheet" type="text/css">
head>

<body>
<div th:replace="~{commons/common::topbar}">div>

<div class="container-fluid">
    <div class="row">
        <div th:replace="~{commons/common::sidebar}">div>

        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
        <h2><a class="btn btn-sm btn-success" th:href="@{/emp}">添加a>h2>
        <div class="table-responsive">
            <table class="table table-striped table-sm" id="tb">
                <thead>
                <tr>
                    <th>编号th>
                    <th>姓名th>
                    <th>性别th>
                    <th>部门th>
                    <th>操作th>
                tr>
                thead>
                <tbody>
                <tr th:each="emp:${emps}">
                    <td th:text="${emp.getId()}">td>
                    <td th:text="${emp.getEname()}">td>
                    <td th:text="${emp.getGender()==0?'':''}">td>
                    <td th:text="${dept.get(emp.getDpid())}">td>
                    <td >
                        <a class="btn btn-sm btn-primary" href="#">编辑a>
                        <a class="btn btn-sm btn-danger" href="#">删除a>
                    td>
                tr>
                tbody>
            table>
        div>
    main>
    div>
div>



<script type="text/javascript" th:src="@{/asserts/js/jquery-3.2.1.slim.min.js}">script>
<script type="text/javascript" th:src="@{/asserts/js/popper.min.js}">script>
<script type="text/javascript" th:src="@{/asserts/js/bootstrap.min.js}">script>


<script type="text/javascript" th:src="@{/asserts/js/feather.min.js}">script>
<script>
    feather.replace()
script>


<script type="text/javascript" th:src="@{/asserts/js/Chart.min.js}">script>
<script>
    var ctx = document.getElementById("myChart");
    var myChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
            datasets: [{
                data: [15339, 21345, 18483, 24003, 23489, 24092, 12034],
                lineTension: 0,
                backgroundColor: 'transparent',
                borderColor: '#007bff',
                borderWidth: 4,
                pointBackgroundColor: '#007bff'
            }]
        },
        options: {
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: false
                    }
                }]
            },
            legend: {
                display: false,
            }
        }
    });
script>
body>
html>

在浏览器中输入:http://localhost:8080 ,输入账号admin,密码admin,可访问主页面,点击员工管理可以查询到所有员工的信息。

10.数据分页

在bootstrap官网上下载bootstrap-table,并将bootstrap-table.min.js和bootstrap-table-zh-CN.min.js放入js文件夹中,将bootstrap-table.css放入css文件夹中,另外下载jquery.js放入js文件夹中。

导入上述文件到list.html文件中

<script type="text/javascript" th:src="@{/asserts/js/jquery.js}">script>
<link th:href="@{/asserts/css/bootstrap-table.css}" rel="stylesheet" type="text/css">
<script type="text/javascript" th:src="@{/asserts/js/bootstrap-table.min.js}">script>
<script type="text/javascript" th:src="@{/asserts/js/bootstrap-table-zh-CN.min.js}">script>

再加入一串js代码初始化:

<script>
    $("#tb").bootstrapTable({
        pagination: true,   //是否显示分页条
        pageSize: 5,         //默认一页显示的行数
        paginationLoop: false,   //是否开启分页条无限循环,最后一页时点击下一页是否转到第一页
        pageList: [5, 10, 20]   //选择每页显示多少行
    });
script>

在浏览器中输入:http://localhost:8080 ,输入账号admin,密码admin,点击员工管理可以查询到所有员工分页的信息。

11.实现添加功能

首先你需要一个添加数据的页面,add.html

其实可以复制list.html并且只需要更改main里面的内容即可,在网上下载一个模板添加上去就ok了

<form>
    <div class="form-group">
        <label>LastNamelabel>
        <input type="text" class="form-control" placeholder="xiaoV">
    div>
    <div class="form-group">
        <label>Emaillabel>
        <input type="email" class="form-control" placeholder="[email protected]">
    div>
    <div class="form-group">
        <label>Genderlabel><br/>
        <div class="form-check form-check-inline">
            <input class="form-check-input" type="radio" name="gender"  value="1">
            <label class="form-check-label">label>
        div>
        <div class="form-check form-check-inline">
            <input class="form-check-input" type="radio" name="gender"  value="0">
            <label class="form-check-label">label>
        div>
    div>
    <div class="form-group">
        <label>departmentlabel>
        <select class="form-control">
            <option>1option>
            <option>2option>
            <option>3option>
            <option>4option>
            <option>5option>
        select>
    div>
    <div class="form-group">
        <label>Birthlabel>
        <input type="text" class="form-control" placeholder="xiaoV">
    div>
    <button type="submit" class="btn btn-primary">添加button>
form>

去掉不用的就可以了。

在controller中编写部分代码,点击list上面的按钮来到add.html,记得查询dept,我们需要做下拉框,需要所有的部门信息。来到add.html后,开始编写前端代码。

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
    <form th:action="@{/emp/add}" method="post">
        <div class="form-group">
            <label>姓名label>
            <input type="text" th:name="ename" class="form-control" placeholder="姓名">
        div>

        <div class="form-group">
            <label>性别label><br/>
            <div class="form-check form-check-inline">
                <input class="form-check-input" type="radio" name="gender"  value="1">
                <label class="form-check-label">label>
            div>
            <div class="form-check form-check-inline">
                <input class="form-check-input" type="radio" name="gender"  value="0">
                <label class="form-check-label">label>
            div>
        div>
        <div class="form-group">
            <label>部门label>
            <select class="form-control" th:name="dpid">
                <option th:each="dept:${departments}" th:text="${dept.getDname()}" th:value="${dept.getId()}">option>
            select>
        div>

        <button type="submit" class="btn btn-primary">添加button>
    form>
main>

点击添加按钮后,提交表单。在controller中添加add方法,更改数据库。

@RequestMapping("/emp/toadd")
public String toEmpAdd(Model model) {
    List<Department> departments = departmentService.findAll();
    model.addAttribute("departments", departments);
    return "emp/add";
}

@RequestMapping("/emp/add")
public String addEmp(Employee employee) {
    employeeService.save(employee);
    return "redirect:/emps";
}

调用了Service中的方法,需要在service中添加

void save(Employee employee);
@Override
    public void save(Employee employee) {
        employeeDao.save(employee);
    }

调用了dao中的方法,需要在dao中添加

/**
 * 保存账户
 */
@Insert("insert into employee(ename,gender,dpid) values(#{ename},#{gender},#{dpid})")
void save(Employee employee);

12.实现删除功能

<a class="btn btn-sm btn-danger" th:href="@{/emp/delete/} + ${emp.id}">删除a>

首先在list.html文件里面的路径设置一下,然后编写controller

@RequestMapping("/emp/delete/{id}")
public String deleteEmp(@PathVariable("id") Integer id) {
    employeeService.delete(id);
    return "redirect:/emps";
}

调用了Service中的方法,需要在service中添加

void delete(Integer id);
@Override
public void delete(Integer id) {
    employeeDao.delete(id);
}

调用了dao中的方法,需要在dao中添加

/**
 * 删除
 * @param id
 */
@Delete("delete from employee where id=#{id}")
void delete(Integer id);

13.实现修改功能

添加一个update.html页面,可以直接复制add.html页面,修改部分代码即可。

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
    <form th:action="@{/emp/update}" method="post">
        <input th:name="id" type="hidden" th:value="${emp.getId()}">
        <div class="form-group">
            <label>姓名label>
            <input type="text" th:name="ename" class="form-control" th:value="${emp.getEname()}"/>
        div>

        <div class="form-group">
            <label>性别label><br/>
            <div class="form-check form-check-inline">
                <input class="form-check-input"  th:checked="${emp.getGender()==1}" type="radio" name="gender"  value="1">
                <label class="form-check-label" >label>
            div>
            <div class="form-check form-check-inline">
                <input class="form-check-input" th:checked="${emp.getGender()==0}" type="radio" name="gender"  value="0">
                <label class="form-check-label">label>
            div>
        div>
        <div class="form-group">
            <label>部门label>
            <select class="form-control" th:name="dpid" th:checked="${emp.getDpid()}">
                <option th:each="dept:${departments}" th:text="${dept.getDname()}" th:value="${dept.getId()}">option>
            select>
        div>

        <button type="submit" class="btn btn-primary">修改button>
    form>
main>
<a class="btn btn-sm btn-primary" th:href="@{/emp/update/}+${emp.id}">编辑a>

首先在list.html文件里面的路径设置一下,然后编写controller

 @RequestMapping("/emp/update/{id}")
    public String toUpdateEmp(@PathVariable("id") Integer id, Model model) {
        Employee employee = employeeService.findById(id);
        List<Department> departments = departmentService.findAll();
        model.addAttribute("emp", employee);
        model.addAttribute("departments", departments);
        return "emp/update";
    }


    @RequestMapping("/emp/update")
    public String updateEmp(Employee employee) {
        employeeService.update(employee);
        return "redirect:/emps";
    }

调用了Service中的方法,需要在service中添加

Employee findById(Integer id);

void update(Employee employee);
   @Override
    public void update(Employee employee) {
        employeeDao.update(employee);
    }

    @Override
    public Employee findById(Integer id) {
        return employeeDao.findById(id);
    }

调用了dao中的方法,需要在dao中添加

  /**
     * 根据id查询
     * @param id
     * @return
     */
    @Select("select * from employee where id =#{id}")
    Employee findById(Integer id);

    /**
     * 修改
     * @param employee
     */
    @Update("update employee set ename=#{ename},gender=#{gender},dpid=#{dpid} where id=#{id}")
    void update(Employee employee);

重点记得一定要在update.html中添加

<input th:name="id" type="hidden" th:value="${emp.getId()}">

不然就能查询出id,后台打印的时候也只是空值。

14.定制错误页面

我们只需要在模板目录下添加一个error文件夹,文件夹中存放我们相应的错误页面,比如404.html 或者 4xx.html 等等,SpringBoot就会帮我们自动使用了!

你可能感兴趣的:(笔记)