SpringBoot 2.7.X 一套代码适配多种数据库讲解(图文详细)

news2024/9/19 10:57:03

文章目录

  • SpringBoot 2.7.X 一套代码适配多种数据库讲解(图文详细)
    • 1 简介
      • 1.1 概述
      • 1.2 环境安装
      • 1.3 测试脚本
    • 2 基于Mybatis 方式
      • 2.1 添加DatabaseIdProvider配置
      • 2.2 在Mybatis的XML中,指定SQL语句的databaseId标签
      • 2.3 控制器接口样例
      • 2.4 呈现效果
    • 3 基于MP框架Wrapps条件构造器方式
      • 3.1 框架整合
      • 3.2 业务接口实现层
      • 3.3 控制器层接口
      • 3.4 Yaml多数据源配置
      • 3.5 呈现效果

SpringBoot 2.7.X 一套代码适配多种数据库讲解(图文详细)

1 简介

1.1 概述

  • 随着日新月异的项目变化,应对不同客户的数据库安全需求,避免企业项目重复繁琐的工作量。故需要项目同时适配多种数据库,如MYSQL、Oracle、PostgreSQL、SQL Server、kingBaseES等…,提升项目交付能力,从而获取更多效益和口碑!

1.2 环境安装

  • PostgreSQL 15数据库安装: https://blog.csdn.net/weixin_44187730/article/details/129958012

  • MySQL 5.7数据库安装: https://blog.csdn.net/weixin_44187730/article/details/101287509

  • Oracle 12c数据库安装: https://blog.csdn.net/weixin_44187730/article/details/107543314

1.3 测试脚本

  • Oracle
-- ----------------------------
-- 1. 测试-Oracle 格式表结构
-- ----------------------------
create table ed_sys_user (
  user_id           number(20)      not null,
  dept_id           number(20)      default null,
  user_name         varchar2(40)    not null,
  nick_name         varchar2(40)    not null,
  user_type         varchar2(10)    default 'sys_user',
  email             varchar2(50)    default '',
  phone_number      varchar2(11)    default '',
  sex               char(1)         default '0',
  avatar            varchar2(100)   default '',
  password          varchar2(100)   default '',
  status            char(1)         default '0',
  del_flag          char(1)         default '0',
  login_ip          varchar2(128)   default '',
  login_date        date,
  create_by         varchar2(64),
  create_time       date,
  update_by         varchar2(64)    default '',
  update_time       date,
  remark            varchar2(500)   default ''
);

alter table ed_sys_user add constraint pk_sys_user primary key (user_id);

comment on table  ed_sys_user              is '用户信息表';
comment on column ed_sys_user.user_id      is '用户ID';
comment on column ed_sys_user.dept_id      is '部门ID';
comment on column ed_sys_user.user_name    is '用户账号';
comment on column ed_sys_user.nick_name    is '用户昵称';
comment on column ed_sys_user.user_type    is '用户类型(sys_user系统用户)';
comment on column ed_sys_user.email        is '用户邮箱';
comment on column ed_sys_user.phone_number  is '手机号码';
comment on column ed_sys_user.sex          is '用户性别(0男 1女 2未知)';
comment on column ed_sys_user.avatar       is '头像路径';
comment on column ed_sys_user.password     is '密码';
comment on column ed_sys_user.status       is '帐号状态(0正常 1停用)';
comment on column ed_sys_user.del_flag     is '删除标志(0代表存在 2代表删除)';
comment on column ed_sys_user.login_ip     is '最后登录IP';
comment on column ed_sys_user.login_date   is '最后登录时间';
comment on column ed_sys_user.create_by    is '创建者';
comment on column ed_sys_user.create_time  is '创建时间';
comment on column ed_sys_user.update_by    is '更新者';
comment on column ed_sys_user.update_time  is '更新时间';
comment on column ed_sys_user.remark       is '备注';

