当前位置: 首页 > news >正文

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: 8090spring:datasource:#---- ^ MySQL 数据库配置 ----#driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/帅龍之龍?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTCusername: 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: 20filters: stat,wall# 合并多个DruidDataSource的监控数据#useGlobalDataSourceStat: true# 通过connectProperties属性来打开mergeSql功能;慢SQL记录connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000# 采集web-jdbc关联监控的数据web-stat-filter:enabled: trueurl-pattern: "/*"exclusions: "*.txt,*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"# 监控配置stat-view-servlet:enabled: trueurl-pattern: "/druid/*"reset-enable: falselogin-username: rootlogin-password: 123456allow:deny:#---- / Druid ^ 数据库连接池配置 ----##---- ^ 文件上传大小限制 ----#servlet:multipart:max-file-size: 30MBmax-request-size: 30MB#---- / 文件上传大小限制 ----##---- ^ thymeleaf 前端模板配置 ----#thymeleaf:mode: HTMLencoding: UTF-8cache: falseprefix: classpath:/templates/suffix: .html#---- / thymeleaf 前端模板配置 ----##---- ^ mybatis-plus 配置 ----#
mybatis-plus:mapper-locations: mapper/*.xmlconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: truetype-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 {@Autowiredprivate RecordServiceImpl recordService;/*** 保存用户访问记录*/@GetMapping(value = "saveUserAccessRecord")@ResponseBody@CrossOriginpublic <T> T saveUserAccessRecord (HttpServletRequest request) {return recordService.saveUserAccessRecord(request);}/*** 删除用户访问记录*/@GetMapping(value = "deleteUserAccessRecord")@ResponseBody@CrossOriginpublic <T> T deleteUserAccessRecord (@RequestParam("recordId") Integer recordId) {return recordService.deleteUserAccessRecord(recordId);}/*** 修改用户访问记录*/@GetMapping(value = "modifyUserAccessRecord")@ResponseBody@CrossOriginpublic <T> T modifyUserAccessRecord () {return recordService.modifyUserAccessRecord();}/*** 查询用户访问记录*/@GetMapping(value = "queryUserAccessRecord")@ResponseBody@CrossOriginpublic <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);@Autowiredpublic RecordMapper recordMapper;@Overridepublic <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;}@Overridepublic <T> T deleteUserAccessRecord(Integer recordId) {try {recordMapper.deleteById(recordId);return (T) "success";} catch (Exception e) {return (T) "fail";}}@Overridepublic <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";}}@Overridepublic <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);}
}

九、运行效果

(1)德鲁伊监控面板

(2)增删改查示例

相关文章:

SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池

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

导致 JVM 内存泄露的 ThreadLocal 详解

为什么要有 ThreadLocal 当我们在学习JDBC时获取数据库连接时&#xff0c;每次CRUD的时候都需要再一次的获取连接对象&#xff0c;并把我们的sql交给连接对象实现操作。 在实际的工作中&#xff0c;我们不会每次执行 SQL 语句时临时去建立连接&#xff0c;而是会借助数据库连接…...

使用预约小程序app有什么方便之处

一、用户人群广&#xff1a;无论是老年人、残疾人还是上班族&#xff0c;只要有需要&#xff0c;都可以通过该小程序轻松预约服务。例如&#xff0c;行动不便的老年人或残疾人&#xff0c;可以通过小程序约家政服务、医疗护理等服务&#xff0c;省去了亲自前往服务场所的麻烦。…...

【转】ubuntu 安装 OpenCv 4.6脚本 installOCV.sh

摘自 https://github.com/opencv/opencv/issues/22132 好东西&#xff0c;收一下。 installOCV.sh#! /bin/bash VER4.6.0 PYTHON_VERSION3.8 CORES2 echo "Script for installing the OpenCV $VER on Ubuntu 18.04 LTS" echo "Updating the OS..." sudo …...

Android 视图动画与属性动画的区别

Android的视图动画和属性动画在功能和使用上有一些明显的区别。 视图动画主要作用于视图&#xff0c;实现如缩放、旋转等效果。这种动画效果相对固定&#xff0c;只能应用于视图对象&#xff0c;且只能改变视图的大小和位置&#xff0c;而不能真正改变视图的属性。视图动画在A…...

Springboot——jxls实现同sheet多个列表展示

文章目录 前言制定模板1、限定模板数据的范围2、设定报表展示项 编写测试类1、将xls模板文件放于 resource 下的 doc文件夹中2、导入依赖文件3、编写接口和导出逻辑 效果预览结论 前言 在之前的博客中Springboot——使用jxls实现excel模板导出excel&#xff0c;具体说明了jxls…...

分布式软件架构——服务端缓存的三种属性

服务端缓存 在透明多级分流系统中&#xff0c;我们以流量从客户端中发出开始&#xff0c;以流量到达服务器集群中真正处理业务的节点结束。一起探索了在这个过程中与业务无关的一些通用组件&#xff0c;包括DNS、CDN、客户端缓存&#xff0c;等等。 实际上&#xff0c;服务端缓…...

Flink之Watermark策略代码模板

