之前搭建SpringBoot项目工程,所使用的持久层框架不是Mybatis就是JPA,还没试过整合MybatisPlus框架并使用,原来也如此简单。在此简单记录一下在SpringBoot项目中,整合MybatisPlus持久层框架、Druid数据库连接池的过程。
(1)pom.xml
- "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.0modelVersion>
-
- <groupId>org.examplegroupId>
- <artifactId>帅龍之龍artifactId>
- <version>1.0-SNAPSHOTversion>
-
-
- <parent>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-parentartifactId>
- <version>2.5.3version>
-
- <relativePath/>
- parent>
-
-
- <properties>
- <java.version>1.8java.version>
-
- properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-webartifactId>
- dependency>
-
-
- <dependency>
- <groupId>org.mybatis.spring.bootgroupId>
- <artifactId>mybatis-spring-boot-starterartifactId>
- <version>2.1.1version>
- dependency>
-
-
- <dependency>
- <groupId>com.baomidougroupId>
- <artifactId>mybatis-plus-boot-starterartifactId>
- <version>3.5.2version>
- dependency>
-
-
- <dependency>
- <groupId>com.alibabagroupId>
- <artifactId>druid-spring-boot-starterartifactId>
- <version>1.2.15version>
- dependency>
-
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <scope>runtimescope>
- dependency>
-
-
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-thymeleafartifactId>
- dependency>
-
-
- <dependency>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- dependency>
-
-
- <dependency>
- <groupId>eu.bitwalkergroupId>
- <artifactId>UserAgentUtilsartifactId>
- <version>1.20version>
- dependency>
- dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-maven-pluginartifactId>
- 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 saveUserAccessRecord (HttpServletRequest request) { - return recordService.saveUserAccessRecord(request);
- }
-
- /**
- * 删除用户访问记录
- */
- @GetMapping(value = "deleteUserAccessRecord")
- @ResponseBody
- @CrossOrigin
- public
T deleteUserAccessRecord (@RequestParam("recordId") Integer recordId) { - return recordService.deleteUserAccessRecord(recordId);
- }
-
- /**
- * 修改用户访问记录
- */
- @GetMapping(value = "modifyUserAccessRecord")
- @ResponseBody
- @CrossOrigin
- public
T modifyUserAccessRecord () { - return recordService.modifyUserAccessRecord();
- }
-
- /**
- * 查询用户访问记录
- */
- @GetMapping(value = "queryUserAccessRecord")
- @ResponseBody
- @CrossOrigin
- public
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 saveUserAccessRecord(HttpServletRequest request); -
-
T deleteUserAccessRecord(Integer recordId); -
-
T modifyUserAccessRecord(); -
-
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 saveUserAccessRecord(HttpServletRequest request) { - HashMap
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 deleteUserAccessRecord(Integer recordId) { - try {
- recordMapper.deleteById(recordId);
- return (T) "success";
- } catch (Exception e) {
- return (T) "fail";
- }
- }
-
- @Override
- public
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 queryUserAccessRecord() { - // 根据ID查询
- // Long recordId = (long) 1;
- // return (T) recordMapper.selectById(recordId);
-
- // 使用 QueryWrapper 构造器查询全部用户
- // QueryWrapper
queryWrapper = new QueryWrapper<>(); - // queryWrapper.eq("ip", "0:0:0:0:0:0:0:1");
- // return (T) recordMapper.selectList(queryWrapper);
-
- // 使用 LambdaQueryWrapper 构造器查询全部用户
- LambdaQueryWrapper
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
{ - }
(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');

