【Spring Boot】9.后台管理系统

目录

1.项目搭建

1.1 创建SpringBoot

1.2 导入静态资源

在这里插入图片描述

1.3 bean.User.java

package com.node.demo.bean;

import lombok.Data;

@Data
public class User {
    private String UserName;
    private String Password;

}

1.4 controller.LoginController.java

package com.node.demo.controller;

import com.node.demo.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpSession;
import javax.websocket.Session;

@Controller

public class LoginController {

    @GetMapping("/")
    public String login(){
        return "login";
    }


    @PostMapping("/login")
    public String main(User user, HttpSession session, Model model){

        if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){//如果user.getName()有长度且user.getPassword()为123456,则登陆成功
            //把登陆成功的用户保存起来
            session.setAttribute("loginUser",user);
            return "redirect:/index.html";//当如果是@PostMapping进入到index页面,刷新的话就会不断重复提交刷新表单,所以需要一个重定向搭配index页面
        }else {
            model.addAttribute("msg","账号密码错误");
            //回到登录页面
            return "login";
        }

    }

    //登陆成功重定向到main.html 重定向防止表单重复提交
    @GetMapping("/index.html")
    public String mainPage(HttpSession session,Model model){
        //是否登陆-->拦截器、过滤器
        Object loginUser= session.getAttribute("#");
        if(loginUser!=null){
            return "index.html";
        }else {
            model.addAttribute("msg","请重新登陆");
            return "login";
        }

    }

}

1.5 修改login.html

在这里插入图片描述

xmlns:th="http://www.thymeleaf.org"

在这里插入图片描述

1.6 修改index.html

在这里插入图片描述
在这里插入图片描述

1.7 测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.静态资源公共html

把静态资源每个页面都用到的html、css、JavaScript都放到一个common.html里面,这样就不用在其他html页面重复使用了

2.1导入静态资源的table资源

在这里插入图片描述
在这里插入图片描述

2.2 编写TableController

package com.node.demo.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class TableController {

    @GetMapping("/basic_table")
    public String basic_table(){
        return "table/basic_table";
    }

    @GetMapping("/dynamic_table")
    public String dynamic_table(){
        return "table/dynamic_table";
    }
    @GetMapping("/responsive_table")
    public String responsive_table(){
        return "table/responsive_table";
    }
    @GetMapping("/editable_table")
    public String editable_table(){
        return "table/editable_table";
    }
}

2.3 寻找公共资源

2.3.1 从index中找(或其他html)找到后删除

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.2 创建common.html放到里面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="commonhead">
    <meta charset="UTF-8">
    <title>所有公共模板信息</title>
    <!--common-->
    <link href="css/style.css" th:href="@{/css/style.css}" rel="stylesheet">
    <link href="css/style-responsive.css" th:href="@{/css/style-responsive.css}" rel="stylesheet">




    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="js/html5shiv.js" th:src="@{/js/html5shiv.js}"></script>
    <script src="js/respond.min.js" th:src="@{/js/respond.min.js}"></script>
    <![endif]-->
</head>
<body>

<div th:fragment="commonscript">
    <script th:src="@{/js/jquery-1.10.2.min.js}"></script>
    <script th:src="@{/js/jquery-ui-1.9.2.custom.min.js}"></script>
    <script th:src="@{/js/jquery-migrate-1.2.1.min.js}"></script>
    <script th:src="@{/js/bootstrap.min.js}"></script>
    <script th:src="@{/js/modernizr.min.js}"></script>
    <script th:src="@{/js/jquery.nicescroll.js}"></script>
    <script th:src="@{/js/scripts.js}"></script>
</div>



</body>
</html>

在这里插入图片描述

在这里插入图片描述

2.3.3 index(或其他html)引用

在这里插入图片描述
在这里插入图片描述

3.遍历数据

3.1 TableController

在这里插入图片描述

@GetMapping("/dynamic_table")
    public String dynamic_table(Model model){
        //表格内容的遍历
        List<User> users = Arrays.asList(new User("zhangsan", "123456"),
                new User("lisi", "123444"),
                new User("haha", "aaaaa"),
                new User("hehe ", "aaddd"));
        model.addAttribute("users",users);
        return "table/dynamic_table";
    }

3.2 dynamic_table.html

在这里插入图片描述

