SpringBoot笔记5-整合数据库和MyBatis分页/MyBatis-plus分页

Spring Boot 的数据访问:

一、Spring Boot整合JdbcTemplatedbc:

Spring对数据库的操作在jdbc上面做了更深层次的封装,而JdbcTemplate便是Spring提供的一个操作数据库的便捷工具。我们可以借助JdbcTemplate来执行所有数据库操作,例如插入,更新,删除和从数据库中检索数据,并且有效避免直接使用jdbc带来的繁琐编码。

当然,在大部分情况下,我们都会直接使用更加强大的持久化框架来访问数据库,比如MyBatis、Hibernate或者Spring Data JPA,我们这里讲解JdbcTemplate的整合,只是告诉大家有这么一种操作数据库的方式。
在这里插入图片描述

导入数据源的场景和数据库驱动:要使用JdbcTemplatedbc则导入这两个依赖配合使用

 <!--数据库的场景-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <!--数据库驱动,我们自己使用的数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

springboot默认自动进行了mysql版本仲裁:
<mysql.version>8.0.23</mysql.version>
但是不一定和我们本机的mysql版本对应:这时候我们要保持版本一致。
在这里插入图片描述

解决方法一:

在这里插入图片描述
方法二:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
添加相关yml配置:

1.yml中添加数据源配置:
在application.yml中 ,添加MySQL数据源的连接信息。
2.配置数据库的必要参数值:

在这里插入图片描述
说明:yml中的jdbc.template.下的query-timeout可以不用配置(建议不配置此项);

在这里插入图片描述

在这里插入图片描述

测试:
在这里插入图片描述
代码演示:

package com.fan.redis;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootTest
class SpringbootRedisApplicationTests {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    void testjdbcTemplate(){
        Integer integer = jdbcTemplate.queryForObject("select  count(*) from user ", Integer.class);
        System.out.println("查出的记录数:"+integer);
    }
}

效果:查出的记录数:7

二、使用德鲁伊数据源(旧方式,不推荐):

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
监控页:
在这里插入图片描述

测试:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

加入监控功能:在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

开启防火墙;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

配置登录名字:

在这里插入图片描述

在这里插入图片描述

刷新:

在这里插入图片描述

可以先登录后台管理,然后路径改成sql,这样就有了session的信息了。

在这里插入图片描述

三、更简洁的使用数据源(德鲁伊数据源starter整合方式):

Druid连接池的介绍:

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。
在这里插入图片描述

在这里插入图片描述

springboot中使用Druid :

1.引入Druid Spring Boot Starter:

Druid Spring Boot Starter 用于帮助你在Spring Boot项目中轻松集成Druid数据库连接池和监控。

在这里插入图片描述

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>
2.添加配置:
spring.datasource.url= 
spring.datasource.username=
spring.datasource.password=
# ...其他配置(可选,不是必须的,使用内嵌数据库的话上述三项也可省略不填,使用druid的话不能省略)

2.配置属性:

Druid Spring Boot Starter 配置属性的名称完全遵照 Druid,你可以通过 Spring Boot 配置文件来配置Druid数据库连接池和监控,如果没有配置则使用默认值。

JDBC 配置

spring.datasource.druid.url= # 或spring.datasource.url= 
spring.datasource.druid.username= # 或spring.datasource.username=
spring.datasource.druid.password= # 或spring.datasource.password=
spring.datasource.druid.driver-class-name= #或 spring.datasource.driver-class-name=

连接池配置:

spring.datasource.druid.initial-size=
spring.datasource.druid.max-active=
spring.datasource.druid.min-idle=
spring.datasource.druid.max-wait=
spring.datasource.druid.pool-prepared-statements=
spring.datasource.druid.max-pool-prepared-statement-per-connection-size= 
spring.datasource.druid.max-open-prepared-statements= #和上面的等价
spring.datasource.druid.validation-query=
spring.datasource.druid.validation-query-timeout=
spring.datasource.druid.test-on-borrow=
spring.datasource.druid.test-on-return=
spring.datasource.druid.test-while-idle=
spring.datasource.druid.time-between-eviction-runs-millis=
spring.datasource.druid.min-evictable-idle-time-millis=
spring.datasource.druid.max-evictable-idle-time-millis=
spring.datasource.druid.filters= #配置多个英文逗号分隔
....//more

