数据源管理|JDBC|JdbcTemplate|MybatisPlusGenerator

个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview


复杂的项目常常会涉及到多数据源的配置,解决方案也是有很多。但这篇文章不是讲这个的,而是纯粹的数据源管理,通过数据源配置,获取数据库信息、表信息、数据等等,更像是超级简单的数据库管理工具(DbeaverNavicat等)。

这个有什么应用呢?

1、一些后台类系统常需要查数功能,这个就可以用到。有人问了我们有DbeaverNavicat还需要这个?确实,有专业的数据库管理工具,这个就显得非常鸡肋了。但是数据库通常是由专业的DBA管理的,账号和权限都是受管控的,而且数据库账号通常无法和后台类系统用户权限关联,所以这个就显得有点用处了。

2、作为外部数据源,有时候系统本身的数据不够用,或者说是有局限性,希望能够接上外部更加丰富数据,这时也是可以应用的。

3、代码生成器

4、等

数据库信息

因为JDBC,数据源的配置包含jdbcUrlusernamepassworddriverClassName就可以建立数据库的连接了。

数据库类型

数据库类型从jdbcUrl就能确认,可以参考mybatis-plus-generatorcom.baomidou.mybatisplus.generator.config;中的DataSourceConfig#getDbType方法。

private DbType getDbType(@NotNull String str) {
    if (str.contains(":mysql:") || str.contains(":cobar:")) {
        return DbType.MYSQL;
    } else if (str.contains(":oracle:")) {
        return DbType.ORACLE;
    } else if (str.contains(":postgresql:")) {
        return DbType.POSTGRE_SQL;
    } else if (str.contains(":sqlserver:")) {
        return DbType.SQL_SERVER;
    } else if (str.contains(":db2:")) {
        return DbType.DB2;
    } else if (str.contains(":mariadb:")) {
        return DbType.MARIADB;
    } else if (str.contains(":sqlite:")) {
        return DbType.SQLITE;
    } else if (str.contains(":h2:")) {
        return DbType.H2;
    } else if (str.contains(":kingbase:") || str.contains(":kingbase8:")) {
        return DbType.KINGBASE_ES;
    } else if (str.contains(":dm:")) {
        return DbType.DM;
    } else if (str.contains(":zenith:")) {
        return DbType.GAUSS;
    } else if (str.contains(":oscar:")) {
        return DbType.OSCAR;
    } else if (str.contains(":firebird:")) {
        return DbType.FIREBIRD;
    } else if (str.contains(":xugu:")) {
        return DbType.XU_GU;
    } else if (str.contains(":clickhouse:")) {
        return DbType.CLICK_HOUSE;
    } else if (str.contains(":sybase:")) {
        return DbType.SYBASE;
    } else {
        return DbType.OTHER;
    }
}

数据库默认库

数据库本身自带有默认的数据库,常用的MySQLmysqlinformation_schema等基础库。数据库的默认库也可以参考DataSourceConfig#getDefaultSchema方法。

数据库s

因为数据库SQL语句有差异,所以并非所有SQL都是MySQLSHOW DATABASES;

以下是针对一些常见数据库系统的 SQL 查询所有数据库的示例:

  1. MySQL:
SHOW DATABASES;
  1. PostgreSQL:
SELECT datname FROM pg_database WHERE datistemplate = false;
  1. SQL Server:
SELECT name FROM sys.databases;
  1. Oracle:
SELECT username FROM all_users;
  1. SQLite:
.databases
  1. DB2:
SELECT dbname FROM sysibm.sysdummy1;

这些 SQL 查询语句可以在相应的数据库管理系统中执行,以获取所有数据库的列表或名称。需要注意的是,每个数据库系统的系统表或系统视图可能不同,因此查询方式会有所不同。

更多可以chatGPT一下,重写一下不同实现在使用时会更方便。

表信息

在已有数据源配置和数据库信息后,表信息当然也是很轻易就能获取。

表s

mybatis-plus-generatorcom.baomidou.mybatisplus.generator.config;中的IDbQuery#tablesSql接口针对不同库有不同实现,可以使用。如下代码就可以查询出所有数据源中一个库的所有表信息。

HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(dbConfig.getFullJdbcUrl());
ds.setUsername(dbConfig.getUsername());
ds.setPassword(dbConfig.getPassword());
ds.setDriverClassName(dbConfig.getDriverClassName());
JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);

DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(dbConfig.getJdbcUrl(), dbConfig.getUsername(), dbConfig.getPassword()).build();
IDbQuery dbQuery = dataSourceConfig.getDbQuery();
List<Map<String, Object>> results = jdbcTemplate.queryForList(dbQuery.tablesSql());
List<TableInfo> tableInfos = Lists.newArrayList();
for (Map<String, Object> table : results) {
    TableInfo tableInfo = new TableInfo();
    tableInfo.setName((String) table.get(dbQuery.tableName()));
    tableInfo.setComment((String) table.get(dbQuery.tableComment()));
    tableInfos.add(tableInfo);
}

表结构信息

方法1

JDBC 中,DatabaseMetaData.getColumns() 方法返回的 ResultSet 包含了表的列信息,其中列名可以作为参数传递给 ResultSet.getString() 方法。除了 COLUMN_NAME 字符串外,还有一些其他的字符串可以用来获取不同的列信息。以下是一些常用的列信息对应的字符串:

  1. COLUMN_NAME:列名
  2. TYPE_NAME:列的数据类型名称
  3. COLUMN_SIZE:列的大小(长度)
  4. NULLABLE:列是否允许为空,返回值为 ResultSetMetaData.columnNoNullsResultSetMetaData.columnNullableResultSetMetaData.columnNullableUnknown 之一
  5. REMARKS:列的注释(备注)
  6. IS_AUTOINCREMENT:列是否是自动增长的,返回值为 “YES” 或 “NO
  7. IS_GENERATEDCOLUMN:列是否是生成的列(自动生成的),返回值为 “YES” 或 “NO
  8. COLUMN_DEF:列的默认值

这些字符串可以作为 ResultSetgetXXX() 方法的参数,用于获取相应的列信息。例如,ResultSet.getString("COLUMN_NAME") 获取列名,ResultSet.getString("TYPE_NAME") 获取列的数据类型名称,以此类推。

ResultSet columnsResultSet = metaData.getColumns(null, null, tableName, null);
while (columnsResultSet.next()) {
    String columnName = columnsResultSet.getString("COLUMN_NAME");
    String columnType = columnsResultSet.getString("TYPE_NAME");
    String columnComment = columnsResultSet.getString("REMARKS");

    System.out.println("Column Name: " + columnName);
    System.out.println("Column Type: " + columnType);
    System.out.println("Column Comment: " + columnComment);
    System.out.println();
}

方法2

好吧,又是它mybatis-plus-generatorcom.baomidou.mybatisplus.generator.config;中的IDbQuery#tableFieldsSql可以确认数据库表结构,而且有不同实现,用起来更方便。

不确定表结构情况下查询数据

以下仅作参考

public class Main {

    private static final DataSource dataSource;

    private static final ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    private static final String SQL_QUERY = "SELECT * FROM {}";

