SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。

前言

之前搭建SpringBoot项目工程,所使用的持久层框架不是Mybatis就是JPA,还没试过整合MybatisPlus框架并使用,原来也如此简单。在此简单记录一下在SpringBoot项目中,整合MybatisPlus持久层框架、Druid数据库连接池的过程。

一、导入依赖

(1)pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>帅龍之龍</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- SpringBoot应用的父级依赖:提供了SpringBoot统一的依赖管理和插件管理 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.5.3</version>
        <!-- <version>3.0.1</version> -->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!-- JDK版本 -->
    <properties>
        <java.version>1.8</java.version>
        <!-- <java.version>17</java.version> -->
    </properties>

    <dependencies>
        <!-- Web启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- MyBatis 持久层框架 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <!-- MyBatisPlus 增强框架 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

        <!-- Druid 数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.15</version>
        </dependency>

        <!-- MySQL 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

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

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- UserAgent -->
        <dependency>
            <groupId>eu.bitwalker</groupId>
            <artifactId>UserAgentUtils</artifactId>
            <version>1.20</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

二、项目配置

(1)application.yml

server:
  port: 8090

spring:
  datasource:
    #---- ^ MySQL 数据库配置 ----#
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/帅龍之龍?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    username: 
    password: 
    type: com.alibaba.druid.pool.DruidDataSource
    #---- / MySQL 数据库配置 ----#

    #---- ^ Druid 数据库连接池配置 ----#
    druid:
      # 初始化连接池数量
      initial-size: 5
      # 最小连接池数量
      min-idle: 5
      # 最大连接池数量
      max-active: 30
      # 配置获取连接等待超时的时间,单位毫秒
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      # 验证数据库连接的有效性,若返回结果不为空,则说明连接可用
      validation-query: select 1
      # 在检查闲置连接时同时检查连接可用性
      test-while-idle: true
      # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      test-on-borrow: false
      # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      test-on-return: false
      # 是否缓存preparedStatement,也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说Oracle,而在MySQL下建议关闭
      pool-prepared-statements: true
      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat,wall
      # 合并多个DruidDataSource的监控数据
      #useGlobalDataSourceStat: true
      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
      connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 采集web-jdbc关联监控的数据
      web-stat-filter:
        enabled: true
        url-pattern: "/*"
        exclusions: "*.txt,*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
      # 监控配置
      stat-view-servlet:
        enabled: true
        url-pattern: "/druid/*"
        reset-enable: false
        login-username: root
        login-password: 123456
        allow:
        deny:
    #---- / Druid ^ 数据库连接池配置 ----#

  #---- ^ 文件上传大小限制 ----#
  servlet:
    multipart:
      max-file-size: 30MB
      max-request-size: 30MB
  #---- / 文件上传大小限制 ----#

  #---- ^ thymeleaf 前端模板配置 ----#
  thymeleaf:
    mode: HTML
    encoding: UTF-8
    cache: false
    prefix: classpath:/templates/
    suffix: .html
  #---- / thymeleaf 前端模板配置 ----#

#---- ^ mybatis-plus 配置 ----#
mybatis-plus:
  mapper-locations: mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  type-aliases-package: org.example.pojo.entity
#---- / mybatis-plus 配置 ----#

三、控制层

(1)/src/org/example/controller/RecordController.java

package org.example.controller;

import org.example.service.impl.RecordServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping(value = "api")
public class RecordController {
   
   

    @Autowired
    private RecordServiceImpl recordService;

    /**
     * 保存用户访问记录
     */
    @GetMapping(value = "saveUserAccessRecord")
    @ResponseBody
    @CrossOrigin
    public <T> T saveUserAccessRecord (HttpServletRequest request) {
   
   
        return recordService.saveUserAccessRecord(request);
    }

    /**
     * 删除用户访问记录
     */
    @GetMapping(value = "deleteUserAccessRecord")
    @ResponseBody
    @CrossOrigin
    public <T> T deleteUserAccessRecord (@RequestParam("recordId") Integer recordId) {
   
   
        return recordService.deleteUserAccessRecord(recordId);
    }

    /**
     * 修改用户访问记录
     */
    @GetMapping(value = "modifyUserAccessRecord")
    @ResponseBody
    @CrossOrigin
    public <T> T modifyUserAccessRecord () {
   
   
        return recordService.modifyUserAccessRecord();
    }

    /**
     * 查询用户访问记录
     */
    @GetMapping(value = "queryUserAccessRecord")
    @ResponseBody
    @CrossOrigin
    public <T> T queryUserAccessRecord () {
   
   
        return recordService.queryUserAccessRecord();
    }
}

四、接口层

(1)/src/org/example/service/IRecordService.java

package org.example.service;

import javax.servlet.http.HttpServletRequest;

public interface IRecordService {
   
   
    <T> T saveUserAccessRecord(HttpServletRequest request);

    <T> T deleteUserAccessRecord(Integer recordId);

    <T> T modifyUserAccessRecord();

    <T> T queryUserAccessRecord();
}

五、实现层

(1)/src/org/example/service/impl/RecordServiceImpl.java

package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import eu.bitwalker.useragentutils.UserAgent;
import org.example.mapper.RecordMapper;
import org.example.pojo.entity.Record;
import org.example.service.IRecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;

@Service
public class RecordServiceImpl implements IRecordService {
   
   

    private static final Logger log = LoggerFactory.getLogger(RecordServiceImpl.class);

    @Autowired
    public RecordMapper recordMapper;