监控配置:

# WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
spring.datasource.druid.web-stat-filter.enabled= #是否启用StatFilter默认值false
spring.datasource.druid.web-stat-filter.url-pattern=
spring.datasource.druid.web-stat-filter.exclusions=
spring.datasource.druid.web-stat-filter.session-stat-enable=
spring.datasource.druid.web-stat-filter.session-stat-max-count=
spring.datasource.druid.web-stat-filter.principal-session-name=
spring.datasource.druid.web-stat-filter.principal-cookie-name=
spring.datasource.druid.web-stat-filter.profile-enable=

# StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
spring.datasource.druid.stat-view-servlet.enabled= #是否启用StatViewServlet(监控页面)默认值为false(考虑到安全问题默认并未启动,如需启用建议设置密码或白名单以保障安全)
spring.datasource.druid.stat-view-servlet.url-pattern=
spring.datasource.druid.stat-view-servlet.reset-enable=
spring.datasource.druid.stat-view-servlet.login-username=
spring.datasource.druid.stat-view-servlet.login-password=
spring.datasource.druid.stat-view-servlet.allow=
spring.datasource.druid.stat-view-servlet.deny=

# Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置
spring.datasource.druid.aop-patterns= # Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔

Druid Spring Boot Starter 不仅限于对以上配置属性提供支持,DruidDataSource 内提供setter方法的可配置属性都将被支持。你可以参考WIKI文档或通过IDE输入提示来进行配置。配置文件的格式你可以选择.properties或.yml,效果是一样的,在配置较多的情况下推荐使用.yml。

分析自动配置

在这里插入图片描述

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

在这里插入图片描述
找此类:DruidDataSourceAutoConfigure
在这里插入图片描述

在这里插入图片描述

springboot配置文件中数据源的各项配置:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    password: root
    username: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    #type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
    druid:
      aop-patterns: com.fan.admin.*  #监控springbean
      filters: stat,wall  #底层开启功能,stat(sql监控),wall(防火墙)

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

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

      filter: #对上面filter里面的stat的详细配置,防火墙的配置
        stat:
          slow-sql-millis: 1000
          log-slow-sql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false
  jdbc:
    template:
      query-timeout: 3


在这里插入图片描述
代码演示,数据层使用mybatis,结合thymleaf进行测试

JDBC依赖必须要?
总结:无论springboot整合mybatis框架,还是springboot整合web资源,都不用添加jdbc依赖。

1.maven依赖:

<dependencies>
        <!--数据源的三个依赖,mysql,jdbc,mybatis,暂时没写连接池druid-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--jdbc依赖此处没必要了-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <!--引入mybatis生成器-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.0</version>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.22</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

2.然后配置application.yal:

spring:
  #jdbc配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/test?allowMultiQueries=true&useSSL=false&serverTimezone=UTC

  #开启restful风格支持
  mvc:
    hiddenmethod:
      filter:
        enabled: true

#mybatis基本配置
mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml

3.写一个简单的HelloController进行测试:

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model){
        model.addAttribute("msg","thymleaf,你好");
        return "hello";
    }
}

4.templates下的hello.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>成功页面</h1>
<label th:text="${msg}"></label>
</body>
</html>

测试结果:
在这里插入图片描述
然后我们测试mybatis:

1.然后我们使用逆向工程的工具:generatorConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--导入属性配置-->
    <!--<properties resource="db.properties"></properties>-->
    <!--指定特定数据库的jdbc驱动jar包的位置-->
    <!--<classPathEntry location="${jdbc.driverLocation}"/>-->