<div class="panel-body">
        <div class="adv-table">
        <table  class="display table table-bordered table-striped" id="dynamic-table">
        <thead>
        <tr>
            <th>用户名</th>
            <th>密码</th>
        </tr>
        </thead>
        <tbody>
        <tr class="gradeX" th:each="user:${users}">
            <td th:text="${user.userName}"></td>
            <td >[[${user.userName}]]</td>  <!-- 行内写法-->
        </tr>
        </tbody>

在这里插入图片描述

4.拦截器

在这里插入图片描述

4.1 LoginInterceptor.java

package com.node.demo.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/*
*   登陆拦截器
*  1.配置拦截器拦截哪些请求
* 2.把这些配置放在容器中
*  */
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //目标方法执行之前,登陆检查逻辑
        HttpSession session=request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser!=null){
            return true;
        }
        //拦截 跳到登录页
        request.setAttribute("msg","请先登陆");
        request.getRequestDispatcher("/").forward(request,response); //转发

        /*
        * 重定向与转发:
        * 转发:是服务器内部的跳转,浏览器的地址栏不会发生变化。从一个页面到另一个页面的跳转还是同一个请求,也即是只有一个请求响应。可以通过request域来传递对象。
        * 重定向:是浏览器自动发起对跳转目标的请求,浏览器的地址栏会发生变化。从一个页面到另一个页面的跳转是不同的请求,也即是有两个或两个以上的不同的请求的响应。无法通过request域来传递对象。
        * */
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

4.2 AdminWebConfig.java

package com.node.demo.config;

import com.node.demo.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 1、编写一个拦截器实现HandlerInterceptor接口
 * 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)  相当于SSM中的SpringMVC的xml配置文件
 * 3、指定拦截规则【如果是拦截所有,静态资源也会被拦截】
 */
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") //所有请求都会被拦截,包括静态资源
                .excludePathPatterns("/","/login","/css/**","/fonts/**","/images");//放行不拦截
    }
}

4.3拦截器简单理解

在这里插入图片描述

5.文件上传

5.1 导入静态资源

在这里插入图片描述
在这里插入图片描述

5.2 修改静态资源

在这里插入图片描述
在这里插入图片描述

<!--enctype="multipart/form-data":表单数据有多部分构成,既有文本数据,又有文件等二进制数据的意思
                        -->
                        <form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">
                            <div class="form-group">
                                <label for="exampleInputEmail1">邮箱</label>
                                <input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
                            </div>
                            <div class="form-group">
                                <label for="exampleInputPassword1">名字</label>
                                <input type="text"  name="username" class="form-control" id="exampleInputPassword1" >
                            </div>
                            <div class="form-group">
                                <label for="exampleInputFile">头像</label>
                                <input type="file" name="headerImg" id="exampleInputFile">

                            </div>
                            <div class="form-group">
                                <label for="exampleInputFile">生活照</label>
                                <input type="file" name="photos" multiple>

                            </div>

5.3 controller

在这里插入图片描述

package com.node.demo.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/*
* 文件上传测试
* */
@Slf4j
@Controller
public class FormTestController {

    @GetMapping("/form_layouts")
    public String form_layouts(){
        return "form/form_layouts";
    }



    @PostMapping("/upload")
    /*
        email、username、headrImg、photos对应html的表单name属性
      * @RequestPart("headrImg")MultipartFile headrImag, //自动封装上传的单文件
        @RequestPart("photos") MultipartFile[] photos//自动封装上传的多文件

      *@RequestPart:用在multipart/form-data表单提交请求的方法上(多数用于文件上传),
      * @RequestParam和@RequestPart对比,@RequestPart适用于复杂的请求域(像JSON,XML)
    * */
    public  String ipload(@RequestParam("email") String email,
                          @RequestParam("username") String username,
                          @RequestPart("headerImg")MultipartFile headerImg, //自动封装上传的单文件
                          @RequestPart("photos") MultipartFile[] photos ) throws IOException {

        log.info("上传的信息:email={},username={},headerImg={},photos={}",
                email,username,headerImg.getSize(),photos.length);

        if(!headerImg.isEmpty()){
            //保存到文件服务器,OSS服务器
            String originalFilename = headerImg.getOriginalFilename();
            headerImg.transferTo(new File("E:\\idea\\SpringBoot-后台管理系统\\src\\main\\resources\\static\\images\\upload\\"+originalFilename));
        }

        if(photos.length > 0){
            for (MultipartFile photo : photos) {
                if(!photo.isEmpty()){
                    String originalFilename = photo.getOriginalFilename();
                    photo.transferTo(new File("E:\\idea\\SpringBoot-后台管理系统\\src\\main\\resources\\static\\images\\upload\\"+originalFilename));
                }
            }
        }
            return "index";
    }
}