-- ----------------------------
-- 初始化-用户信息表数据
-- ----------------------------
insert into ed_sys_user values(1,  103, 'Sysadmin', '超级管理员', 'sys_user', '111106@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate, 'Sysadmin', sysdate, 'Sysadmin', sysdate,'超级管理员-Oracle数据库数据');


  • MySQL
-- ----------------------------
-- 1. 测试-Mysql 格式表结构
-- ----------------------------
drop table if exists ed_sys_user;
create table ed_sys_user (
  user_id           bigint(20)      not null     comment '用户ID',
  dept_id           bigint(20)      default null               comment '部门ID',
  user_name         varchar(30)     not null                   comment '用户账号',
  nick_name         varchar(30)     not null                   comment '用户昵称',
  user_type         varchar(10)     default 'sys_user'         comment '用户类型(sys_user系统用户)',
  email             varchar(50)     default ''                 comment '用户邮箱',
  phone_number       varchar(11)     default ''                 comment '手机号码',
  sex               char(1)         default '0'                comment '用户性别(0男 1女 2未知)',
  avatar            varchar(100)    default ''                 comment '头像地址',
  password          varchar(100)    default ''                 comment '密码',
  status            char(1)         default '0'                comment '帐号状态(0正常 1停用)',
  del_flag          char(1)         default '0'                comment '删除标志(0代表存在 2代表删除)',
  login_ip          varchar(128)    default ''                 comment '最后登录IP',
  login_date        datetime                                   comment '最后登录时间',
  create_by         varchar(64)     default ''                 comment '创建者',
  create_time       datetime                                   comment '创建时间',
  update_by         varchar(64)     default ''                 comment '更新者',
  update_time       datetime                                   comment '更新时间',
  remark            varchar(500)    default null               comment '备注',
  primary key (user_id)
) engine=innodb comment = '用户信息表';

-- ----------------------------
-- 初始化-用户信息表数据
-- ----------------------------
insert into ed_sys_user values(1,  103, 'Sysadmin', '超级管理员', 'sys_user', '99099@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'Sysadmin', sysdate(), 'Sysadmin', sysdate(), '超级管理员-Mysql数据库中数据');


  • PostgreSQL
-- ----------------------------
-- 1. 测试-postgresSql 格式表结构
-- ----------------------------
drop table if exists ed_sys_user;
create table if not exists ed_sys_user
(
    user_id     int8,
    dept_id     int8,
    user_name   varchar(30) not null,
    nick_name   varchar(30) not null,
    user_type   varchar(10)  default 'sys_user'::varchar,
    email       varchar(50)  default ''::varchar,
    phone_number varchar(11)  default ''::varchar,
    sex         char         default '0'::bpchar,
    avatar      varchar(100) default ''::varchar,
    password    varchar(100) default ''::varchar,
    status      char         default '0'::bpchar,
    del_flag    char         default '0'::bpchar,
    login_ip    varchar(128) default ''::varchar,
    login_date  timestamp,
    create_by   varchar(64)  default ''::varchar,
    create_time timestamp,
    update_by   varchar(64)  default ''::varchar,
    update_time timestamp,
    remark      varchar(500) default null::varchar,
    constraint "ed_sys_user_pk" primary key (user_id)
);

comment on table ed_sys_user is '用户信息表';
comment on column ed_sys_user.user_id is '用户ID';
comment on column ed_sys_user.dept_id is '部门ID';
comment on column ed_sys_user.user_name is '用户账号';
comment on column ed_sys_user.nick_name is '用户昵称';
comment on column ed_sys_user.user_type is '用户类型(sys_user系统用户)';
comment on column ed_sys_user.email is '用户邮箱';
comment on column ed_sys_user.phone_number is '手机号码';
comment on column ed_sys_user.sex is '用户性别(0男 1女 2未知)';
comment on column ed_sys_user.avatar is '头像地址';
comment on column ed_sys_user.password is '密码';
comment on column ed_sys_user.status is '帐号状态(0正常 1停用)';
comment on column ed_sys_user.del_flag is '删除标志(0代表存在 2代表删除)';
comment on column ed_sys_user.login_ip is '最后登陆IP';
comment on column ed_sys_user.login_date is '最后登陆时间';
comment on column ed_sys_user.create_by is '创建者';
comment on column ed_sys_user.create_time is '创建时间';
comment on column ed_sys_user.update_by is '更新者';
comment on column ed_sys_user.update_time is '更新时间';
comment on column ed_sys_user.remark is '备注';

-- ----------------------------
-- 初始化-用户信息表数据
-- ----------------------------
insert into ed_sys_user values(1,  103, 'Sysadmin', '超级管理员', 'sys_user', '99099@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', now(), 'Sysadmin', now(), 'Sysadmin', now(), '超级管理员-postgresSql数据库数据');

2 基于Mybatis 方式

2.1 添加DatabaseIdProvider配置

package com.xs.dsy.config;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

/**
 * @Copyright (C), 2016-2023 MP
 * @ClassName: DsyDateSourceConfg
 * @Author: hf
 * @Date: 2023/4/24 15:50
 * @Description: 动态数据源Provider配置
 */
@Configuration
public class DsyDateSourceConfig {

    /**
     * 自动识别使用的数据库类型
     * 在mapper.xml中databaseId的值就是跟这里的value值对应,Key值必须是数据库供应商的标识ID,
     * 
     * 数据库标识ID名称: dataSource.getConnection().getMetaData().getDatabaseProductName();
     * 
     * 如果没有databaseId选择则说明该sql适用所有数据库
     */
    @Bean
    public DatabaseIdProvider getDatabaseIdProvider() {
        DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
        Properties properties = new Properties();
        properties.setProperty("Oracle", "oracle");
        properties.setProperty("MySQL", "mysql");
        properties.setProperty("PostgreSQL", "PostgreSQL");
        databaseIdProvider.setProperties(properties);
        return databaseIdProvider;
    }

}

2.2 在Mybatis的XML中,指定SQL语句的databaseId标签

<?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.xs.dsy.ed.mapper.EdSysUserMapper">

    <!--MySQL数据库指定-->
    <select id="all" databaseId="mysql" resultType="com.xs.dsy.ed.domain.EdSysUser">
         SELECT * FROM ED_SYS_USER
    </select>

    <!--Oracle数据库指定-->
    <select id="all" databaseId="oracle" resultType="com.xs.dsy.ed.domain.EdSysUser">
         SELECT * FROM ed_sys_user
    </select>

    <!--PostgreSQL数据库指定-->
    <select id="all" databaseId="PostgreSQL" resultType="com.xs.dsy.ed.domain.EdSysUser">
         SELECT * FROM ed_sys_user
    </select>

</mapper>

2.3 控制器接口样例

package com.xs.dsy.ed.controller;

import com.xs.common.core.controller.BaseController;
import com.xs.common.core.domain.PageQuery;
import com.xs.common.core.domain.R;
import com.xs.common.core.page.TableDataInfo;
import com.xs.common.core.validate.AddGroup;
import com.xs.common.core.validate.EditGroup;
import com.xs.dsy.ed.domain.EdSysUser;
import com.xs.dsy.ed.domain.bo.EdSysUserBo;
import com.xs.dsy.ed.domain.vo.EdSysUserVo;
import com.xs.dsy.ed.service.EdSysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.sql.DataSource;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 用户信息-前端控制器
 *
 * @author Lion Li
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user")
public class EdSysUserController extends BaseController {

    private final EdSysUserService userService;

    private final DataSource dataSource;

    /**
     * 查询用户信息列表
     */
    @GetMapping("/queryAll")
    public R<Object> queryAll() throws SQLException {

        //1.0 获取数据源信息
        HashMap<String, Object> map = new HashMap<>();
        Connection connection = dataSource.getConnection();
        DatabaseMetaData metaData = connection.getMetaData();
        map.put("driverName", metaData.getDriverName());
        map.put("driverVersion", metaData.getDriverVersion());
        map.put("databaseProductName", metaData.getDatabaseProductName());
        map.put("databaseProductVersion", metaData.getDatabaseProductVersion());
        
        //2.0 查询数据
        List<EdSysUser> rows = userService.all();
        map.put("rows", rows);


        return R.ok(map);
    }
}

2.4 呈现效果

  • 当项目配置的数据源是不同的数据库时,同一个接口会自动切换查询不同的数据库,从而只需注意部分语法兼容,不影响原有业务逻辑。

在这里插入图片描述

3 基于MP框架Wrapps条件构造器方式

3.1 框架整合

  • SpringBoot+ Mybatis Plus框架整合: https://blog.csdn.net/weixin_44187730/article/details/101620137

  • SpringBoot + MP 多数据源整合: https://blog.csdn.net/weixin_44187730/article/details/103504300

3.2 业务接口实现层

package com.xs.dsy.ed.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xs.common.core.domain.PageQuery;
import com.xs.common.core.page.TableDataInfo;
import com.xs.common.utils.StringUtils;
import com.xs.dsy.ed.domain.EdSysUser;
import com.xs.dsy.ed.domain.bo.EdSysUserBo;
import com.xs.dsy.ed.domain.vo.EdSysUserVo;
import com.xs.dsy.ed.mapper.EdSysUserMapper;
import com.xs.dsy.ed.service.EdSysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 用户 业务层处理
 *
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class EdSysUserServiceImpl implements EdSysUserService {

    private final EdSysUserMapper baseMapper;

    /**
     * 查询用户信息
     */
    @Override
    public EdSysUserVo queryById(Long userId) {
        return baseMapper.selectVoById(userId, EdSysUserVo.class);
    }


    /**
     * 查询用户信息列表
     */
    @Override
    public TableDataInfo<EdSysUserVo> queryPageList(EdSysUserBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EdSysUser> lqw = buildQueryWrapper(bo);
        Page<EdSysUserVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw, EdSysUserVo.class);
        return TableDataInfo.build(result);
    }

    /**
     * 查询用户信息列表
     */
    @Override
    public List<EdSysUserVo> queryList(EdSysUserBo bo) {
        LambdaQueryWrapper<EdSysUser> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw, EdSysUserVo.class);
    }

    private LambdaQueryWrapper<EdSysUser> buildQueryWrapper(EdSysUserBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EdSysUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getDeptId() != null, EdSysUser::getDeptId, bo.getDeptId());
        lqw.like(StringUtils.isNotBlank(bo.getUserName()), EdSysUser::getUserName, bo.getUserName());
        lqw.like(StringUtils.isNotBlank(bo.getNickName()), EdSysUser::getNickName, bo.getNickName());
        lqw.eq(StringUtils.isNotBlank(bo.getUserType()), EdSysUser::getUserType, bo.getUserType());
        lqw.eq(StringUtils.isNotBlank(bo.getEmail()), EdSysUser::getEmail, bo.getEmail());
        lqw.eq(StringUtils.isNotBlank(bo.getPhoneNumber()), EdSysUser::getPhoneNumber, bo.getPhoneNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getSex()), EdSysUser::getSex, bo.getSex());
        lqw.eq(StringUtils.isNoneBlank(bo.getAvatar()), EdSysUser::getAvatar, bo.getAvatar());
        lqw.eq(StringUtils.isNotBlank(bo.getPassword()), EdSysUser::getPassword, bo.getPassword());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), EdSysUser::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getLoginIp()), EdSysUser::getLoginIp, bo.getLoginIp());
        lqw.eq(bo.getLoginDate() != null, EdSysUser::getLoginDate, bo.getLoginDate());
        return lqw;
    }

    /**
     * 新增用户信息
     */
    @Override
    public Boolean insertByBo(EdSysUserBo bo) {
        EdSysUser add = BeanUtil.toBean(bo, EdSysUser.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setUserId(add.getUserId());
        }
        return flag;
    }

    /**
     * 修改用户信息
     */
    @Override
    public Boolean updateByBo(EdSysUserBo bo) {
        EdSysUser update = BeanUtil.toBean(bo, EdSysUser.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(EdSysUser entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除用户信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

}

3.3 控制器层接口

package com.xs.dsy.ed.controller;

import com.xs.common.core.controller.BaseController;
import com.xs.common.core.domain.PageQuery;
import com.xs.common.core.domain.R;
import com.xs.common.core.page.TableDataInfo;
import com.xs.common.core.validate.AddGroup;
import com.xs.common.core.validate.EditGroup;
import com.xs.dsy.ed.domain.EdSysUser;
import com.xs.dsy.ed.domain.bo.EdSysUserBo;
import com.xs.dsy.ed.domain.vo.EdSysUserVo;
import com.xs.dsy.ed.service.EdSysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.sql.DataSource;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 用户信息-前端控制器
 *
 * @author Lion Li
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user")
public class EdSysUserController extends BaseController {

    private final EdSysUserService userService;

    /**
     * 查询用户信息列表
     */
    @GetMapping("/list")
    public TableDataInfo<EdSysUserVo> list(EdSysUserBo bo, PageQuery pageQuery) {
        return userService.queryPageList(bo, pageQuery);
    }


    /**
     * 查询用户信息列表
     */
    @GetMapping("/all")
    public TableDataInfo<EdSysUserVo> all(EdSysUserBo bo, PageQuery pageQuery) {

        return userService.queryPageList(bo, pageQuery);
    }

    /**
     * 获取用户信息详细信息
     *
     * @param userId 主键
     */
    @GetMapping("/{userId}")
    public R<EdSysUserVo> getInfo(@NotNull(message = "主键不能为空")
                                  @PathVariable Long userId) {
        return R.ok(userService.queryById(userId));
    }

    /**
     * 新增用户信息
     */
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody EdSysUserBo bo) {
        return toAjax(userService.insertByBo(bo));
    }

    /**
     * 修改用户信息
     */
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody EdSysUserBo bo) {
        return toAjax(userService.updateByBo(bo));
    }

    /**
     * 删除用户信息
     *
     * @param userIds 主键串
     */
    @DeleteMapping("/{userIds}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] userIds) {

        return toAjax(userService.deleteWithValidByIds(Arrays.asList(userIds), true));
    }

}