    static {
        try {
            HikariConfig hikariConfig = new HikariConfig();
            hikariConfig.setJdbcUrl("jdbc:mysql://158.1.18.149:3306/carbon");
            hikariConfig.setUsername("root");
            hikariConfig.setPassword("hzbank");
            hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource = new HikariDataSource(hikariConfig);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public static Connection getConnection() {
        try {
            Connection connection = threadLocal.get();
            if (connection == null) {
                connection = dataSource.getConnection();
                threadLocal.set(connection);
            }
            return connection;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public static void close() {
        try {
            Connection connection = threadLocal.get();
            if (connection != null) {
                threadLocal.remove();
                connection.setAutoCommit(true);
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws SQLException {
        Connection connection = getConnection();

        String totalCreditsQuery = StrUtil.format(SQL_QUERY, "total_credits");

        PreparedStatement preparedStatement = connection.prepareStatement(totalCreditsQuery);
        ResultSet resultSet = preparedStatement.executeQuery();

        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();

        for (int i = 1; i <= columnCount; i++) {
            String columnName = metaData.getColumnName(i);
            System.out.print(columnName + "\t");
        }
        System.out.println();

        while (resultSet.next()) {
            for (int i = 1; i <= columnCount; i++) {
                System.out.print(resultSet.getString(i) + "\t");
            }
            System.out.println();
        }

        close();
    }
}

表数据/索引容量

SELECT
	table_schema AS '数据库',
	table_name AS '表名',
	table_rows AS '记录数',
	TRUNCATE ( data_length / 1024 / 1024, 2 ) AS '数据容量(MB)',
	TRUNCATE ( index_length / 1024 / 1024, 2 ) AS '索引容量(MB)' 
FROM
	information_schema.TABLES 
ORDER BY
	data_length DESC,
	index_length DESC;

直到我看到这条sql,并去看information_schema.TABLES ,才知道数据库自带的库是有多么重要!

写在最后

拙作艰辛,字句心血,望诸君垂青,多予支持,不胜感激。


个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

el-table 实现嵌套表格的思路及完整功能代码

要实现的需求是这样的&#xff1a; 本来我是用 el-table 的 :span-method 方法实现的&#xff0c;但发现合并起来有问题&#xff0c;跟我的需求差距有些大&#xff0c;于是我想到了嵌套表格。但是嵌套完之后的样子也是很奇怪&#xff1a; 不要气馁&#xff0c;思路还是对的&a…

MacOS使用PhpStorm+Xdebug断点调式

基本环境&#xff1a; MacOS m1 PhpStorm 2024.1 PHP7.4.33 Xdebug v3.1.6 1、php.ini 配置 [xdebug] zend_extension "/opt/homebrew/Cellar/php7.4/7.4.33_6/pecl/20190902/xdebug.so" xdebug.idekey "PHPSTORM" xdebug.c…

SpringBoot集成Logback将日志写入文件夹

一、logback简介&#xff1a; 目前比较常用的ava日志框架:Logback、log4j、log4j2、JUL等等。 Logback是在log4j的基础上重新开发的一套日志框架&#xff0c;是完全实现SLF4J接口API(也叫日志门面)。 Logback 的架构非常通用&#xff0c;可以应用于不同的环境。目前logback分为…

【人工智能项目】小车障碍物识别与模型训练(完整工程资料源码)

实物演示效果: 一、绪论: 1.1 设计背景 小车障碍物识别与模型训练的设计背景通常涉及以下几个方面: 随着自动驾驶技术的发展,小车(如无人驾驶汽车、机器人等)需要能够在复杂的环境中自主导航。障碍物识别是实现这一目标的关键技术之一,它允许小车检测并避开路上的障碍物…

C++-函数

函数&#xff08;Function&#xff09;&#xff1a;是一个提前封装好的、可重复使用的、完成特定功能的独立代码单元。 特点&#xff1a;提前封装、可重复使用的、完成特定功能 将针对特定功能的、有重复使用需求的代码&#xff0c;提前封装到函数内&#xff0c; 在需要的时候…

IEN在Web3.0中的性能与安全优势

随着Web3.0的快速发展&#xff0c;优化网络基础设施变得至关重要。智能生态网络&#xff08;Intelligent Ecological Network, IEN&#xff09;作为新一代网络架构&#xff0c;在提升性能与增强安全方面展现出巨大潜力。本文将深入探讨IEN在Web3.0中的技术优势&#xff0c;并展…

Qt输入输出类使用总结

Qt输入输出类简介 QTextStream 类(文本流)和 QDataStream 类(数据流)Qt 输入输出的两个核心类,其作用分别如下: QTextStream 类:用于对数据进行文本格式的读/写操作,可在 QString、QIODevice或 QByteArray 上运行,比如把数据输出到 QString、QIODevice 或 QByteArray 对象…

JS、Go、Rust 错误处理的不同 - JS 可以不用 Try/Catch 吗?

原文&#xff1a;Mateusz Piorowski - 2023.07.24 先来了解一下我的背景吧。我是一名软件开发人员&#xff0c;有大约十年的工作经验&#xff0c;最初使用 PHP&#xff0c;后来逐渐转向 JavaScript。 大约五年前&#xff0c;我开始使用 TypeScript&#xff0c;从那时起&#…

Go微服务——go-micro v4安装使用

安装go-micro 打开cmd窗口&#xff0c;执行以下命令 go install github.com/go-micro/cli/cmd/go-microlatest测试是否成功安装 go-micro -v创建服务 go-micro new service helloworldwindows 安装make 安装地址 https://gnuwin32.sourceforge.net/packages/make.htm 配置…

python从0开始学习(九)

前言 上一篇文章我们介绍了python中的序列类型和元组类型&#xff0c;本篇文章将接着往下将。 1、字典类型 字典类型是根据一个信息查找另一个信息的方式所构成的“键值对”&#xff0c;它表示索引用的键和对应的值构成的成对关系。它是一个可变数据类型&#xff0c;也就是说它…

JAVA基础知识100题练习、蓝桥杯竞赛题,编程基础必练题!

各位编程小伙伴们&#xff0c;这里可是作者花费了无数个日日夜夜&#xff0c;熬秃了不知道多少根头发&#xff0c;凭借着那超级无敌多年的编程经验&#xff0c;拼死拼活、千辛万苦总结出来的呀&#xff01;这可是各种开发语言都绝对必须要练的基础编程知识哇&#xff01;什么九…

jenkins自动化部署详解

一、准备相关软件 整个自动化部署的过程就是从git仓库拉取最新代码&#xff0c;然后使用maven进行构建代码&#xff0c;构建包构建好了之后&#xff0c;通过ssh发送到发布服务的linux服务器的目录&#xff0c;最后在此服务器上执行相关的linux命令进行发布。 此篇文章jenkins…

Linux gurb2简介

文章目录 前言一、GRUB 2简介二、GRUB 2相关文件/文件夹2.1 /etc/default/grub文件2.2 /etc/grub.d/文件夹2.3 /boot/grub/grub.cfg文件 三、grubx64.efi参考资料 前言 简单来说&#xff0c;引导加载程序&#xff08;boot loader&#xff09;是计算机启动时运行的第一个软件程…

262 基于matlab的一级倒立摆仿真

基于matlab的一级倒立摆仿真&#xff0c;在对一级倒立摆进行数学建模的基础上&#xff0c;对模型进行线性化&#xff0c;得到其状态空间模型&#xff0c;利用二次型最优控制方法得出控制率。输出角度和位置优化曲线。程序已调通&#xff0c;可直接运行。 262 一级倒立摆仿真 状…

Sui生态DeFi项目Cetus和Aftermath宣布启动孵化器

Sui DeFi中的去中心化交易所Cetus和Aftermath Finance联合Sui基金会宣布启动新的孵化器&#xff0c;为初创项目提供更多可行性途径。这两个DeFi项目在Sui上有着较长的历史&#xff0c;自去年一同与主网推出以来&#xff0c;目前在TVL方面位居前五。这两个项目的持久性和成功使它…

构建品牌长期价值:海外KOC营销的持续性策略解析

在当今数字化时代&#xff0c;随着社交媒体的兴起&#xff0c;消费者对于品牌的信任和认可越来越依赖于个人的推荐和体验。因此&#xff0c;KOC营销成为了品牌推广中的重要策略之一。但是&#xff0c;要想构建品牌的长期价值&#xff0c;单纯地依靠一次性的KOC合作是远远不够的…

【云原生】K8s管理工具--Kubectl详解(一)

一、陈述式管理 1.1、陈述式资源管理方法 kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口kubectl 是官方的 CLI 命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为apiserver 能识…

深度学习之基于Matlab的BP神经网络交通标志识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 随着智能交通系统&#xff08;ITS&#xff09;的快速发展&#xff0c;交通标志识别&#xff0…

十年磨一剑“2024成都电子信息展会”推动电子产业全球发展

2024成都电子展&#xff0c;招商工作已接近尾声&#xff0c;这场盛大的展会不仅是电子信息行业的一次盛会&#xff0c;更是中国西部电子信息产业发展的重要里程碑。自2013年起&#xff0c;中国&#xff08;西部&#xff09;电子信息博览会便选择成都作为其永久的举办地&#xf…

【誉天618·年中钜惠】无忧卡计算VIP会员上线

在数字化浪潮汹涌的当下&#xff0c;技术更新迭代的速度令人目不暇接。为了满足广大技术爱好者与专业人士对于最新技术的渴望与追求。2022年我们推出了誉天系列会员卡&#xff0c;受到了学员和企业的一致好评&#xff0c;现在我们又结合当下的热门ICT技术进行了会员卡升级。 誉…