5.4 测试

在这里插入图片描述
在这里插入图片描述

5.5 原理

5.5.1 文件限制原理

文件上传自动配置类-MultipartAutoConfiguration-MultipartProperties
在这里插入图片描述

6. 异常处理

6.1 错误处理

官方文档:
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-error-handling
在这里插入图片描述
在这里插入图片描述

6.1.1 默认规则

  • 默认情况下,Spring Boot提供/error处理所有错误的映射
  • 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据

在这里插入图片描述

  • 要对其进行自定义,添加View解析为error
  • 要完全替换默认行为,可以实现 ErrorController 并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容。
  • error/下的4xx,5xx页面会被自动解析;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

7.数据库操作

7.1 SQL

7.1.1 数据源的自动配置-HikariDataSource

7.1.1.1 导入JDBC
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
7.1.1.2 导入驱动
<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

因为官方不知道我们接下要操作什么数据库,所以只导入了JDBC场景,驱动还是需要我们自己手动导入
在这里插入图片描述
如果需要改版本

  • 方法一:直接依赖引入具体版本(maven的就近依赖原则)
  • 方法二:重新声明版本(maven的属性的就近优先原则)
<properties>
        <java.version>1.8</java.version>
        <mysql.version>5.1.49</mysql.version>
    </properties>

在这里插入图片描述

7.1.1.2 分析JDBC自动配置

在这里插入图片描述
在这里插入图片描述
DataSourceAutoConfiguration : 数据源的自动配置

  • 底层配置好的连接池是:HikariDataSource

DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置
JdbcTemplateAutoConfiguration: JdbcTemplate的自动配置,可以来对数据库进行crud
JndiDataSourceAutoConfiguration: jndi的自动配置
XADataSourceAutoConfiguration: 分布式事务相关的

7.1.1.3 修改配置项
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_account
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
7.1.1.4 测试

在单元测试DemoApplicationTests.java中

package com.node.demo;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
@Slf4j
@SpringBootTest
class DemoApplicationTests {

    @Autowired
    JdbcTemplate jdbcTemplate;
    @Test
    void contextLoads() {
        //jdbcTemplate.queryForObject("select * from student"); //查询一个对象
        Long aLong = jdbcTemplate.queryForObject("select count(*) from student", Long.class);//查询有几条数据,封装成long
     log.info("记录总数:{}",aLong);
    }

}

7.1.2 Druid数据源

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。
官方:https://github.com/alibaba/druid
官方文档:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

整合第三方技术的两种方式
• 自定义
• 找starter

7.1.2.1 自定义方式
7.1.2.1.1 引入数据源
<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    destroy-method="close">
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="maxActive" value="20" />
    <property name="initialSize" value="1" />
    <property name="maxWait" value="60000" />
    <property name="minIdle" value="1" />
    <property name="timeBetweenEvictionRunsMillis" value="60000" />
    <property name="minEvictableIdleTimeMillis" value="300000" />
    <property name="testWhileIdle" value="true" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />
    <property name="poolPreparedStatements" value="true" />
    <property name="maxOpenPreparedStatements" value="20" />
7.1.2.1.2 创建MyDruidConfig
package com.node.demo.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.lang.reflect.Array;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;

@Configuration
public class MyDruidConfig {
    @ConfigurationProperties("spring.datasource")  //DataSource和配置文件的属性绑定
    @Bean
    public DataSource dataSource() throws SQLException {

        DruidDataSource druidDataSource=new DruidDataSource();
//        druidDataSource.setUrl();
//        druidDataSource.setUsername();
        //加入监控功能和防火墙功能
        druidDataSource.setFilters("stat,wall");
        return druidDataSource;
    }


    /*
    * 配置driod的监控功能
    * */
    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
        StatViewServlet statViewServlet=new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean=new ServletRegistrationBean<>(statViewServlet,"/druid/*");

        /*监控页面访问密码*/
        registrationBean.addInitParameter("loginUsername","admin");
        registrationBean.addInitParameter("loginPassword","123456");
        return registrationBean;
    }

    /*
    * WebStatFilter 用于采集web-jdbc关联监控的数据*/
    @Bean
    public FilterRegistrationBean webStatFFilter(){
        WebStatFilter webStatFilter = new WebStatFilter();
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>(webStatFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));//监控所有路径
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}


7.1.2.1.4 测试

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.1.2.2 引入starter方式
<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>

在这里插入图片描述