3.4 Yaml多数据源配置

--- # 数据源配置
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
    dynamic:
      # 性能分析插件(有性能损耗 不建议生产环境使用)
      p6spy: true
      # 设置默认的数据源或者数据源组,默认值即为 master
      primary: postgres
      # 严格模式 匹配不到数据源则报错
      strict: true
      datasource:
        # 主库数据源
        master:
          type: ${spring.datasource.type}
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://10.15.20.11:13307/ry_vue_db_0322?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
          username: root
          password: OC_sql_11

        # 从库数据源
#        slave:
#          lazy: true
#          type: ${spring.datasource.type}
#          driverClassName: com.mysql.cj.jdbc.Driver
#          url: jdbc:mysql://10.15.20.11:13307/ry_vue_db_0322?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
#          username: root
#          password: OC_sql_11

        oracle:
          type: ${spring.datasource.type}
          driverClassName: oracle.jdbc.OracleDriver
          url: jdbc:oracle:thin:@//127.0.0.1:1521/orcl
          username: SYS as SYSDBA
          password: OC11
          hikari:
            connectionTestQuery: SELECT 1 FROM DUAL


        postgres:
          type: ${spring.datasource.type}
          driverClassName: org.postgresql.Driver
          url: jdbc:postgresql://10.15.20.11:5432/test_db?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
          username: postgres
          password: postgres