<!--MyBatis3Simple:生成简单的curd,MyBatis3:豪华版的-->
    <context id="MySql" targetRuntime="MyBatis3">

        <!-- optional(可选的),旨在创建class时,对注释进行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--jdbc的数据库连接 -->
        <jdbcConnection
                driverClass="com.mysql.cj.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/test?allowMultiQueries=true&amp;serverTimezone=UTC"
                userId="root"
                password="root">
        </jdbcConnection>


        <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>


        <!-- Model模型生成器(指定生成javabean的位置),用来生成含有主键key的类,记录类 以及查询Example类
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在该项目下所在的路径
        -->
        <javaModelGenerator targetPackage="com.fan.domain"
                            targetProject="src/main/java">

            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否对model添加 构造函数 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>

        <!--Mapper映射文件生成所在的目录, 为每一个数据库的表生成对应的SqlMap文件 -->
        <sqlMapGenerator targetPackage="mybatis.mapper"
                         targetProject="src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
                type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
                type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
                type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
                生成Dao接口的包名和位置:javaClientGenerator
        -->
        <javaClientGenerator targetPackage="com.fan.mapper"
                             targetProject="src/main/java" type="XMLMAPPER">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!--tableName:指定了表名
            domainObjectName:指定了实体类的名称
            enableCountByExample等指定了开启复杂查询等语句
        -->
        <table tableName="loginuser" domainObjectName="LoginUser"

               enableCountByExample="true" enableUpdateByExample="true"
               enableDeleteByExample="true" enableSelectByExample="true"
               selectByExampleQueryId="true">
        </table>
        <!--<table tableName="dept" domainObjectName="Dept"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>-->

    </context>
</generatorConfiguration>

2.然后在maven的plugins中找到mybatis-generator工具,并运行,注意要先在数据库中创建好表且不要用user名字的表(存在冲突,遇到过这个坑),和不能在多个数据库中有相同的表名(遇到过这个坑)。

3.然后我们就可以在测试类中测试:

@SpringBootTest
class SpringbootAdminweb01ApplicationTests {

    @Resource
    LoginUserMapper loginUserMapper;

    @Test
    void contextLoads() {
        int x = loginUserMapper.insert(new LoginUser(null, "fandongdong", "123"));
        System.out.println(x);
    }
}

正常情况下会测试成功的。这样想让我们的数据库跑起来。

参照官方文档:
https://github.com/alibaba/druid

https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

四、Springboot整合mybatis:

第一步:引入相应的场景启动器:

        <!--第三方的mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

第二步:配置:

在这里插入图片描述

注意我们把mybatis全局配置文件编写完后,一定要将全局配置文件的位置告诉springboot的总配置文件application.yml

通过mybatis.config-location: (全局配置文件的位置)
通过此配置mybatis.mapper.location:(sql映射文件的位置)
mapper接口的位置通过@MapperScan(“com.fan.mapper”)来告知springboot;

注意我们也可以这样设置,不需要mybatis-config.xml文件,和此配置:config-location: classpath:mybatis-config.xml

然后mybatis的全局配置文件中什么也不用写:
在这里插入图片描述

在这里插入图片描述

扫描映射器

无需一一注册所有映射器。相反,您可以让MyBatis-Spring扫描它们的类路径。

有三种不同的方法可以做到这一点:

使用mybatis:scan元素。
使用注释 @MapperScan(推荐使用)
使用经典的Spring xml文件并注册 MapperScannerConfigurer
双方mybatis:scan/并@MapperScan在MyBatis的spring1.2.0引入的功能。@MapperScan需要Spring 3.1或更高版本。

从2.0.2开始,映射器扫描功能支持选项(lazy-initialization),该选项控制启用/禁用映射器bean的延迟初始化。添加该选项的动机是支持Spring Boot 2.2支持的惰性初始化控制功能。此选项的默认值为false(=不使用延迟初始化)。如果开发人员想要对映射器bean使用延迟初始化,则应将其设置为trueexpress。

重要的如果使用延迟初始化功能,则开发人员需要了解以下限制。如果满足以下任一条件,则通常无法在应用程序上使用延迟初始化功能。

当使用()和()引用其他映射器的语句时@One@Many
当包括对的片段其他映射器使用
当使用()引用其他映射器的缓存时@CacheNamespaceRef
当使用()引用其他映射器的结果映射时@ResultMap

在这里插入图片描述
UserMapper.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.fan.admin.mapper.UserMapper">
    <!--public User getUser(Integer id);-->
    <select id="getUser" resultType="com.fan.admin.entity.User">
    select * from t_user where id = #{id}
  </select>