7.1.2.3 不在需要MyDruidConfig,直接配置文件里面修改
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      aop-patterns: com.atguigu.admin.*  #监控SpringBean
      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)

      stat-view-servlet:   # 配置监控页功能
        enabled: true
        login-username: admin
        login-password: admin
        resetEnable: false

      web-stat-filter:  # 监控web
        enabled: true
        urlPattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'


      filter:
        stat:    # 对上面filters里面的stat的详细配置
          slow-sql-millis: 1000
          logSlowSql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false

SpringBoot配置示例:
https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
配置项列表
https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8

7.1.3 整合MyBatis

官方文档:https://mybatis.org/mybatis-3/zh/index.html
GitHub官方:https://github.com/mybatis
GitHub官方文档:https://github.com/mybatis/spring-boot-starter/wiki/Quick-Start
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>
  • 全局配置文件
  • SqlSessionFactory: 自动配置好了
  • SqlSession:自动配置了 SqlSessionTemplate 组合了SqlSession
  • @Import(AutoConfiguredMapperScannerRegistrar.class);
  • Mapper: 只要我们写的操作MyBatis的接口标准了 @Mapper 就会被自动扫描进来
  • 在这里插入图片描述
@EnableConfigurationProperties(MybatisProperties.class)MyBatis配置项绑定类。
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration{}

@ConfigurationProperties(prefix = "mybatis")
public class MybatisProperties
7.1.3.1 方法一:配置整合

在这里插入图片描述

导入包

<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

在这里插入图片描述

7.1.3.1.1 Student
package com.node.demo.bean;

import lombok.Data;

@Data
public class Student {
    private Integer id;
    private String name;
    private String sex;
    private Integer age;
}

7.1.3.1.2 mybatis-conffig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>
7.1.3.1.3 StudentMapper
package com.node.demo.mapper;

import com.node.demo.bean.Student;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface StudentMapper {
   List<Student> queryStudentList();
    Student getStuId(int id);
    int addStu(Student student);
    int updateStu(Student student);
    int deleteStu(int id);


}

7.1.3.1.4 StudentMapper.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.node.demo.mapper.StudentMapper">

    <select id="queryStudentList" resultType="com.node.demo.bean.Student">
       select * from student
    </select>
    <select id="getStuId" resultType="com.node.demo.bean.Student">
       select * from student where id=#{id}
    </select>
    <select id="addStu" resultType="com.node.demo.bean.Student">
       insert into student (id,name,sex,age) values (#{id},#{name},#{sex},#{age})
    </select>
    <select id="updateStu" resultType="com.node.demo.bean.Student">
       update student set name=#{name},sex=#{sex} where id =#{id}
    </select>
    <select id="deleteStu" resultType="com.node.demo.bean.Student">
       delete  from student where id=#{id}
    </select>
</mapper>

7.1.3.1.5 application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      aop-patterns: com.atguigu.admin.*  #监控SpringBean
      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)

      stat-view-servlet:   # 配置监控页功能
        enabled: true
        login-username: admin
        login-password: admin
        resetEnable: false

      web-stat-filter:  # 监控web
        enabled: true
        urlPattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'


      filter:
        stat:    # 对上面filters里面的stat的详细配置
          slow-sql-millis: 1000
          logSlowSql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false
# 配置mybatis规则
mybatis:
  config-location: classpath:mybatis/mybatis-conffig.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

7.1.3.1.7 LoginController
@Controller
public class LoginController {
/* 配置整合Mybatis*/
    @Autowired
    StudentMapper studentMapper;

    @ResponseBody
    @GetMapping("/stu")
    public List<Student> queryStudentList(){
        List<Student> studentList=studentMapper.queryStudentList();
        for(Student student:studentList){
            System.out.println(student);
        }
        return studentList;
    }

}

7.1.3.1.8 测试

在这里插入图片描述

7.1.3.2 方法二:注解模式
@Mapper
public interface CityMapper {

    @Select("select * from city where id=#{id}")
    public City getById(Long id);

    public void insert(City city);

}
7.1.3.4 方法三:混合模式
7.1.3.5 最佳实战

• 引入mybatis-starter
• 配置application.yaml中,指定mapper-location位置即可
• 编写Mapper接口并标注@Mapper注解
• 简单方法直接注解方式
• 复杂方法编写mapper.xml进行绑定映射
• @MapperScan(“com.atguigu.admin.mapper”) 简化,其他的接口就可以不用标注@Mapper注解

7.1.4 整合Mybatis-Plus

