SpringBoot学习笔记

SpringBoot入门与基本实现

技术:springboot+html页面+thymeleaf模板引擎+ajax框架+restful风格+slf4j日志+logback

一、整理

1、开发思路和技术实现

SpringBoot学习笔记_第1张图片

2、创建SpringBoot项目的方式

  1. 官网的初始化页面创建下载
  2. alibaba的初始化页面创建下载
  3. 直接使用Idea或sts创建
    创建project 选择 spring initializr jdk1.8 并选择阿里云模板下载好点
    SpringBoot学习笔记_第2张图片后面右上角选择springboot版本(2.1.x稳定点)

创建完之后,管理POM文件下载依赖

3、SpringBoot基本使用

  • 引入jdbc
    下文的mybatis包的引入中,里面已经包含了jdbc,所有不需要再加依赖了
  • 常用注解 yaml语法
    用application.properties也行,application.yaml也行,这里用yaml。
    yaml中可以给类中的变量赋值
    SpringBoot学习笔记_第3张图片SpringBoot学习笔记_第4张图片

下面是初始配置yaml要写的东西

spring:
 application:
  name: springboot
#数据库配置
#必须把username前面的data-去掉
 datasource:
   username: root
   password: 123456
   url: jdbc:mysql://localhost:3306/hotelbookidea?useUnicode=true&characterEncoding=utf8
   driver-class-name: com.mysql.jdbc.Driver
server:
 port: 8888
fa:
 id1: 100
 name1: 发啊发
 bj1: 17
mybatis:
 mapper-locations: classpath:mapper/*.xml
 config-location: classpath:mybatis-config.xml
 type-aliases-package: com.lingnan.entity
logging:
 level:
   com.lingnan.dao: debug
 config: classpath:log/logback-spring.xml
  • 引入mybatis
    pom依赖,这里用的是mysql5.1.47
       
       <dependency>
           <groupId>mysqlgroupId>
           <artifactId>mysql-connector-javaartifactId>
           <version>${mysql.version}version>
       dependency>
       <dependency>
           <groupId>org.mybatis.spring.bootgroupId>
           <artifactId>mybatis-spring-boot-starterartifactId>
           <version>1.3.2version>
       dependency>
  • 引入mybatis plus实现分页
    pom依赖
        
       
       <dependency>
           <groupId>com.baomidougroupId>
           <artifactId>mybatis-plusartifactId>
           <version>3.0.7.1version>
       dependency>

还需要建一个plus配置类

@Configuration
public class MyBatisPlusConfig {
   @Bean
   public PaginationInterceptor paginationInterceptor(){
       PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
       return  paginationInterceptor;
   }
}
  • 使用Java类+注解实现配置文件效果
    html使用thymeleaf模板引擎,使得效果与jsp差不多
    pom依赖
       
       <dependency>
           <groupId>org.springframework.bootgroupId>
           <artifactId>spring-boot-starter-thymeleafartifactId>
       dependency>
  • 实现增删改查功能
    使用idea的easycode插件,右边数据表右键一键创建mapper,controller,dao,service,serviceImpl,xml。具体功能再增加。下面是用户管理的controller
package com.lingnan.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lingnan.common.CommonReslut;
import com.lingnan.entity.Admin;
import com.lingnan.entity.Course;
import com.lingnan.excelUtils.ExcelForList;
import com.lingnan.service.AdminService;
import com.lingnan.service.CourseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
* (Admin)表控制层
*
* @author makejava
* @since 2020-05-26 19:14:25
*/
@Controller
@RequestMapping("admin")
public class AdminController {
   /**
    * 加入日志的使用,减少使用sout打印debug
    */
   private Logger logger=LoggerFactory.getLogger(getClass());
   /**
    * 服务对象
    */
   @Resource
   private AdminService adminService;

   @Autowired
   private CourseService courseService;

