为“自研”的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.hqwc.cn/news/586801.html

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

相关文章

《Python之路:系统自学指南》

引言 在当今信息时代&#xff0c;编程已经成为一项越来越重要的技能。而Python作为一门功能强大、易学易用的编程语言&#xff0c;受到了越来越多人的青睐。然而&#xff0c;学习Python并不是一蹴而就的事情&#xff0c;尤其是对于没有编程基础的初学者来说&#xff0c;往往需…

【SQL】1633. 各赛事的用户注册率(COUNT函数 表达式用法)

题目描述 leetcode题目&#xff1a;1633. 各赛事的用户注册率 Code select contest_id, round(count(*)/(select count(*) from Users)*100, 2) as percentage from Register group by contest_id order by percentage desc, contest_id ascCOUNT()函数 COUNT函数用法&#…

Java的编程之旅44——学生信息管理系统

目录 1.MVC设计模式初探 文件结构的搭建 2.Student类用来初始化学生信息 3.主函数里的两个功能 1.调用初始化学生信息的功能 2.输出欢迎界面功能 4.Global类中方法的编写 5.StuPage类&#xff0c;StuCtrl类&#xff0c;StuModel类中方法的编写 1.查询功能 selStu方法的…

关于 C/C++ 1Z(17)开源项目 openppp2 协同程式切换工作流

下述为开源项目 openppp2&#xff08;github&#xff09;构建工作在 C/C 17 的 stackful 有栈协同程式的工作流切换示意图&#xff1a; 在 openppp2 之中采用人工手动方式管理协同程式之间的切换&#xff0c;每个中断过程只是保存线程栈信息&#xff08;如寄存器、当前#PC EIP&…

【Java 集合进阶】单练集合顶层接口collction迭代器

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

枚举---算法

1、定义 枚举算法&#xff1a;也称之为穷举算法&#xff0c;这种算法就是在解决问题的时候去使用所有的方式去解决这个问题&#xff0c;会通过推理去考虑事件发生的每一种可能&#xff0c;最后推导出结果。优点&#xff1a;简单粗暴&#xff0c;它暴力的枚举所有可能&#xff…

hxp CTF 2021 - A New Novel LFI(新颖的解法)

一、环境 unbentu&#xff0c;docker https://2021.ctf.link/assets/files/includers%20revenge-25377e1ebb23d014.tar.xz 二、解析 PHP Filter 当中有一种 convert.iconv 的 Filter &#xff0c;可以用来将数据从字符集 A 转换为字符集 B &#xff0c;其中这两个字符集可以…

26版SPSS操作教程(初级第十四章)

前言 #由于导师最近布置了学习SPSS这款软件的任务&#xff0c;因此想来平台和大家一起交流下学习经验&#xff0c;这期推送内容接上一次第十三章的学习笔记&#xff0c;希望能得到一些指正和帮助~ 粉丝及官方意见说明 #针对官方爸爸的意见说的推送缺乏操作过程的数据案例文件…

【嵌入式学习】FreeRTOS day04.02

一、思维导图 二、练习 1.总结任务调度算法之间的区别&#xff0c;重新实现一遍任务调度算法的代码。 调度算法&#xff1a;抢占式调度&#xff1a;优先级高的任务可以打断低优先级任务的执行&#xff0c;适用于不同优先级任务的执行。 时间片轮换&#xff1a;分配时间片&…

论文精读--GPT4

现有的所有模型都无法做到在线学习&#xff0c;能力有限&#xff0c;而让大模型拥有一个tools工具库&#xff0c;则可以使大模型变成一个交互式的工具去协调调用API完成任务&#xff0c;同时GPT4还联网了&#xff0c;可以不断地更新自己的知识库 多模态模型&#xff0c;接受文…

加密/ 解密 PDF:使用Python为PDF文档设置、移除密码

在数字化时代&#xff0c;文档的安全性变得越来越重要。特别是对于包含敏感信息的PDF文件&#xff0c;确保其不被未经授权的人员访问或修改是至关重要的。本文将介绍如何使用Python在PDF文档中设置密码&#xff0c;以及如何移除已经设置的密码。 目录 PDF加密基础知识 Pytho…