#        sqlserver:
#          type: ${spring.datasource.type}
#          driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
#          url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
#          username: SA
#          password: root
      hikari:
        # 最大连接池数量
        maxPoolSize: 20
        # 最小空闲线程数量
        minIdle: 10
        # 配置获取连接等待超时的时间
        connectionTimeout: 30000
        # 校验超时时间
        validationTimeout: 5000
        # 空闲连接存活最大时间,默认10分钟
        idleTimeout: 600000
        # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟
        maxLifetime: 1800000
        # 连接测试query(配置检测连接是否有效)
        connectionTestQuery: SELECT 1
        # 多久检查一次连接的活性
        keepaliveTime: 30000
  redis:
    # 地址
    host: 10.15.20.11
    # 端口,默认为6379
    port: 61379
    # 数据库索引
    database: 0
    # 密码(如没有密码请注释掉)
    # password:
    # 连接超时时间
    timeout: 10s
    # 是否开启ssl
    ssl: false

redisson:
  # redis key前缀
  keyPrefix:
  # 线程池数量
  threads: 4
  # Netty线程池数量
  nettyThreads: 8
  # 单节点配置
  singleServerConfig:
    # 客户端名称
    clientName: ${ruoyi.name}
    # 最小空闲连接数
    connectionMinimumIdleSize: 8
    # 连接池大小
    connectionPoolSize: 32
    # 连接空闲超时,单位:毫秒
    idleConnectionTimeout: 10000
    # 命令等待超时,单位:毫秒
    timeout: 3000
    # 发布和订阅连接池大小
    subscriptionConnectionPoolSize: 50