   //admin页面的查询所有功能
   @PostMapping("queryAll")
   @ResponseBody
   public Object queryAll(Integer page,Integer limit,Admin admin){
       CommonReslut<Admin> result=new CommonReslut<>();
       IPage<Admin> iPage =adminService.queryAllByLimit(page,limit,admin);
       result.setCode(0);
//        System.out.println("iPage.getTotal():::"+iPage.getTotal());
       result.setCount(iPage.getTotal());
       result.setData(iPage.getRecords());
       return result;
   }
   //登录界面
   @RequestMapping("tologin")
   public String tologin(){
       return  "login";
   }

   //首页
   @RequestMapping("towelcome")
   public String towelcome(){
       return  "welcome";
   }

   @GetMapping("selectOne")
   public Admin selectOne(Integer id) {
       return this.adminService.queryById(id);
   }

   //管理查询界面
   @RequestMapping("tolist")
   public String tolist() {
       return "/user/table";
   }
   //管理添加界面
   @RequestMapping("toadd")
   public String toadd(Model model) {
       model.addAttribute("admin",new Admin());
       return "/user/admin_add";
   }
     //管理添加保存功能
   @PostMapping("save")
   @ResponseBody
   public Object save(Admin admin) {
       boolean result=false;

       if(admin.getId()!=null){
           //编辑
           result =adminService.update(admin)>0;
       }else{
           //添加
           result=adminService.insert(admin).getId()!=null;
       }


       return result;
   }
     //管理更新功能
   @RequestMapping("toedit")
   public String toedit(int id,Model model) {

       System.out.println("id:::"+id);
       Admin admin=adminService.queryById(id);
       model.addAttribute("admin",admin);

       return "user/admin_add";
   }
     //管理删除功能
   @PostMapping("delete")
   @ResponseBody
   public boolean delete(Integer[] ids) {

       if(ids==null ||ids.length==0)
           return false;
//        System.out.println(ids[0]);
//        return true;

       return adminService.deleteById(Arrays.asList(ids));
   }


   //上传
   @PostMapping(value="upload")
   @ResponseBody
   public  Object imporCourse(MultipartFile file, HttpSession httpSession) throws IOException {
       CommonReslut<String> result = new CommonReslut<>();
       InputStream in = file.getInputStream();
       String fileOriginalName = file.getOriginalFilename();
       String fileName = file.getName();
       String excelType = fileOriginalName.substring(fileOriginalName.indexOf(".") + 1);

       //记录插入多条记录到了数据库;
       int importSuccessNum = 0;
       int importAllNum = 0;
       boolean importSuccess;

       System.out.println("in:::" + in);
       System.out.println("fileOriginalName:::" + fileOriginalName);
       System.out.println("fileName:::" + fileName);
       System.out.println("excelType:::" + excelType);
       List<Object> forlist = ExcelForList.ExcelForList(file, Course.class, true, excelType);
       for (Object object : forlist) {
           Course course = (Course) object;
           importAllNum++;
           importSuccess = courseService.importExcel(course);
           if (importSuccess)
               importSuccessNum++;

       }
       httpSession.setAttribute("importAllNum", importAllNum);
       httpSession.setAttribute("importSuccessNum", importSuccessNum);

       if (importSuccessNum <= 0)
           result.setMsg("上传excel文件出错!");
//            return "success!"+"应处理"+importAllNum+"条,已成功处理"+importSuccessNum+"条!";

       result.setData(file.getOriginalFilename());
       return result;

   }
   //登录功能验证
   @GetMapping("login")
   public String login(String account, String password, String captcha, Model model,HttpServletResponse response) {
//        Cookie account_cookie = new Cookie("account", account);
//        Cookie password_cookie = new Cookie("password", password);
//        httpSession.setAttribute("account",account);
//        httpSession.setAttribute("password",password);
       // 输出到客户端
//        response.addCookie(account_cookie);
//        response.addCookie(password_cookie);

       logger.info(account);
       logger.info(password);
       logger.info("Start to verify acount [{}]",account);
       logger.info("Start to verify password [{}]",password);
       logger.trace("最低级别");
       logger.debug("第二");
       logger.info("第三");
       logger.warn("第四");
       logger.error("第五");

       // 新建Cookie
       Cookie account_cookie = new Cookie("account", account);
       Cookie password_cookie = new Cookie("password", password);
       // 输出到客户端
       response.addCookie(account_cookie);
       response.addCookie(password_cookie);
       model.addAttribute("account",account);
       if(this.adminService.login(account,password)!=null&&captcha.equals("xszg"))
           return "index";
       return "OK";
   }

