为“自研”的KV数据库编写JDBC驱动

一觉醒来,受到梦的启发,自研了一套K/V数据库系统,因为"客户"一直催促我提供数据库的JDBC驱动,无奈之下,只好花费一个上午的时间为用户编写一个。

我们知道,JDBC只定义一系列的接口, 具体的实现需要由不同厂商提供的,我们首先需要实现java.sql.Driver这个接口:

package org.littlestar.propsjdbc;
//import ...
public class Driver implements java.sql.Driver {// 当class loader加载本类时,向DriverManager注册该驱动static {try {java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException e) {throw new RuntimeException("Can't register driver!");}}@Overridepublic Connection connect(String url, Properties info) throws SQLException {return new ConnectionImpl(url);}@Overridepublic boolean acceptsURL(String url) throws SQLException {if (url == null) {throw new SQLException("url is null.");}// 接受'jdbc:props:'类型的URLreturn url.trim().startsWith("jdbc:props:");}// ... 其它接口实现省略
}

DriverManager是通过JDK内置的SPI(Service Provider Interface)机制来发现我编写的’org.littlestar.propsjdbc.Driver’实现。所以我们需要在META-INF/services/目录里创建一个以服务接口命名的文件, 文件名为"java.sql.Driver"的文件, 该文件内容为接口实现类: ‘org.littlestar.propsjdbc.Driver’。当DriverManager在调ensureDriversInitialized()方法的时候,ServiceLoader会查找类路径下的META-INF/services/java.sql.Driver文件,并加载其定义的接口实现类。

private static void ensureDriversInitialized() {//...ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);Iterator<Driver> driversIterator = loadedDrivers.iterator();/* Load these drivers, so that they can be instantiated...*/try {while (driversIterator.hasNext()) {driversIterator.next();}} catch (Throwable t) {// Do nothing}//...
}

接下来还要分别实现java.sql.Connection,java.sql.Statement和java.sql.ResultSet接口:

package org.littlestar.propsjdbc;
// import ...;
public class ConnectionImpl implements java.sql.Connection {String dbPath = System.getProperty("user.dir");public ConnectionImpl(String url) {if (url != null) {dbPath = url.trim().replaceFirst("jdbc:props:", "").trim();}}@Overridepublic Statement createStatement() throws SQLException {return new StatementImpl(dbPath);}// ... 其它接口实现省略
}

编写java.sql.Statement接口的实现:

package org.littlestar.propsjdbc;
// import ...;
public class StatementImpl implements java.sql.Statement {String dbPath = "";public StatementImpl(String path) {dbPath = path;}@Overridepublic ResultSet executeQuery(String sql) throws SQLException {String pattern = "(?i)SELECT.*?FROM";String fileName = sql.replaceFirst(pattern, "").trim();Properties props = new Properties();String file = dbPath + File.separator + fileName;try (BufferedReader reader = Files.newBufferedReader(Paths.get(file), StandardCharsets.UTF_8)) {props.load(reader);} catch (IOException e) {throw new SQLException(e);}return new ResultSetImpl(props);}// ... 其它接口实现省略
}

编写java.sql.ResultSet实现:

package org.littlestar.propsjdbc;
//import ...
public class ResultSetImpl implements java.sql.ResultSet {final Properties props;Iterator<Entry<Object, Object>> iterator;Entry<Object, Object> row;public ResultSetImpl(Properties props) {this.props = props;iterator = props.entrySet().iterator();}@Overridepublic boolean next() throws SQLException {boolean next = iterator.hasNext();if (next) {row = iterator.next();}return next;}@Overridepublic String getString(int columnIndex) throws SQLException {if (row == null) {return null;}if (columnIndex == 1) {return row.getKey().toString();} else if (columnIndex == 2) {return row.getValue().toString();} else {return null;}}// ... 其它接口实现省略
}	

至此,jdbc驱动已经开发完毕,我们打包交给客户测试。Eclipse选择我们的项目,右键菜单选择"Export…“。在弹出的向导菜单中选择"JAR file”,然后点击下一步按钮。
在这里插入图片描述
点击结束按钮既可生成驱动的jar文件。交给用户测试。

测试如下。。。。先通过数据库管理工具"explorer.exe",创建一个"数据库":“D:\testcase\nbdb”,然后通过数据库开发工具“notepad.exe”创建一个表’table1’,内容如下:

名称=牛B数据库系统®
版本=高级企业版本(v24.4)
售价=60000000马内
供应商=白日梦股份有限公司

点击"保存"提交。接下来通过jdbc进行数据库访问:

public class Test {public static void main(String[] args) throws SQLException {String url = "jdbc:props:D:\\testcase\\nbdb";try (Connection connection = DriverManager.getConnection(url);Statement stmt = connection.createStatement();ResultSet rs = stmt.executeQuery("select * from table1")) {// System.out.println(connection.getClass().getCanonicalName());// System.out.println(stmt.getClass().getCanonicalName());// System.out.println(rs.getClass().getCanonicalName());while (rs.next()) {String key = rs.getString(1);String value = rs.getString(2);System.out.println(key + ": " + value);}}}
}
// 程序执行结果如下:
售价: 60000000马内
名称:B数据库系统®
版本: 高级企业版本(v24.4)
供应商: 白日梦股份有限公司

经过"客户"专家组评审,这套数据库系统测试符合预期,达到了业界领先水平,喜提6000w马内,实现人生财富自由。爽文至此结束。各位看官学废了吗?

最后附上完整代码(如果文件审核能过。。。),https://download.csdn.net/download/Li_Xiang_996/89071254

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

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

相关文章

WeekPaper:GraphTranslator将知识图谱与大模型对齐

GraphTranslator: 将图模型与大型语言模型对齐&#xff0c;用于开放式任务。 将基于图的结构和信息与大型语言模型的能力整合在一起&#xff0c;以提高在涉及复杂和多样数据的任务中的性能。其目标是利用图模型和大型语言模型的优势&#xff0c;解决需要处理和理解结构化和非结…

Python深度学习034:cuda的环境如何配置

文章目录 1.安装nvidia cuda驱动CMD中看一下cuda版本:下载并安装cuda驱动2.创建虚拟环境并安装pytorch的torch_cuda3.测试附录1.安装nvidia cuda驱动 CMD中看一下cuda版本: 注意: 红框的cuda版本,是你的显卡能装的最高的cuda版本,所以可以选择低于它的版本。比如我的是11…

Prometheus+grafana环境搭建redis(docker+二进制两种方式安装)(四)

由于所有组件写一篇幅过长&#xff0c;所以每个组件分一篇方便查看&#xff0c;前三篇 Prometheusgrafana环境搭建方法及流程两种方式(docker和源码包)(一)-CSDN博客 Prometheusgrafana环境搭建rabbitmq(docker二进制两种方式安装)(二)-CSDN博客 Prometheusgrafana环境搭建m…

HarmonyOS实战开发-一次开发,多端部署-视频应用

介绍 随着智能设备类型的不断丰富&#xff0c;用户可以在不同的设备上享受同样的服务&#xff0c;但由于设备形态不尽相同&#xff0c;开发者往往需要针对具体设备修改或重构代码&#xff0c;以实现功能完整性和界面美观性的统一。OpenHarmony为开发者提供了“一次开发&#x…

Ubuntu20.04安装MatlabR2018a

一、安装包 安装包下载链接 提取码&#xff1a;kve2 网上相关教程很多&#xff0c;此处仅作为安装软件记录&#xff0c;方便后续软件重装&#xff0c;大家按需取用。 二、安装 1. 相关文件一览 下载并解压文件后&#xff0c;如下图所示&#xff1a; 2. 挂载镜像并安装 2…

python实战之宝塔部署flask项目

一. 项目 这个demo只是提供了简单的几个api接口, 并没有前端页面 # -*- coding: utf-8 -*- import flask as fk from flask import jsonify, requestapp fk.Flask(__name__)app.route(/api/hello, methods[GET]) def get_data():return hello world# 假设我们要提供一个获取用…

rabbitmq死信交换机,死信队列使用

背景 对于核心业务需要保证消息必须正常消费&#xff0c;就必须考虑消费失败的场景&#xff0c;rabbitmq提供了以下三种消费失败处理机制 直接reject&#xff0c;丢弃消息&#xff08;默认&#xff09;返回nack&#xff0c;消息重新入队列将失败消息投递到指定的交换机 对于核…

每日一题 --- 右旋字符串[卡码][Go]

右旋字符串 题目&#xff1a;55. 右旋字符串&#xff08;第八期模拟笔试&#xff09; (kamacoder.com) 题目描述 字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k&#xff0c;请编写一个函数&#xff0c;将字符串中的后面…

HarmonyOS 应用开发之同步任务开发指导 (TaskPool和Worker)

同步任务是指在多个线程之间协调执行的任务&#xff0c;其目的是确保多个任务按照一定的顺序和规则执行&#xff0c;例如使用锁来防止数据竞争。 同步任务的实现需要考虑多个线程之间的协作和同步&#xff0c;以确保数据的正确性和程序的正确执行。 由于TaskPool偏向于单个独…

scRNA+bulk+MR:动脉粥样硬化五个GEO数据集+GWAS,工作量十分到位

今天给大家分享一篇JCR一区&#xff0c;单细胞bulkMR的文章&#xff1a;An integrative analysis of single-cell and bulk transcriptome and bidirectional mendelian randomization analysis identified C1Q as a novel stimulated risk gene for Atherosclerosis 标题&…

rtph264depay插件分析笔记

1、rtp协议头 2、rtp可以基于TCP或者UDP 其中基于TCP需要加4个字节的RTP标志 3、rtph264depay定义解析函数gst_rtp_h264_depay_process&#xff0c;通过RFC 3984文档实现。 static void gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass) {GObjectClass *gobject…

AI资讯2024-04-02 | 前微软副总裁姜大昕携「阶跃星辰」入场,出手即万亿参数大模型!

关注文章底部公众号获取每日AI新闻,以及各种好玩的黑科技,如AI换脸,AI数字人,AI生成视频等工具 阶跃星辰发布万亿参数大模型 终于!国内大模型创业公司最后一位强实力玩家入场——阶跃星辰。它是由微软前全球副总裁姜大昕所创办,公司名称也来源于,发了三个大模型:Step-…

当msvcp120.dll文件找不到了要怎么解决?教你靠谱的3种修复msvcp120.dll方法

当出现msvcp120.dll文件丢失的问题时&#xff0c;不用担心&#xff0c;这是一个常见的情况。在日常使用电脑时&#xff0c;误删或受到计算机病毒影响都可能导致这个问题。为了解决这个问题&#xff0c;今天我们将向大家介绍正确的msvcp120.dll修复方法。 一.msvcp120.dll文件是…

体验OceanBase 的binlog service

OceanBase对MySQL具备很好的兼容性。目前&#xff0c;已经发布了开源版的binlog service工具&#xff0c;该工具能够将OceanBase特有的clog模式转换成binlog模式&#xff0c;以便下游工具如canal、flink cdc等使用。今天&#xff0c;我们就来简单体验一下这个binlog service的功…

RA8889/RA8876显示自定义ASCII字符方法

本文介绍用户自己生成的ASCII字库如何通过RA8889/RA8876显示到液晶屏上。 先上一张实例效果图&#xff1a; 再上程序代码&#xff1a; int main(void) {unsigned short x,y;/* System Clocks Configuration */RCC_Configuration(); delay_init(72); GPIO_Configuration(); …

转圈游戏(acwing)

题目描述&#xff1a; n 个小伙伴&#xff08;编号从 0 到 n−1&#xff09;围坐一圈玩游戏。 按照顺时针方向给 n 个位置编号&#xff0c;从 0 到 n−1。 最初&#xff0c;第 0 号小伙伴在第 0 号位置&#xff0c;第 1 号小伙伴在第 1 号位置&#xff0c;…

前端学习<二>CSS基础——17-CSS3的常见边框汇总

CSS3 常见边框汇总 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>CSS3 边框</title><style>body, ul, li, dl, dt, dd, h1, h2, h3, h4, h5 {margin: 0;padding: 0;}​body {background-c…

治愈风景视频素材在哪找?日落风景、伤感风景、江南风景这里都有

在这个视频内容为王的时代&#xff0c;做个爆款视频好比烹饪一道米其林三星级大餐&#xff0c;少了那么一点儿神秘的调料&#xff0c;总觉得差了点味道。我&#xff0c;一个在视频剪辑战场上摸爬滚打多年的老兵&#xff0c;今天就来跟大家分享几个找素材的秘密武器&#xff0c;…

STM32应用开发——使用PWM+DMA驱动WS2812

STM32应用开发——使用PWMDMA驱动WS2812 目录 STM32应用开发——使用PWMDMA驱动WS2812前言1 硬件介绍1.1 WS2812介绍1.1.1 芯片简介1.1.2 引脚描述1.1.3 工作原理1.1.4 时序1.1.5 传输协议 1.2 电路设计 2 软件编程2.1 软件原理2.2 测试代码2.2.1 底层驱动2.2.2 灯效应用 2.3 运…

leetcode二叉树相关题目

目录 二叉树的建立整数数组转二叉树Object数组转二叉树 二叉树的遍历leetcode94.二叉树的中序遍历leetcode144.二叉树的前序遍历 二叉树的建立 整数数组转二叉树 下面只是一个简单的示例&#xff0c;没考虑某个子树为空的情况。把{1, 2, 3, 21, 22, 31, 32} 转变为一个二叉树…