</mapper>

Mapper接口:
在这里插入图片描述

package com.fan.admin.mapper;

import com.fan.admin.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper//Mapper接口
public interface UserMapper {
    //此接口方法的实现我们写在xml文件中
    public User getUser(Integer id);
}

Service代码:

package com.fan.admin.service;

import com.fan.admin.entity.User;
import com.fan.admin.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;


@Service("userService")
public class UserService {
    @Resource//这里使用此注解避免报错
    private UserMapper userMapper;//注入Mapper接口

    public User getUser(Integer id){
        return userMapper.getUser(id);
    }
}

Cntroller代码:

package com.fan.admin.controller;

import com.fan.admin.entity.User;
import com.fan.admin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jdbc.core.JdbcTemplate;

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

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

@Controller
public class SqlStateController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Resource
    private UserService userService;//注入service组件

    @ResponseBody
    @GetMapping("/user")
    public User getUserById(@RequestParam("id") Integer id){
        User user = userService.getUser(id);
        return user;
    }
}

mybatis-config.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>
    <!--开启驼峰命名匹配-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

在这里插入图片描述

两种开启驼峰命名的方式只能选择一个:不然报错

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

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml
  #configuration:
    #map-underscore-to-camel-case: true

测试:
在这里插入图片描述

在这里插入图片描述

1.纯注解版的springboot整合mybatis

mapper接口:操作数据库的,相当于实体层
在这里插入图片描述
service:

在这里插入图片描述

controller:
在这里插入图片描述

纯注解版的mybatis就不需要sql映射文件了。因为我们已经在mapper接口那里写了。
测试:
在这里插入图片描述

2.混合版的mybatis:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

测试:
在这里插入图片描述

纯注解版的mybatis:
在这里插入图片描述

最佳实践:
在这里插入图片描述

五、Springboot整合mybatis-plus

mybatis-plus的官网:
https://mp.baomidou.com/

MybatisX快速开发插件:
MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装。
在这里插入图片描述
mybatis-plus快速开始:
第一步,先创建一张表:

在这里插入图片描述

引入依赖;

在这里插入图片描述

在这里插入图片描述

看自动配置类的原理:

在这里插入图片描述

在这里插入图片描述

查询用户:

mapper映射文件的位置,默认是类路径下的mapper文件夹下:
在这里插入图片描述

在这里插入图片描述
mybatis-plus自动配置好了哪些东西:

在这里插入图片描述

实体类准备:

在这里插入图片描述

我们定义的mapper接口继承一个BaseMapper:

其中基础的mapper中已经声明好了一些方法:
在这里插入图片描述
在这里插入图片描述
代码:
在这里插入图片描述

测试结果:
在这里插入图片描述

解决数据库的表名和实体类名不一致的方法:
默认情况下类名会去数据库中找和它实体类名一样的表。

在这里插入图片描述

修改service接口和实现类:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

MP快速开始的小结:
通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能,甚至连 XML 文件都不用编写!

从以上步骤中,我们可以看到集成MyBatis-Plus非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可。

MyBatis-Plus的分页插件的使用:

mybatis原生的分页插件的官方文档:
链接: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md.

mybatis与springboot结合的分页的官方文档:
链接: https://github.com/pagehelper/pagehelper-spring-boot.

MyBatis-Plus参考链接:
链接: https://www.cnblogs.com/l-y-h/p/12859477.html.
https://www.cnblogs.com/l-y-h/p/12859477.html

找到分页条,我们拿来用一下,然后在页面审查元素,右键copy-copy element即可,放到table表格下,然后ctrl+alt+l 进行代码的格式化。
在这里插入图片描述

在这里插入图片描述

前端传递一个当前的页码:后台接收
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

配置mybatis的分页插件:

我们可以参考官网的设置,进行部分修改即可:
https://mp.baomidou.com/guide/page.html

在这里插入图片描述
分页的一些参数设置:

com.fan.admin.config.MybatisConfig的编写:

package com.fan.admin.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();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.H2);
        paginationInnerInterceptor.setOverflow(true);
        paginationInnerInterceptor.setMaxLimit(500L);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }
}

在这里插入图片描述

在这里插入图片描述

<ul>
     <li class="prev disabled"><a href="#">← 前一页</a></li>
     <li th:class="${num==page.current?'active':''} " th:each="num:${#numbers.sequence(1,page.pages)}">
         <a th:href="@{/dynamic_table(pn=${num})}">[[${num}]]</a></li>
     <!--<li><a href="#">2</a></li>
     <li><a href="#">3</a></li>-->
     <li class="next"><a href="#">下一页 → </a></li>
 </ul>

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
分页的前端代码:

<!--分页div-->
 <div class="row">
     <div class="col-lg-6">
         <div class="dataTables_info" id="editable-sample_info">当前第 [[${page.current}]]页,
             共[[${page.pages}]]页,
             一共[[${page.total}]]条记录
         </div>
         <!--分页通过下拉框选择每页显示的个数-->
         <div id="dynamic-table_length" class="dataTables_length">
             <label>
                 <select
                         class="form-control" size="1" name="dynamic-table_length"
                         aria-controls="dynamic-table">
                     <option value="3" th:selected="${page.size==3}">3</option>
                     <option value="5" th:selected="${page.size==5 }">5</option>
                     <option value="10" th:selected="${page.size==10}">10</option>
                     <option value="20" th:selected="${page.size==20}">20</option>

                 </select>
                 每页显示的条数
             </label>
         </div>
     </div>

     <div class="col-lg-6">
         <div class="dataTables_paginate paging_bootstrap pagination">
             <!--直接跳到某一页-->
             <div style="padding-top: 30px">
                 到第<input style="width: 50px" name="pn" id="pn_input" th:value="${param.pageNum}">页
                 <input id="searchPageBtn" style="width: 80px" type="button"  value="确定">
                 <div>
                     <ul>
                         <li th:if="${page.hasPrevious()}"><a id="first_page" th:href="@{/book/dynamic_table_bookPage(pageNum=1)}">首页</a></li>
                      
                         <li class="prev" th:if="${page.hasPrevious()}">
                             <a class="pre_a" th:href="@{/book/dynamic_table_bookPage(pageNum=${page.current} - 1)}">← 上一页</a>
                         </li>
                         <!--遍历条数,pageNo位所有页码的序列号,${pageNo}<=5页面序列号小于5个才显示-->
                         <li th:class="${pageNo==page.current?'active':'' }" th:each="pageNo:${#numbers.sequence(1,page.pages)}"
                             ><!--th:if="${pageNo}<=5"  , -->
                             <a th:class="pageNum_a" th:href="@{/book/dynamic_table_bookPage(pageNum=${pageNo})}" th:text="${pageNo}"></a>
                         </li>


                         <li class="next" th:if="${page.hasNext()}">
                             <!--th:href="'/dynamic_table_bookPage?pageNum='+(${page.current} +1)"-->
                             <a th:href="'/book/dynamic_table_bookPage?pageNum='+(${page.current} +1)" id="next_a"  >下一页 → </a>

                         </li>
                         <li th:if="${page.hasNext()}"><a class="last_page" th:href="@{/book/dynamic_table_bookPage(pageNum=${page.pages})}">尾页</a></li>


                     </ul>
                 </div>
             </div>
         </div>


     </div>
 </div>

分页有关的js:

<!--分页有关的js-->
<script type="text/javascript" th:inline="javascript">
    //首页
    $("#first_page").click(function () {
        var pageNum = 1;
        var pageSize = $(".dataTables_length option:selected").val();
        location.href="/book/dynamic_table_bookPage?pageNum="+(pageNum)+"&pageSize="+pageSize;
        window.event.returnValue=false;
    });
    //上一页
    $(".pre_a").click(function () {

        var pageNum = [[${page.current}]] ;
        var pageSize = $(".dataTables_length option:selected").val();

        location.href="/book/dynamic_table_bookPage?pageNum="+(pageNum-1)+"&pageSize="+pageSize;
        window.event.returnValue=false;
    });
    //每一个页码:
    $(".pageNum_a").click(function () {
        var pageNum = $(this).text();
        var pageSize = $(".dataTables_length option:selected").val();

        location.href="/book/dynamic_table_bookPage?pageNum="+(pageNum)+"&pageSize="+pageSize;
        window.event.returnValue=false;
    });
    /*下一页*/
    $("#next_a").click(function () {

        var pageNum = [[${page.current}]] ;
        var pageSize = $(".dataTables_length option:selected").val();

        location.href="/book/dynamic_table_bookPage?pageNum="+(pageNum+1)+"&pageSize="+pageSize;
        window.event.returnValue=false;
    });
    //尾页
    $(".last_page").click(function () {
        var pageNum = [[${page.pages}]];
        var pageSize = $(".dataTables_length option:selected").val();
        location.href="/book/dynamic_table_bookPage?pageNum="+(pageNum)+"&pageSize="+pageSize;
        window.event.returnValue=false;
    });
</script>
<!--下拉框选择分页pageSize发送请求-->
<script type="text/javascript">
    $(".dataTables_length").change(function(){
        //两个分页的参数,一个默认是第一页,一个是每页的显示条数
        var pageSize = $(".dataTables_length option:selected").val();

        location.href="/book/dynamic_table_bookPage?pageNum=1" +"&pageSize="+pageSize;
        window.event.returnValue=false;
    });
</script>

分页的后台代码controller:

//无条件的分页查找
    @GetMapping("/dynamic_table_bookPage")
    public String dynamic_table_bookPage(
            @RequestParam(required = true,defaultValue = "1",value = "pageNum")Integer pageNum,
            @RequestParam(defaultValue = "3",value = "pageSize")Integer pageSize,
            Model model
    ){
        if(pageNum==null || "".equals(pageNum)){
            pageNum = 1;
        }
        if(pageSize == null || "".equals(pageSize)) {
            pageSize = 3;
        }
        Page<Book> bookPage = new Page<>(pageNum, pageSize);

        System.out.println("bookPage***********"+bookPage);

        Page<Book> page = bookService.getBaseMapper().selectPage(bookPage, null);
        page.getRecords().forEach(System.out::println);

        model.addAttribute("page",page);

        return "table/dynamic_table_book";
    }

六、使用模态框实现新增和修改:

 <!--隐藏的表单,这里使用模态框-->
 <!-- Button trigger modal -->
 <button id="insert_open" style="margin: 10px;float: right" type="button" class="btn btn-primary btn-lg" >
     新增图书
 </button>

 <!-- Modal -->
 <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
             <div class="modal-header">
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                 <h4 class="modal-title" id="myModalLabel">新增图书</h4>
             </div>
             <div class="modal-body">
                 <form id="layer_form" action="" method="post" style="" >
                     <div class="title">
                         <h2 id="form_h2">新增图书</h2>
                         <a onclick="layer.style.display=none"></a>
                     </div>
                     <div style="width: auto;margin-left: 150px;margin-right: 150px">
                         <!--重置表单-->
                         <input type="reset" hidden />
                         <input type="hidden" id="hiddenid" name="id" />
                         <p><label>名称: </label><input type="input" id="name" name="name"  /></p>
                         <p><label>价格: </label><input type="input" name="price" /></p>
                         <p><label>作者: </label><input type="input" name="author" /></p>
                         <p><label>销量: </label><input type="input" name="sales" /></p>
                         <p><label>库存: </label><input type="input" name="stock" /></p> <br>
                         <!--th:value="${book!=null}?${book.stock}:'' "-->
                         <button id="btnSave"   style="margin-left: 70px;width: 80px" class="btn btn-success" type="submit" />保存</a>
                     </div>


                 </form>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                 <!--<button type="button" class="btn btn-primary">保存</button>-->
             </div>
         </div>
     </div>
 </div>

新增和修改的js代码:

//打开新增模态框
    $("#insert_open").click(function () {
        alert("打开新增表单");
        //重置表单
        $('#layer_form')[0].reset();//重置表单
        $("#myModalLabel").text("新增图书");

        //设置表单的action
        $("#layer_form").prop("action","/book/insertBook");
        //弹出模态框
        $("#myModal").modal('show');
    });