   @RequestMapping(value = "checkCookie")
   public String checkCookie(String account, String password, HttpServletResponse response){
       // 新建Cookie
       Cookie account_cookie = new Cookie("account", account);
       Cookie password_cookie = new Cookie("password", password);
       // 输出到客户端
       response.addCookie(account_cookie);
       response.addCookie(password_cookie);
       return "redirect:tologin";
   }

//    @RequestMapping(value = "getCookie")
//    public String getCookie(@CookieValue("account") String account, @CookieValue("password") String password){
//        // 控制台输出
//        System.out.println("account: " + account);
//        System.out.println("password: " + password);
//        return "OK";
//    }

}
  • 引入日志管理,使用slf4j+logback

4、引入layui

  • 下载layui模板,是一个git项目

  • GitHub发版地址:https://github.com/zhongshaofa/layuimini/releases
    Gitee发版地址:https://gitee.com/zhongshaofa/layuimini/releases

  • SpringBoot所有资源文件(包括js、css、图片、配置文件)都在resources目录

  • 将模板中静态资源放在static目录下,表示该资源都必须使用/开头去引入

  • 将html页面放在templates目录下,并且引入thymeleaf的依赖
    SpringBoot学习笔记_第5张图片SpringBoot学习笔记_第6张图片

5、thymeleaf基本语法

去官网学习 https://www.thymeleaf.org/

  • 引入,表头。目的只是方便提示
<html  xmlns:th="http://www.thymeleaf.org">
  • 引入静态资源:@{/资源路径}。
  • 行内表达式:[[$ {变量名}]]、[[${对象名.属性名}]] 在js中可以直接调用。
    例子:
<script>
  var user ="[[${session.loginUser.getName()}]]";
   var h1=document.getElementById("welcome");
   h1.innerText="欢迎您"+user+",正在预订";
script>
  • 在标签中的话:
  • 1.该标签的属性必须th:属性名
  • 2. 变 量 名 或 {变量名}或 {对象名.属性名}
  • 表单:th:object与*{}的配合使用
    后端controller中需要加入model.addattribute("(dto对象)admin"),admin),前端使用时候,表单form 可以加th:admin,然后里面的框的value加 * {(属性)name }。或者form那里不加th:admin,里面框直接admin.name.
  • 创建并引入公共部分:~{}
  • 实现ifelse swich,还有src拼接后端传来的值操作:
  •   <div th:if="${session.room.image}">
         <img id="images" width="220px" height="110px"  alt="" 
         th:src="@{/images/{image}(image=${session.room.image})}" 
         class="property_img">
        </div> 
    
    
    
    

6、layui基本使用 必须引入layui.js和jquery

  • layui.use加载组件,比如表单(form)、表格(table)、上传(upload)、层(layer) 菜单管理查询实现
  • 表单组件:提交、验证、常用的复选框或单选按钮监听。结合jquery的ajax来完成
  • 表格:加载表格、按钮事件监听、表格刷新、表格条件搜索、表格分页显示 上传:配置一下就行了,非常简单
  • 层:打开添加或编辑页面、提示信息、页面关闭的同时刷新表格即end回调

二、SpringBoot日志引入

为什么要接入日志

  • 开发阶段使用system.out.println() 上线之后,上面的打印一样可以运行。
  • 日志过多,很容易被覆盖
  • 保存到文件之中。不可能只保存在一个文件中,应该以日期为文件名称保存
  • 开发一个日志框架。异常发短信通知,慢查询