server:
  servlet:
    context-path: /
  port: 1300

3.5 呈现效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/463106.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AutoGPT也有Web UI了

AutoGPT能够在你的电脑上做任何你想做的事情&#xff0c;并且我们在前面的文章中也介绍了其他的一些类似的应用。 但是AutoGPT最大的一个问题是只能通过命令行界面(CLI)运行&#xff0c;这样就算是专业的技术人员使用起来也很麻烦&#xff0c;想想Stable Diffusion&#xff0c…

关于jeecgboot中遇到的问题及解决方案

1&#xff0c;关于数据权限问题 目的&#xff1a;一个人对应多个部门&#xff0c;部门下可能有子部门&#xff0c;过滤数据权限 解决方案&#xff1a; 方案①&#xff08;不推荐&#xff09;&#xff1a;如果后台是手写的sql&#xff08;没有用到mybatis-plus&#xff09;&…

一文弄懂标识符的规则和instanceof关键字

“世间有吸引法则&#xff0c;在于你有没有价值&#xff0c;价值来于物质资本和精神资本” 标识符的命名规则 标识符的含义&#xff1a;是指在程序中&#xff0c;我们自己定义的内容&#xff0c;例如方法名&#xff0c;变量名或者类名 命名规则&#xff1a;&#xff08;硬性要…