    @Override
    public <T> T saveUserAccessRecord(HttpServletRequest request) {
   
   
        HashMap<String, Object> responseObj = new HashMap<>();

        try {
   
   
            String agent = request.getHeader("User-Agent");
            UserAgent userAgent = UserAgent.parseUserAgentString(agent);

            // 获取发起请求的IP地址
            String ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
   
   
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
   
   
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
   
   
                ip = request.getRemoteAddr();
            }

            Record record = new Record();
            record.setIp(ip);
            record.setBrowser(userAgent.getBrowser().getName());
            record.setOs(userAgent.getOperatingSystem().getName());
            record.setDeviceType(userAgent.getOperatingSystem().getDeviceType().getName());
            recordMapper.insert(record);

            responseObj.put("code", 200);
            responseObj.put("success", true);
            responseObj.put("data", record);
            responseObj.put("msg", "保存成功");
        } catch (Exception e) {
   
   
            responseObj.put("code", 500);
            responseObj.put("success", false);
            responseObj.put("msg", e.getMessage());
        }

        return (T) responseObj;
    }

    @Override
    public <T> T deleteUserAccessRecord(Integer recordId) {
   
   
        try {
   
   
            recordMapper.deleteById(recordId);
            return (T) "success";
        } catch (Exception e) {
   
   
            return (T) "fail";
        }
    }

    @Override
    public <T> T modifyUserAccessRecord() {
   
   
        try {
   
   
            Record record = new Record();
            record.setId(1L);
            record.setIp("localhost");
            record.setBrowser("帅龍之龍");
            record.setOs("Windows 11");
            record.setDeviceType("Android");
            recordMapper.updateById(record);
            return (T) "success";
        } catch (Exception e) {
   
   
            return (T) "fail";
        }
    }

    @Override
    public <T> T queryUserAccessRecord() {
   
   
        // 根据ID查询
        // Long recordId = (long) 1;
        // return (T) recordMapper.selectById(recordId);

        // 使用 QueryWrapper 构造器查询全部用户
        // QueryWrapper<Record> queryWrapper = new QueryWrapper<>();
        // queryWrapper.eq("ip", "0:0:0:0:0:0:0:1");
        // return (T) recordMapper.selectList(queryWrapper);

        // 使用 LambdaQueryWrapper 构造器查询全部用户
        LambdaQueryWrapper<Record> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Record::getIp, "127.0.0.1");
        return (T) recordMapper.selectList(lambdaQueryWrapper);
    }
}

六、对象实体

(1)/src/org/example/pojo/entity/Record.java

package org.example.pojo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.ToString;

import java.sql.Timestamp;

@Data
@ToString
public class Record {
   
   
    // 指定主键名、主键生产策略
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private String ip;

    private String os;

    private String browser;

    // 指定列名,若一致则可以不用指定,若不一致则需要指定
    @TableField("device_type")
    private String deviceType;

    // 指定列名,若一致则可以不用指定,若不一致则需要指定
    @TableField("create_time")
    private Timestamp createTime;
}

七、持久层

(1)/src/org/example/mapper/RecordMapper.java

package org.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.example.pojo.entity.*;
import org.springframework.stereotype.Repository;

@Repository
public interface RecordMapper extends BaseMapper<Record> {
   
   
}

八、启动器

(1)App.java

package org.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@MapperScan("org.example.*")
@EnableWebMvc
@EnableTransactionManagement
@SpringBootApplication
public class App {
   
   
    public static void main(String[] args) {
   
   
        SpringApplication.run(App.class, args);
    }
}

九、数据表

--
-- 表的结构 `record`
--

CREATE TABLE IF NOT EXISTS `record` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `ip` varchar(30) DEFAULT NULL,
  `os` varchar(30) DEFAULT NULL,
  `browser` varchar(30) DEFAULT NULL,
  `device_type` varchar(30) DEFAULT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;

--
-- 转存表中的数据 `record`
--

INSERT INTO `record` (`id`, `ip`, `os`, `browser`, `device_type`, `create_time`) VALUES
(1, 'localhost', 'Windows 11', '帅龍之龍', 'Android', '2021-11-13 17:33:24'),
(2, '0:0:0:0:0:0:0:1', 'WINDOWS_10', 'CHROME', 'Computer', '2021-11-13 17:43:54'),
(3, '0:0:0:0:0:0:0:1', 'WINDOWS_10', 'CHROME', 'Computer', '2021-11-13 17:48:28'),
(4, '127.0.0.1', 'WINDOWS_10', 'CHROME', 'Computer', '2021-11-13 17:49:38'),
(5, '127.0.0.1', 'WINDOWS_10', 'CHROME', 'Computer', '2021-11-13 17:54:42'),
(6, '192.168.0.101', 'Windows 10', 'Chrome 9', 'Computer', '2023-10-09 14:18:32'),
(7, '192.168.0.101', 'Windows 10', 'Chrome 9', 'Computer', '2023-10-09 14:19:29');

十、运行效果

(1)德鲁伊登录页面

(2)查询示例

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
21 4
|
8天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
58 1
|
3天前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
8 0
|
10天前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
36 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
10天前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
22 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
11天前
|
SQL 关系型数据库 MySQL
Go语言项目高效对接SQL数据库:实践技巧与方法
在Go语言项目中,与SQL数据库进行对接是一项基础且重要的任务
28 11
|
9天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
18 3
|
10天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第7天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建 Spring Boot 项目并配置 Spring Security。接着,实现后端 API 以提供菜单数据。在前端部分,使用 Ant Design Pro Vue 脚手架创建项目,并配置动态路由和菜单。最后,启动前后端服务,实现高效、美观且功能强大的应用框架。
13 2
|
10天前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
11 0
mybatis使用二:springboot 整合 mybatis,创建开发环境
|
11天前
|
Java 数据库连接 API
springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。