日志发展过程

SpringBoot学习笔记_第7张图片SpringBoot学习笔记_第8张图片

slf4j是springBoot默认的方式,每次运行出现的日志就是

实现日志接入有两种:

  • 配置文件中设置(下面有)。
  • 使用logback-spring.xml,放置resource下,在xml中设置。

1.回顾之前的日志打印配置

SpringBoot学习笔记_第9张图片

2.将日志放在指定位置

SpringBoot学习笔记_第10张图片可以运行项目可以看到有日志出现
SpringBoot学习笔记_第11张图片

3.使用slf4j和logback

slf4j
这里是在controller中加入这段
SpringBoot学习笔记_第12张图片具体控制层中写
SpringBoot学习笔记_第13张图片查看日志就会出现
在这里插入图片描述logback

  • 前面配置文件中file: app.log 这句可以先注释掉。
  • 将logback-spring.xml放在resource文件下,不能改名
  • logback-spring.xml网上找下来的,已经有人做好的,不需要自己写,拿下来只需要改改路径

在这里插入图片描述
写好日志路径和项目名称,路径是从电脑系统的根目录开始
SpringBoot学习笔记_第14张图片我使用的是mybatis,下面我设置的跟配置文件方法一样,写好扫描的dao层。
SpringBoot学习笔记_第15张图片下面是运行项目的日志
SpringBoot学习笔记_第16张图片如果想要将logback-spring.xml放在resource下的其他文件内
就需要再配置文件application.yaml中的logging增加config路径
SpringBoot学习笔记_第17张图片SpringBoot学习笔记_第18张图片

三、Restful风格api

1.restful风格实例之——管理员界面
SpringBoot学习笔记_第19张图片2、相关注解
@PathVariable:获取uri中的值

3、如何以PUT和DELETE发送请求

一定要在页面加上隐藏按钮的这句话

<form>
    <input type="hidden" name="_method" value="put或delete">
 </form>

四、thymeleaf公共部分提取

在resource下创建一个空html,增加thymeleaf语法后将一个页面的所有特效引入,即剪切过来,那个页面用一行命令即可。


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="css">
    <meta charset="utf-8">
    <meta name="keywords" content="layuimini,layui,layui模板,layui后台,后台模板,admin,admin模板,layui mini">
    <meta name="description" content="layuimini基于layui的轻量级前端后台管理框架,最简洁、易用的后台框架模板,面向所有层次的前后端程序,只需提供一个接口就直接初始化整个框架,无需复杂操作。">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta http-equiv="Access-Control-Allow-Origin" content="*">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <link rel="icon" th:href="@{/images/favicon.ico}">
    <link rel="stylesheet" th:href="@{/layui-v2.5.5/css/layui.css}" media="all">
    <link rel="stylesheet" th:href="@{/css/layuimini.css?v=2.0.4.2}" media="all">
    <link rel="stylesheet" th:href="@{/css/themes/default.css}" media="all">
    <link rel="stylesheet" th:href="@{/font-awesome-4.7.0/css/font-awesome.min.css}" media="all">

div>
<div th:fragment="js">
    
    <script th:src="@{/layui-v2.5.5/layui.js}" charset="utf-8">script>
    <script th:src="@{/js/lay-config.js?v=2.0.0}" charset="utf-8">script>
div>
body>
html>

在index页面中就可以这样应用


<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>后台管理系统title>
    <div th:include="common::css">div>
    <style id="layuimini-bg-color">
    style>
head>
<body>



<div th:include="common::js">div>
body>

这样引用公共模块就更为简洁

  • th:insert 最简单:它将简单地将指定的片段作为其host标签的主体插入。
  • th:replace 实际上将其主机标签替换为指定的片段。
  • th:include 与相似 th:insert ,但不插入片段,而是仅插入该片段的内容

五、使用Basedao缩减代码

传送门

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