AlgoC++第六课:BP反向传播算法

目录 BP反向传播算法前言1. MNIST2. 感知机2.1 前言2.2 感知机-矩阵表示2.3 感知机-矩阵表示-多个样本2.4 感知机-增加偏置2.5 感知机-多个输出2.6 总结2.7 关于广播 3. BP4. 动量SGD5. BP示例代码总结 BP反向传播算法 前言 手写AI推出的全新面向AI算法的C课程 Algo C&#xf…

PHP、一:概述

1.概念 2.wampsever安装 百度搜索直接下载 下图是解压后目录&#xff0c;所写文件必须写在www文件夹下。 例&#xff1a;www文件夹下新建1.php&#xff0c;phpinfo()查看当前版本等信息。 使用localhost访问 php版本切换&#xff1a; 鼠标左键点击wampserver&#xff0c;切…

git rebase

git rebase rebase 是一个……我觉得很麻烦的指令&#xff0c;不过没办法&#xff0c;公司算是有个软规定必须要使用 rebase。 rebase 的功能和 merge 很像&#xff0c;不过它能够保持一个相对干净的历史&#xff0c;继续举个例子&#xff0c;假设现在有一个新的功能开发好了…

Golang Gin HTTP 请求和参数解析

gin 网络请求与路由处理 我们介绍了Gin框架&#xff0c;并做了Gin框架的安装&#xff0c;完成了第一个Gin工程的创建。 创建Engine 在gin框架中&#xff0c;Engine被定义成为一个结构体&#xff0c;Engine代表gin框架的一个结构体定义&#xff0c;其中包含了路由组、中间件、…

26- OCR 基于PP-OCRv3的液晶屏读数识别

要点&#xff1a; 液晶屏识别示例github 地址 1. 简介 本项目基于PaddleOCR开源套件&#xff0c;以PP-OCRv3检测和识别模型为基础&#xff0c;针对液晶屏读数识别场景进行优化。主要是针对各种仪表进行识别&#xff1a; 2 安装环境 安装Git&#xff1a;Git 详细安装教程 # 首…

YOLOv8 Bug及解决方案汇总

