报表系统-连接数据库操作
本专栏用于解析自己开源的项目代码,作为复盘和学习使用。欢迎大家一起交流
本样例说明源码开源在:
ruoyi-reoprt gitee仓库
ruoyi-report github仓库
欢迎大家到到项目中多给点star支持,对项目有建议或者有想要了解的欢迎一起讨论
连接数据库这一模块整体参考的是AJ-report的模块:去掉了目前不支持的数据库格式,仅保留了mysql和sqlserver
https://gitee.com/anji-plus/report
1. 存储数据库连接
1.1 数据库连接表单设计
create table cwu_data_source
(source_code varchar(100) null comment '数据源编码',source_name varchar(100) null comment '数据源名称',source_desc varchar(255) null comment '数据源描述',source_type varchar(50) null comment '数据源类型 DIC_NAME=SOURCE_TYPE; mysql,orace,sqlserver,elasticsearch,接口,javaBean,数据源类型字典中item-extend动态生成表单',source_config varchar(2048) null comment '数据源连接配置json:关系库{ jdbcUrl:'''', username:'''', password:'''' } ES{ hostList:''ip1:9300,ip2:9300,ip3:9300'', clusterName:''elasticsearch_cluster'' } 接口{ apiUrl:''http://ip:port/url'', method:'''' } javaBean{ beanNamw:''xxx'' }',enable_flag int default 1 null comment '0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG',id int auto_incrementprimary key,create_time bigint null comment '创建时间',update_time bigint null comment '更新时间',update_user bigint null comment '更新者id',create_user bigint null comment '创建者id',create_org bigint null comment '创建的组织id',update_org bigint null comment '更新的组织id',is_delete int default 0 null comment '1删除0有效',version int null,constraint unique_source_codeunique (source_code)
)comment '数据源管理' charset = utf8row_format = DYNAMIC;
1.2 测试连接配置是否能连接成功
在写入存储阶段先进行一次测试连接,给用户及时反馈配置是否正确。
使用Hikari进行数据库连接,获取到一个连接,判断是否能正常获取到
// 传入连接所需的参数
public class DataSourceDto extends BaseClass implements Serializable {/** 数据源编码 */private String sourceCode;/** 数据源名称 */private String sourceName;/** 数据源描述 */private String sourceDesc;/** 数据源类型 DIC_NAME=SOURCE_TYPE; mysql,orace,sqlserver,elasticsearch,接口,javaBean,数据源类型字典中item-extend动态生成表单 */private String sourceType;/** 数据源连接配置json:关系库{ jdbcUrl:'', username:'', password:'','driverName':''}ES-sql{ apiUrl:'http://127.0.0.1:9092/_xpack/sql?format=json','method':'POST','body':'{"query":"select 1"}' } 接口{ apiUrl:'http://ip:port/url', method:'' } javaBean{ beanNamw:'xxx' } */private String sourceConfig;/** 0--已禁用 1--已启用 DIC_NAME=ENABLE_FLAG */private Integer enableFlag;/** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */private Integer deleteFlag;/**************************************************************//**关系型数据库jdbcUrl */private String jdbcUrl;/** 关系型数据库用户名 */private String username;/** 关系型数据库密码 */private String password;/** 关系型数据库驱动类 */private String driverName;/** 关系型数据库sql */private String sql;/** http requestUrl */private String apiUrl;/** http method */private String method;/** http header */private String header;/** http 请求体 */private String body;/** 动态查询sql或者接口中的请求体 */private String dynSentence;/** 传入的自定义参数,解决url中存在的动态参数*/private Map<String, Object> contextData;}public HikariPool getJdbcConnectionPool(DataSourceDto dataSource) {if (map.containsKey(dataSource.getId())) {return map.get(dataSource.getId());} else {try {synchronized (lock) {if (!map.containsKey(dataSource.getId())) {HikariPool pool = hikariPoolProperties.dataSource(dataSource.getJdbcUrl(),dataSource.getUsername(), dataSource.getPassword(), dataSource.getDriverName());map.put(dataSource.getId(), pool);log.info("创建连接池成功:{}", dataSource.getJdbcUrl());}}return map.get(dataSource.getId());} finally {}}}
2. 执行查询语句
目前能执行的数据库都是关系型数据库,所以直接执行到对应的方法中,先从连接池中根据数据库id取出对应的连接,如果没有的话新建一个。然后执行对应的sql语句.
查询结果用
List<Map<String,Object>>
的结构返回,list中的一个元素表示一行的值,map中的key,value为数据库中对应的字段和值
public List<Map<String,Object>> executeRelationalDb(DataSourceDto dto) {analysisRelationalDbConfig(dto);Connection pooledConnection = null;try {pooledConnection = jdbcService.getPooledConnection(dto);PreparedStatement statement = pooledConnection.prepareStatement(dto.getDynSentence());ResultSet rs = statement.executeQuery();int columnCount = rs.getMetaData().getColumnCount();List<String> columns = new ArrayList<>();for (int i = 1; i <= columnCount; i++) {String columnName = rs.getMetaData().getColumnLabel(i);columns.add(columnName);}List<Map<String,Object>> list = new ArrayList<>();while (rs.next()) {Map<String,Object> jo = new HashMap<>();columns.forEach(t -> {try {Object value = rs.getObject(t);//数据类型转换Object result = dealResult(value);jo.put(t, result);} catch (SQLException throwable) {log.error("error",throwable);throw new GlobalException(ResponseCode.EXECUTE_SQL_ERROR, throwable.getMessage());}});list.add(jo);}return list;} catch (Exception throwable) {log.error("error",throwable);throw new GlobalException(ResponseCode.EXECUTE_SQL_ERROR, throwable.getMessage());} finally {try {if (pooledConnection != null) {pooledConnection.close();}} catch (SQLException throwable) {log.error("error",throwable);throw new GlobalException(ResponseCode.DATA_SOURCE_CONNECTION_FAILED, throwable.getMessage());}}}
3. 获取数据库中的表和字段结构
对于mysql和sqlserver来说,传入表名字,获取表中的字段结构的sql语句存在不同,所以需要分别处理,执行拿到的数据结构统一格式返回
// 传入表名和数据库id,返回对应的表字段数据,包括字段名、类型、备注
public List<Map> getTableFile(String tableName,Integer dataSourceId) {DataSource dataSource = dataSourceService.getById(dataSourceId);List<Map<String,Object>> list = dataSourceService.execute(getSqlByType(dataSource.getSourceType(),tableName),dataSourceId);List<Map> mapList = new ArrayList<>();for (Map<String,Object> map : list) {Map<String,Object> map1 = new HashMap<>();map1.put("field",map.get("Field"));map1.put("type",map.get("Type"));if(map.get("Comment") != null && !map.get("Comment").equals("")){map1.put("comment",map.get("Comment"));}else {map1.put("comment",map.get("Field"));}mapList.add(map1);}return mapList;}
// 根据不同的类型返回不同的sql执行语句
private String getSqlByType(String type,String tableName){switch (type) {case JdbcConstants.MYSQL:return "show full fields from " + tableName; case JdbcConstants.SQL_SERVER:return "SELECT \n" +" c.name AS Field,\n" +" ty.name AS Type,\n" +" c.is_nullable,\n" +" ep.value AS Comment\n" +"FROM \n" +" sys.columns c\n" +" INNER JOIN sys.types ty ON c.user_type_id = ty.user_type_id\n" +" INNER JOIN sys.tables t ON c.object_id = t.object_id\n" +" LEFT JOIN sys.extended_properties ep ON c.object_id = ep.major_id \n" +" AND c.column_id = ep.minor_id \n" +" AND ep.name = 'MS_Description'\n" +" AND ep.class = 1\n" +"WHERE \n" +" t.name = '" + tableName + "'\n" +" AND ty.is_user_defined = 0; ";default:throw new RuntimeException("不支持该类型");}}
4. 对应系统功能展示
相关文章:
报表系统-连接数据库操作
本专栏用于解析自己开源的项目代码,作为复盘和学习使用。欢迎大家一起交流 本样例说明源码开源在: ruoyi-reoprt gitee仓库 ruoyi-report github仓库 欢迎大家到到项目中多给点star支持,对项目有建议或者有想要了解的欢迎一起讨论 连接数据库…...
[计算机网络] 常见端口号
前言 常见的端口号是指互联网协议(如TCP/IP)中预留给特定服务使用的数字范围。它们主要用于标识网络应用程序和服务,并帮助数据包在网络中找到正确的接收方。 按协议类型划分 TCP协议端口: 21:FTP文件传输协议2…...
Linux系统块存储子系统分析记录
1 Linux存储栈 通过网址Linux Storage Stack Diagram - Thomas-Krenn-Wiki-en,可以获取多个linux内核版本下的存储栈概略图,下面是kernel-4.0的存储栈概略图: 2 存储接口、传输速度 和 协议 2.1 硬盘 《深入浅出SSD:固态存储核心…...
大数据——本地威胁检测的全球方法
大数据似乎是众多专业人士关注的话题,从在自然灾害发生时帮助挽救生命,到帮助营销团队设计更有针对性的策略以接触新客户。 对于安全工程师来说,大数据分析被证明是抵御不断演变的网络入侵的有效防御手段,这得益于基于大量不同网…...
使用postman接口测试
一 、postman断言 1、什么是断言 postman 断言借助JavaScript -js 语言编写代码,自动判断预期结果与实际结果是否一致。 断言代码写在 Tests 的标签中。(新版本在Scripts标签中) 2、断言工作原理 3、常用断言 断言响应状态码 // 断言响应状态码 是否为 200 pm.…...
Ubuntu24.04双系统安装(Linux/windows共存一文打通)
他向远方望去,无法看到高山背后的矮山,只能看到一座座更高的山峰。 目录 编辑 一.前言 二.虚拟机和双系统比较 三.Windows/Linux双系统安装 1.Rufus-制作U盘启动盘系统工具安装 2.Ubuntu24.04下载 3.Ubuntu-u盘启动盘制作 4.压缩磁盘留足安装空…...
C++ - deque
博客主页:【夜泉_ly】 本文专栏:【C】 欢迎点赞👍收藏⭐关注❤️ 文章目录 💡双端队列简介1. 基本特性2. 与其他容器的比较与 vector与 list 3. 中控数组的设计4. 优缺点优点缺点 5. 应用场景6. 结论 💡双端队列简…...
国产!瑞芯微米尔RK357核心板革新AIoT设备,8核6T高算力
随着科技的快速发展,AIoT智能终端对嵌入式模块的末端计算能力、数据处理能力等要求日益提高。近日,米尔电子发布了一款基于瑞芯微RK3576核心板和开发板。核心板提供4GB/8GB LPDDR4X、32GB/64GB eMMC等多个型号供选择。瑞芯微RK3576核心优势主要包括高性能…...
中国人寿财险青岛市分公司践行绿色金融,助力可持续发展
中国人寿财险青岛市分公司积极响应国家绿色发展战略,大力推进绿色金融实践。在保险产品创新方面,推出一系列绿色保险产品。如新能源汽车保险,为新能源汽车产业发展提供风险保障,促进交通领域的节能减排。环境污染责任保险则助力企…...
ajax 读取文件
DOMException: Failed to read the responseXML property from XMLHttpRequest: The value is only accessible if the objects responseType is or document (was blob). at XMLHttpRequest.r ( $.ajax({ url: 未来之窗_服务, method: GET, …...
火语言RPA流程组件介绍--开始监听网络请求
🚩【组件功能】:开始监听内置浏览器网络请求(提示:本组件仅适用于火语言内置浏览器) 配置预览 配置说明 匹配网址 可以添加一个或者多个匹配规则用于筛选需要保存的网络请求. 输入输出 输入类型 万能对象类型(Sy…...
CSS综合案例——新闻详情
一、知识点 1、文字颜色 属性名:color 属性值: 颜色表示方式属性值说明使用场景颜色关键字颜色英文单词red,green,blue学习测试rgb表示法rg(r,g,b)r,g,b表示红绿蓝三原色,取值0-255了解rgba表示法rgba(r,g,b,a)a表示透明度,取…...
【【自动驾驶】车辆运动学模型】
【自动驾驶】车辆运动学模型 1. 引言2. 以车辆重心为中心的单车模型2.1 模型介绍2.2 滑移角 β \beta β 的推导2.2 航向角 ψ \psi ψ推导过程:2.3 滑移角 β \beta β2.3 Python代码实现2.4 C代码实现 3. 前轮驱动的单车模型3.1 模型介绍3.3 Python代码实现3.4 …...
叉尖避障新科技:因泰立科技ILS-T52三维深度成像激光雷达
ILS-T52三维深度成像激光雷达是一款高性能的纯固态式激光雷达,采用激光时间飞行法,提供出色的三维图像成像和深度感知功能。特别适用于无人叉车领域,为叉尖避障提供卓越的三维成像和深度感知功能。它的高精度、自适应自动曝光、小尺寸、低功耗…...
精华帖分享 | 低估值还能涨多久?
本文来源于量化小论坛策略分享会板块精华帖,作者为亮子,发布于2024年3月19日。 这两年,A股给我们的感觉就是成长股坍塌,高股息低估值的股票扛起大旗。表现出来就是中国神华、中海油这样的垄断型央国企大涨,包括移动联通…...
如何制作一个自己的网站?
在今天的互联网时代,网站展示已经是一个很基础的营销工具。不管是企业、还是个人,如何制作一个自己的网站?本文将会提供一个全面的基础制作网页教程,教你如何从零开始制作网页。 网页制作的基础知识:HTML、CSS和JavaS…...
torch报错
The Kernel crashed while executing code in the current cell or a previous cell. Please review the code in the cell(s) to identify a possible cause of the failure. Click here for more info. View Jupyter log for further details. 从日志中可以看出,内…...
深入探索卷积神经网络(CNN):图像分类的利器
深入探索卷积神经网络(CNN):图像分类的利器 前言CNN的崛起:为何我们需要它?图像卷积:CNN的基石轮廓过滤器:捕捉边缘特征 图像池化:降低维度的利器CNN的组成:卷积层、池化…...
网站建设中需要注意哪些安全问题?----雷池社区版
服务器与应用安全指南 1. 服务器安全 1.1 操作系统安全 及时更新补丁:确保操作系统始终安装最新补丁,以防范系统漏洞。例如,Windows Server 定期推送安全更新,修复如远程代码执行等潜在威胁。优化系统服务配置:关闭不…...
光控资本:养老金融建设提速 高速铜缆市场空间广阔
养老金融制作提速 金融监管总局办公厅近来印发的《关于大力展开商业保险年金有关事项的奉告》(下称《奉告》)提出,进一步扩大商业养老金业务试点;开发习惯个人养老金准则的新产品和专属产品;保险公司要坚持长期出资、…...
部署前后端分离若依项目--CentOS7宝塔版
准备: CentOS7服务器一台 通过网盘分享的文件:CentOS 7 h 链接: https://pan.baidu.com/s/17DF8eRSSDuj9VeqselGa_Q 提取码: s7x4 大家有需要可以下载这个,密码61 若依前端编译后文件 通过网盘分享的文件:ruoyi-admin.jar 链…...
ubuntu22.04 R Rstudio conda python 深大
一、配置IP network:version: 2renderer: networkdethernets:eth0:dhcp4: noaddresses:- 172.20.0.52/24gateway4: 172.20.0.2nameservers:addresses: [8.8.8.8, 8.8.4.4] 二、update apt update apt upgrade 三、安装python ubuntu 22.04安装python3 在Ubuntu 22.04上安装…...
二百七十一、Kettle——ClickHouse增量导入数据清洗记录表
一、目的 在完成错误数据表任务后,需要对每条错误数据的错误字段及其字段值进行分析 Hive中原有SQL语句和ClickHouse现有SQL语句很大不同 二、Hive中原有代码 2.1 表结构 --31、静态排队数据清洗记录表 create table if not exists hurys_db.dwd_data_clean_…...
为什么说Tcp是面向字节流的以及(Tcp粘包问题、TCP/UDP对比、listen函数的backlog参数的意义)
为什么说Tcp是面向字节流的: Tcp通信的本质是创建一个tcp的socket,同时就会对应的创建一个发送缓冲区和接收缓冲区。 调用write时, 数据会先写入发送缓冲区中;如果发送的字节数太长, 会被拆分成多个TCP的数据包发出如果发送的字节数太短, 就会先在缓冲…...
Flink PostgreSQL CDC源码解读:深入理解数据流同步
目录 一、PostgreSQL的数据捕获和复制机制 二、WAL日志格式 三、Debezium部署架构 3.1 Kafka Connect With Debezium 3.2 Debezium Server 编辑3.3 作为嵌入式引擎 四、Flink Postgres CDC源码解读 4.1. 如何捕捉数据和更新快照 4.2. 捕获的数据怎么从Postgres SQL…...
系统架构设计师 软件架构的定义与生命周期
软件架构的定义 通过一系列的设计活动,以满足系统的功能性需求和符合一定的非功能性需求与质量属性有相似含义的软件系统框架模式。在软件体系结构设计过程中,主要考虑的是系统的非功能性需求 软件体系结构设计经验的总结与重用是软件工程的重要目标之一…...
从零开始使用Surya-OCR最新版本0.6.1——最强文本检测模型:新添表单表格检测识别
目录 一、更新概述 二、环境安装 1.基础环境配置 2.模型参数下载 3.参数地址配置——settings.py 三、指令使用 1.命令指令运行 一、更新概述 surya项目Github地址:https://github.com/VikParuchuri/surya 号称今年最强OCR的surya近期迎来新的更新,Vik…...
linux中级wed服务器(https搭建加密服务器)
一。非对称加密算法: 公钥:公共密钥,开放 私钥:私有密钥,保密 1.发送方用自己的公钥加密,接受方用发送方的私钥解密:不可行 2.发送方用接受方的公钥加密,接受方用自己的私钥解密…...
聊一聊为什么企业数字化转型总是三天热度
听到“数字化转型”,是不是脑子里立马蹦出各种炫酷词汇:AI、大数据、物联网、区块链……瞬间觉得公司马上就要起飞?可惜,现实往往是:转型刚刚起步时大家热血沸腾,结果没过多久一哄而散。最终,这…...
2025年NPDP产品经理认证考试时间和报考条件
在报考2025年NPDP认证考试前,了解NPDP相关考试信息是非常重要的,可以帮助我们更好地制定备考计划,提高学习效率。 NPDP考试时间 NPDP考试每年举办两次,分别在5月和11月进行,且考试一般安排在周末,以便在职的专业人士…...
wordpress自定义内容管理/天眼查企业查询
Zookeeper的目录整理如下 1. 【分布式】分布式架构 2. 【分布式】一致性协议 3. 【分布式】Chubby与Paxos 4. 【分布式】Zookeeper与Paxos 5. 【分布式】Zookeeper使用--命令行 6. 【分布式】Zookeeper使用--Java API 7. 【分布式】Zookeeper使用--开源客户端 8. 【分布式】Zoo…...
网站页头是什么/中国市场营销网网站
点击上方蓝字,记得关注我们!win10原装的主题,老套的桌面布局,已经让许多人心生疲倦再看看美化后的桌面▼▼爱了爱了,废话不多说,上教程▼▼工具下载下载链接:https://pan.baidu.com/s/19jPqMtFD-bavRhc-OSw…...
杭州市网站建设公司/免费企业网站建设流程
K210视觉体验—LCD应用使用设备ZTFR开发板2.8寸LCD连接方式LCD应用基本使用显示英文显示图片利用显示图片的方式显示英文使用设备 ZTFR开发板 2.8寸LCD LCD 液晶显示屏是非常常见的一个外接显示设备。 备注:K210当然支持I2C,但是用I2C感觉有些low&…...
wordpress增加内链/网页设计首页制作
EditText继承关系:View-->TextView-->EditTextEditText的属性很多,这里介绍几个:android:hint"请输入数字!"//设置显示在控件上的提示信息android:numeric"integer"//设置只能输入整数,如果…...
wordpress附件/站内优化主要从哪些方面进行
清除浮动之父级添加overflow 这样就能很好的解决这个问题了。 缺点:无法显示溢出的部分呀...
网站建设的步骤有哪些/网站快速收录的方法
mock:能进行后端数据模拟,生成随机数据,拦截Ajax请求 一、 创建好一个项目 1.安装axios 2.安装mockjs 3.html写一个简单的登录 <div class"home"><p><input type"text" placeholder"请输入账号" /></p>&…...