携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
JDBC 回顾
JDBC(Java Database Connectivity),是一套接口标准。
JDBC接口(API) 包括两个层次:
- 面向应用的
API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果。 - 面向数据库的
`API:Java Driver API,供开发商开发数据库驱动程序用。
驱动功能和分类
驱动主要包括三个功能:
- 连接数据源
- 发送命令语句给数据库
- 获取并处理结果集
大致有四种JDBC Drivers,我在项目中开发的的驱动大致应被归类为第三种。
- Type-1 driver or JDBC-ODBC bridge driver
- Type-2 driver or Native-API driver
- Type-3 driver or Network Protocol driver
- Type-4 driver or Thin driver
JDBC 驱动实现
至少需要实现的接口
java.sql.Driver
java.sql.Connection
java.sql.Statement
java.sql.ResultSet
包结构:
实现上述的四个接口后(PrepareStatement并不是必须的)就可以完成以下的查询操作:
Connection conn = null;
Statement st = null;
ResultSet rs = null;
Class.forName("com.fanruan.myJDBC.driver.MyDriver");
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", info);
st = conn.createStatement();
rs = st.executeQuery("select * from `student`");
System.out.println("-----------");
System.out.println("执行查询语句");
while(rs.next()) {
...
}
上述方法的调用流程:
MyDriver-connect
MyConnection-createStatement
MyStatement-executeQuery
MyStatement-isClosed
MyResultSet-next
Driver
这行代码可能是每一个Java初学者都要犯嘀咕的地方,为什么将驱动类加载进来就已经注册了驱动。
Class.forName("com.fanruan.myJDBC.driver.MyDriver");
在静态代码块中加载驱动是约定俗成的操作,静态代码块会在类被加载的同时执行。
主要需要实现的代码:
public class MyDriver implements Driver {
//依靠静态函数块注册驱动
static{
try {
DriverManager.registerDriver(new MyDriver());
} catch (Exception e) {
throw new RuntimeException("Can't register driver");
}
}
@Override
public Connection connect(String url, Properties info) throws SQLException {
MyConnection conn = new MyConnection(client);
return (Connection) conn;
}
}
Connection
public class MyConnection implements Connection {
@Override
public Statement createStatement() throws SQLException {
...
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
...
}
// 返回元数据信息,通过自己实现的 MyDatabaseMetaData
@Override
public DatabaseMetaData getMetaData() throws SQLException {
...
}
}
MyDatabaseMetaData.java 主要是提供驱动的一些元信息
Statement
public class MyStatement implements Statement {
@Override
public ResultSet executeQuery(String sql) throws SQLException {
...
}
@Override
public boolean isClosed() throws SQLException {
...
}
ResultSet
public class MyResultSet implements ResultSet {
@Override
public boolean next() throws SQLException {
...
}
public XX getXX(){
...
}