方式作用WatermarkStrategy.noWatermarks()不生成watermarkWatermarkStrategy.forMonotonousTimestamps()紧跟最大事件时间watermark生成策略WatermarkStrategy.forBoundedOutOfOrderness()允许乱序watermark生成策略WatermarkStrategy.forGenerator()自定义watermark生成策略 …...

ubuntu 安装postgresql,增加VECTOR向量数据库插件 踏坑详细流程

PGSQL安装&#xff0c;删除&#xff0c;运行&#xff0c;修改密码流程 Ubuntu18.04安装与配置postgresql含远程连接教程&#xff08;含踩坑记录&#xff09;_sudo apt-get install postgresql-CSDN博客 详细安装流程以上博客&#xff0c;自己也记录下 安装vector扩展连接 声明…...

基于Springboot实现影视影院订票选座管理系统【项目源码+论文说明】分享

基于Springboot实现影视影院订票选座管理系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个影城管理系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论…...

mysql批量插入数据,跳过唯一索引报错

数据准备 DROP TABLE IF EXISTS user1; CREATE TABLE user1 ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(45) NULL, age INT(3) NOT NULL, PRIMARY KEY (id), UNIQUE INDEX u_name (name));insert into user1(name, age) values (zhangshan, 18), (lisi, 19);1. INSERT I…...

论文阅读--Energy efficiency in heterogeneous wireless access networks

异构无线接入网络的能源效率 论文信息&#xff1a;Navaratnarajah S, Saeed A, Dianati M, et al. Energy efficiency in heterogeneous wireless access networks[J]. IEEE wireless communications, 2013, 20(5): 37-43. I. ABSTRACT && INTRODUCTION 本文提出了无…...

Redis的C客户端(hiredis库)使用

文章目录 1、Ubuntu安装redis服务端2、hiredis库的安装3、同步API接口的使用3.1、连接redis数据库redisConnect3.2、发送需要执行的命令redisCommand3.3、redisCommandArgv函数3.4、redisAppendCommand*函数支持管道命令3.5、释放资源3.6、同步连接代码 3.7、异步连接4、redis连…...

光引擎、光模块、光器件之间的关系和区别

最近小编有收到一些用户问“光引擎、光模块、光器件之间的关系和区别&#xff1f;”&#xff0c;众所周知光通信技术一直在不断演进&#xff0c;为满足不断增长的数据传输需求提供了强大的解决方案。而光通信系统中&#xff0c;光引擎、光模块和光器件是关键的组成部分&#xf…...

【办公-excel】两个时间相减 (二) - 带毫秒的时间进行相减操作

一、使用内部函数 1.1 效果展示 TEXT(((RIGHT(TEXT(B2,"yyyy-mm-dd hh:mm:ss.000"),LEN(TEXT(B2,"yyyy-mm-dd hh:mm:ss.000"))-FIND(".",TEXT(B2,"yyyy-mm-dd hh:mm:ss.000")))-RIGHT(TEXT(A2,"yyyy-mm-dd hh:mm:ss.000"),…...

二次封装View Design的table组件,实现宽度自适应,内容在一行展示

由于table组件本身并不支持宽度自适应&#xff0c;但实际项目需要&#xff0c;而且多处有用到table组件&#xff0c;所以尝试着自己来二次封装一下组件 想法 刚开始的想法很简单&#xff0c;就是获取每一列中数据和标题在表格中的长度&#xff0c;然后将当中最大的长度作为该列…...

Node.js代码漏洞扫描工具介绍——npm audit

npm audit 运行安全检查 主要作用&#xff1a;检查命令将项目中配置的依赖项的描述提交到默认注册中心&#xff0c;并要求报告已知漏洞。如果发现任何漏洞&#xff0c;则将计算影响和适当的补救措施。如果 fix 提供了参数&#xff0c;则将对包树应用补救措施。 具体参考&#x…...

node.js知识系列(3)-每天了解一点

目录 1. Express.js 中的中间件2. 处理路由和请求3. RESTful 路由4. 身份验证和授权5. 视图引擎6. 错误处理中间件7. 文件上传处理8. Cookie 和 Session 管理9. 路由参数和查询参数10. 处理跨域请求&#xff08;CORS&#xff09; &#x1f44d; 点赞&#xff0c;你的认可是我创…...

Zabbix监控系统 自定义监控项、自动发现与自动注册

Zabbix监控系统 自定义监控项、自动发现与自动注册 一、自定义监控内容部署实例二、zabbix 自动发现与自动注册部署实例2.1 部署zabbix自动发现 一、自定义监控内容部署实例 案列&#xff1a;自定义监控客户端服务器登录的人数 需求&#xff1a;限制登录人数不超过 3 个&#…...

Python信号之分享

在了解了Linux的信号基础之后&#xff0c;Python标准库中的signal包就很容易学习和理解。signal包负责在Python程序内部处理信号&#xff0c;典型的操作包括预设信号处理函数&#xff0c;暂停并等待信号&#xff0c;以及定时发出SIGALRM等。要注意&#xff0c;signal包主要是针…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...