一觉醒来,受到梦的启发,自研了一套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