Github文档:https://github.com/baomidou/mybatis-plus
官方文档:https://baomidou.com/
在这里插入图片描述
在这里插入图片描述
优点:XML跳转、生成代码、重置模板、JPA提示、生成查询
自动配置

  • MybatisPlusAutoConfiguration 配置类,MybatisPlusProperties 配置项绑定。mybatis-plus:xxx 就是对mybatis-plus的定制
  • SqlSessionFactory 自动配置好。底层是容器中默认的数据源
  • mapperLocations 自动配置好的。有默认值。classpath*:/mapper/**/*.xml;任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件,放在 mapper下
  • 容器中也自动配置好了 SqlSessionTemplate
  • @Mapper 标注的接口也会被自动扫描;建议直接 @MapperScan(“com.atguigu.admin.mapper”) 批量扫描就行
7.1.4.1 数据库

在这里插入图片描述

create schema mybatisplus

use mybatisplus

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
7.1.4.1 导入包
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
7.1.4.2 主程序

在这里插入图片描述

7.1.4.3 User
package com.node.demo.bean;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
//@TableName("user_tb1") 你的类名是User,会自动配置你数据库表的user表,如果user表改成了user_tb1,则需要这个注解
public class User {
    /*
    * 所有属性都应该在数据库中*/
    @TableField(exist = false)
    private String UserName;
    @TableField(exist = false)//表示不在数据库中
    private String Password;

    private Integer id;
    private String name;
    private Integer age;
    private String email;
}

7.1.4.4 UserMapper

在这里插入图片描述

package com.node.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.node.demo.bean.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseMapper<User> {

}

在这里插入图片描述

7.1.4.5 DemoApplicationTests
package com.node.demo;

import com.node.demo.bean.User;
import com.node.demo.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


@Slf4j
@SpringBootTest
class DemoApplicationTests {

    
    @Autowired
    UserMapper userMapper;
    
   
    @Test
    void testUserMapper(){
        User user=userMapper.selectById(1L);
        log.info("用户信息:{}",user);
    }

}

7.1.4.6 测试

在这里插入图片描述

7.1.5 整合Mybatis-Plus-CRUD

一般操作:需要操作查询,先调用Service(接口)的一个方法,在去ServiceImpl实现这个方法,ServiceImpl再调用Mapper里面的方法操作数据库

7.1.5.6 数据列表展示

在这里插入图片描述

7.1.5.6.1 UserMapper
package com.node.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.node.demo.bean.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseMapper<User> {

}
7.1.5.6.2 UserService
package com.node.demo.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.node.demo.bean.User;

public interface UserService extends IService<User> {
}

在这里插入图片描述
IService:是所有Service的总接口(顶级),不在需要注解写方法。:要查询的数据

7.1.5.6.3 UserServiceImpl
package com.node.demo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.node.demo.bean.User;
import com.node.demo.mapper.UserMapper;
import com.node.demo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
}

在这里插入图片描述
ServiceImpl<UserMapper, User>:Service的顶级

7.1.5.6.4 TableController
package com.node.demo.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.node.demo.bean.User;
import com.node.demo.service.UserService;
import com.node.demo.service.impl.UserServiceImpl;
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.RequestParam;

import java.util.Arrays;
import java.util.List;

@Controller
public class TableController {

    @GetMapping("/basic_table")
    public String basic_table(){
        return "table/basic_table";
    }

    @Autowired
    UserServiceImpl userService;
    @GetMapping("/dynamic_table")
    public String dynamic_table(@RequestParam(value = "pn",defaultValue = "1")Integer pn, Model model){
        /*//表格内容的遍历
        List<User> users = Arrays.asList(new User("zhangsan", "123456"),
                new User("lisi", "123444"),
                new User("haha", "aaaaa"),
                new User("hehe ", "aaddd"));
        model.addAttribute("users",users);*/
        List<User> list= userService.list();
        model.addAttribute("users",list);
        
        return "table/dynamic_table";
    }
    @GetMapping("/responsive_table")
    public String responsive_table(){
        return "table/responsive_table";
    }
    @GetMapping("/editable_table")
    public String editable_table(){
        return "table/editable_table";
    }
}

7.1.5.6.5 静态资源

在这里插入图片描述

7.1.5.6.6 测试

在这里插入图片描述

7.1.5.7 分页

在这里插入图片描述
在这里插入图片描述

7.1.5.7.1 MybatisConfig(配置分页插件)
package com.node.demo.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisConfig {
    /*
    * 分页插件
    * */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        PaginationInnerInterceptor paginationInnerInterceptor=new PaginationInnerInterceptor();
        paginationInnerInterceptor.setOverflow(true);
        paginationInnerInterceptor.setMaxLimit(500L);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }
}