Traceback (most recent call last): File “D:\Anaconda\Scripts\yolo-script.py”, line 33, in sys.exit(load_entry_point(‘ultralytics==8.0.83’, ‘console_scripts’, ‘yolo’)()) self.model, self.save = parse_model(deepcopy(self.yaml), ch=ch, verbose=verbos…

基于 Python 的 Meta AI —— SAM

Segment Anything Model&#xff08;SAM&#xff09;是 Facebook 的一个 AI 模型&#xff0c;旨在推广分割技术。在我们之前的文章中&#xff0c;我们讨论了 SAM 的一般信息&#xff0c;现在让我们深入了解其技术细节。SAM 模型的结构如下图所示&#xff0c;图像经过编码器得到…

【致敬未来的攻城狮计划】— 连续打卡第十三天:FSP固件库开发启动文件详解

系列文章目录 1.连续打卡第一天&#xff1a;提前对CPK_RA2E1是瑞萨RA系列开发板的初体验&#xff0c;了解一下 2.开发环境的选择和调试&#xff08;从零开始&#xff0c;加油&#xff09; 3.欲速则不达&#xff0c;今天是对RA2E1 基础知识的补充学习。 4.e2 studio 使用教程 5.…

《Spring MVC》 第八章 拦截器实现权限验证、异常处理

前言 Spring 提供了Interceptor 拦截器&#xff0c;可用于实现权限验证、异常处理等 1、拦截器 对用户请求进行拦截&#xff0c;并在请求进入控制器&#xff08;Controller&#xff09;之前、控制器处理完请求后、甚至是渲染视图后&#xff0c;执行一些指定的操作 1.1、定义…

UGUI中点击判断的原理

首选需要理解 EventSystem 中的代码结构&#xff0c;EventSystem 目录下包含4个子文件夹&#xff0c;分别是 EventData、InputModules&#xff0c;Raycasters 和 UIElements&#xff0c;UIElements 下是 UI Toolkit 相关代码&#xff0c;这里不做研究&#xff0c;主要关注其他三…

linux文件及文件内容查找命令总结

在linux环境下&#xff0c;我们经常要查找一个文件或者文件的内容&#xff0c;但搜索的命令有很多&#xff0c;这些命令都有什么区别&#xff0c;应该怎么选择和使用呢&#xff1f; 下面总结了一些常见的文件查找、内容查找的命令&#xff0c;收藏起来备用吧。 文件查找 where…

每日学术速递4.25

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Long-Term Photometric Consistent Novel View Synthesis with Diffusion Models 标题&#xff1a;具有扩散模型的长期光度一致的新视图合成 作者&#xff1a;Jason J. Yu, Feresh…

Python入门教程+项目实战-11.3节: 元组的操作方法

目录 11.3.1 元组的常用操作方法 11.3.2 元组的查找 11.3.3 知识要点 11.3.4 系统学习python 11.3.1 元组的常用操作方法 元组类型是一种抽象数据类型&#xff0c;抽象数据类型定义了数据类型的操作方法&#xff0c;在本节的内容中&#xff0c;着重介绍元组类型的操作方法…

hive udf, tried to access method org.bouncycastle.math.ec.ECPoint$AbstractFp

在hive中添加加密udf,测试报错&#xff1a; select encrypt_sm2("aa","04AD9356466C7A505B3B2E18F2484E1F096108FA19C0F61C707A808EDF7C132BC3CE33E63D2CC6D77FB0A172004F8F5282CEADE22ED9628A02FE8FD85AF1EFE8B3"); Error: Error while compiling statem…

从0搭建Vue3组件库(九):VitePress 搭建部署组件库文档

VitePress 搭建组件库文档 当我们组件库完成的时候,一个详细的使用文档是必不可少的。本篇文章将介绍如何使用 VitePress 快速搭建一个组件库文档站点并部署到GitHub上 安装 首先新建 site 文件夹,并执行pnpm init,然后安装vitepress和vue pnpm install -D vitepress vue安…

什么是分库分表?为什么需要分表?什么时候分库分表

不急于上手实战 ShardingSphere 框架&#xff0c;先来复习下分库分表的基础概念&#xff0c;技术名词大多晦涩难懂&#xff0c;不要死记硬背理解最重要&#xff0c;当你捅破那层窗户纸&#xff0c;发现其实它也就那么回事。 什么是分库分表 分库分表是在海量数据下&#xff0…

“星河杯”隐私计算大赛新闻发布会在京召开

4月24日下午&#xff0c;“星河杯”隐私计算大赛新闻发布会在京召开。本次大赛由中国信通院、中国通信学会、隐私计算联盟共同主办&#xff0c;中移动信息技术有限公司、联通数字科技有限公司、天翼电子商务有限公司、中国通信标准化协会大数据技术标准推进委员会联合协办&…