</script>
<!--修改模态框-->
<script>
function openUpdateModal(id) {

    alert("myid:" + id);
    //重置表单
    $('#layer_form')[0].reset();//重置表单
    $("#myModalLabel").text("修改图书");
    //设置模态框的action,设置属性和值:$(selector).prop(property,value)
    $("#layer_form").prop("action", "/book/updateBook");
    //数据回填
    $.post(
        "/book/selectById",
        {id:id},
        function (jsonData) {
            loadDatatoForm("layer_form", jsonData);
        },
        "json"
    );
    //回填完后弹出模态框
    $("#myModal").modal('show');

}
</script>
<!--加载json数据到表格-->
<script >
    /*回填controller返回的json数据到form表单,将前天数据以json格式返回, @ResponseBody: return book;*/
    function loadDatatoForm(fromId, jsonDate) {
        var obj = jsonDate;
        var key, value, tagName, type, arr;
        for (x in obj) {
            key = x;
            value = obj[x];
            $("#" + fromId + " [name='" + key + "'],#" + fromId + " [name='" + key + "[]']").each(function () {
                tagName = $(this)[0].tagName;
                type = $(this).attr('type');
                if (tagName == 'INPUT') {
                    if (type == 'radio') {
                        $(this).attr('checked', $(this).val() == value);
                    } else if (type == 'checkbox') {
                        try {
                            arr = value.split(',');
                            for (var i = 0; i < arr.length; i++) {
                                if ($(this).val() == arr[i]) {
                                    $(this).attr('checked', true);
                                    break;
                                }
                            }
                        } catch (e) {
                            $(this).attr('checked', value);
                        }
                    } else {
                        $(this).val(value);
                    }
                } else if (tagName == 'TEXTAREA') {
                    $(this).val(value);
                } else if (tagName == 'SELECT') {
                    if ($(this).hasClass("select2")) {
                        $(this).val(value).trigger("change");
                    } else {
                        $(this).val(value);
                    }

                }

            });
        }

    }

</script>

后台controller代码:

 //增加
    @PostMapping("/insertBook")
    public String insertBook(Model model,Book book){
        log.info("前端参数:{}",book);
        boolean save = bookService.save(book);
        if(save){
            return "redirect:/book/dynamic_table_bookPage";//重新定向到查询
        }else {
        model.addAttribute("msg","添加失败");
        }

        return "table/dynamic_table_book";
    }
    //修改要经过两个步骤,回显和更新
    @ResponseBody
    @PostMapping("/selectById")
    public Book selectById(Model model,@RequestParam(value = "id") Integer id){

        Book book = bookService.getById(id);
        System.out.println("查询回显数据^^^^^^^^^^^^:"+book);
        //model.addAttribute("book",book);
        return book;
    }

    @PostMapping("/updateBook")
    public String updateBook(Model model, Book book){

        boolean b = bookService.updateById(book);
        System.out.println("修改:==========================="+book);

        return "redirect:/book/dynamic_table_bookPage";
    }

优化:新增和修改后回到修改的那一页:
添加图书的:
在这里插入图片描述

在这里插入图片描述
自己项目中的:
在这里插入图片描述
在这里插入图片描述

修改图书的:
在这里插入图片描述
后台代码:
在这里插入图片描述

删除用户:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

 <td>
   <!--/user/delete/{id}-->
    <a th:href="@{/user/delete/{id}(id=${user.id},pn=${page.current})}" class="btn btn-danger btn-sm" type="button">删除</a>
</td>

在这里插入图片描述

 //删除一个用户,使用路径变量的方式
    @GetMapping("/user/delete/{id}")
    public String deleteUserById(@PathVariable("id") Integer id,
                                 @RequestParam(value = "pn",defaultValue = "1")Integer pn,
                                 RedirectAttributes re){
        userService.removeById(id);
        re.addAttribute("pn",pn);
        return "redirect:/dynamic_table";
    }

删除用户的时候将但钱页码也发送过去:
在这里插入图片描述
后台也改一下:
在这里插入图片描述

七、条件查询的分页:

查询参数的回显:

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值