7.1.5.7.2 TableController
package com.node.demo.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.node.demo.bean.User;
import com.node.demo.service.UserService;
import com.node.demo.service.impl.UserServiceImpl;
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.RequestParam;

import java.util.Arrays;
import java.util.List;

@Controller
public class TableController {

    @GetMapping("/basic_table")
    public String basic_table(){
        return "table/basic_table";
    }

    @Autowired
    UserServiceImpl userService;
    @GetMapping("/dynamic_table")
    public String dynamic_table(@RequestParam(value = "pn",defaultValue = "1")Integer pn, Model model){

        //表格内容的遍历-->有分页
        //分页查询数据
        Page<User> userPage=new Page<>(pn,2);
        //分页查询结果
        Page<User> page = userService.page(userPage, null);//第二个:queryWrapper-->查询对象
        long current = page.getCurrent();//当前页
        long pages = page.getPages();//总页数
        long total = page.getTotal();//总记录数
        List<User> records=page.getRecords();  //获取所有数据
        model.addAttribute("page",page);
        return "table/dynamic_table";

    }
    @GetMapping("/responsive_table")
    public String responsive_table(){
        return "table/responsive_table";
    }
    @GetMapping("/editable_table")
    public String editable_table(){
        return "table/editable_table";
    }
}

7.1.5.7.3 修改静态资源

在这里插入图片描述

<tr>
                                        <th>用户ID</th>
                                        <th>用户名</th>
                                        <th>年龄</th>
                                        <th>邮箱</th>
                                        
                                    </tr>
                                    </thead>
                                    <tbody>
                                    <tr class="gradeX" th:each="user:${page.records}">
                                        <td th:text="${user.id}"></td>
                                        <td>[[${user.name}]]</td>  <!-- 行内写法-->
                                        <td th:text="${user.age}"></td>
                                        <td th:text="${user.email}"></td>
                                       

                                    </tr>
                                    </tbody>


<div class="dataTables_info" id="editable-sample_info">当前第[[${page.current}]]页
                                            总计[[${page.pages}]]页 共[[${page.total}]]条记录
                                        </div>






<ul>
                                                <li class="prev disabled"><a th:href="@{/dynamic_table(pn=${page.current}-1)}">← 前一页</a></li>
                                                <li th:class="${num==page.current?'active':''}" th:each="num:${#numbers.sequence(1,page.pages)}">
                                                    <!--th:each="num:${#numbers.sequence(1,page.pages)}:遍历出,第一页到总计页数-->
                                                    <a th:href="@{/dynamic_table(pn=${num})}">[[${num}]]</a>
                                                </li>
                                                <li class="prev disabled"><a th:href="@{/dynamic_table(pn=${page.current}+1)}">下一页 → </a></li>
                                            </ul>

7.1.5.7.4 测试

在这里插入图片描述

7.1.5.8 删除
7.1.5.8.1 dynamic_table.html

在这里插入图片描述

<tr>
                                        <th>用户ID</th>
                                        <th>用户名</th>
                                        <th>年龄</th>
                                        <th>邮箱</th>
                                        <th>操作</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    <tr class="gradeX" th:each="user:${page.records}">
                                        <td th:text="${user.id}"></td>
                                        <td>[[${user.name}]]</td>  <!-- 行内写法-->
                                        <td th:text="${user.age}"></td>
                                        <td th:text="${user.email}"></td>
                                        <td>
                                            <a th:href="@{/user/delete/{id}(id=${user.id},pn=${page.current})}"
                                               class="btn btn-danger btn-sm" type="button">删除</a>
                                        </td>

                                    </tr>
7.1.5.8.2 TableController
/*删除*/
    @GetMapping("/user/delete/{id}")
    public String deleteUser(@PathVariable("id")Long id,
                             @RequestParam(value = "pn",defaultValue = "1")Integer pn,
                             RedirectAttributes ra){
        //RedirectAttributes ra:代表着保持当删除当前这页的id时,把当前页pn存起来,再到html里面 @${里面的地址}保持当前页面
        userService.removeById(id);
        ra.addAttribute("pn",pn);
        return "redirect:/dynamic_table";
    }
7.1.5.8.9 测试

删除前
在这里插入图片描述
删除后
在这里插入图片描述

7.2 NoSQL

7.2.1 Redis

官方:http://www.redis.cn/
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值