【Mybatis】1-JDBC连接代码分析

本文详细分析了Mybatis中JDBC连接的过程,包括`jdbcDriver`的关键代码,如`Class.forName`的使用,以及`jdbcStatement`部分,涵盖`Connection`、`Statement`、`PreparedStatement`和`CallableStatement`等接口的解释。通过脑图和代码示例,深入理解JDBC如何初始化驱动、建立连接以及执行SQL操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mybatis 1-JDBC连接代码分析

脑图

在这里插入图片描述

代码示例

1.jdbc代码使用

// 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");

// 获取数据库连接
Properties jdbcConfig = new Properties();
jdbcConfig.setProperty("user", "root");
jdbcConfig.setProperty("password", "password");
Connection connection = DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/jhome?characterEncoding=utf-8",
        jdbcConfig
);

// sql预处理
String testSql = "select * from user where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(testSql);
preparedStatement.setString(1, "1");

// 执行sql
ResultSet resultSet = preparedStatement.executeQuery();

// 获取执行结果
while (resultSet.next()) {
    System.out.println("Result" +
            " id=" + resultSet.getString("name") +
            " name=" + resultSet.getString("name"));
}

preparedStatement.close();
resultSet.close();
connection.close();

2.关键代码-jdbcDriver

  1. Class.forName
  • 包: java.lang.Class
  • 示例: Class t = Class.forName(“com.mysql.cj.jdbc.Driver”)
  • @CallerSensitive 注解
    • 反射安全配置注解, 具体原理暂不细纠
  • initialize
    • true 如果给定的类之前没有被初始化过, 那么就会被初始化
    • jdbc 使用该方法也是为了初始化 driver 类
  • 目测不写这段, 在 DriverManager 初始化的时候也会初始化已有的 driver 类
@CallerSensitive
public static Class<?> forName(String className)
            throws ClassNotFoundException {
    Class<?> caller = Reflection.getCallerClass();
    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
  1. MySQL Driver
  • 包: com.mysql.cj.jdbc.Driver
  • java.sql.DriverManager.registerDriver(new Driver())
    • 在静态代码块中, 类初始化时会加载, 注册本驱动到 DriverManager
    • 后续获取连接也是从 DriverManager 中获取
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    //
    // Register ourselves with the DriverManager
    //
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }

    /**
     * Construct a new driver and register it with DriverManager
     * 
     * @throws SQLException
     *             if a database error occurs.
     */
    public Driver() throws SQLException {
        // Required for Class.forName().newInstance()
    }
}
  1. DriverManager
  • Java sql 驱动管理
  • 类初始化时, 会加载和初始化驱动类
    • System.getProperty(“jdbc.drivers”) 默认先从这里找驱动
    • If the driver is packaged as a Service Provider, load it
      • 会使用 ServiceLoader 加载相关驱动, 暂不纠细节
static {
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
}
  • getConnection 获取连接
    • Reflection.getCallerClass() 获取调用者的类
      • 目的是使用调用者类的类加载器
    • isDriverAllowed 此处会检查驱动是否可用
      • 此处调用了 Class.forName(), 也就是为什么第一步可用省略
// 获取类加载器
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) {
    // synchronize loading of the correct classloader.
    if (callerCL == null) {
        callerCL = Thread.currentThread().getContextClassLoader();
    }
}

// 使用驱动获取连接
for(DriverInfo aDriver : registeredDrivers) {
  if(isDriverAllowed(aDriver.driver, callerCL)) {
      Connection con = aDriver.driver.connect(url, info);
  }
}

// 驱动是否可用
private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
    boolean result = false;
    if(driver != null) {
        Class<?> aClass = null;
        try {
            aClass =  Class.forName(driver.getClass().getName(), true, classLoader);
        } catch (Exception ex) {
            result = false;
        }

          result = ( aClass == driver.getClass() ) ? true : false;
    }

    return result;
}

3.关键代码-jdbcStatement

  1. Connection
  • 包: java.sql.Connection
  • java sql 连接器
  • sql 相关连接以及 statement 都是在 java sql 中定义好的标准接口

Statement createStatement() throws SQLException;

PreparedStatement prepareStatement(String sql)
        throws SQLException;

CallableStatement prepareCall(String sql) throws SQLException;

void setAutoCommit(boolean autoCommit) throws SQLException;

void commit() throws SQLException;

void rollback() throws SQLException;

void close() throws SQLException;

  1. Statement
java.sql.Statement
|_ java.sql.PreparedStatement
|  |_ java.sql.CallableStatement
|
|_ com.mysql.cj.jdbc.JdbcStatement
  • 包: java.sql.Statement
  • 执行静态的 sql 查询和更新
  • ResultSet 查询返回的结果集
    • 本质上是行迭代器
    • 可以基于列下标取值
ResultSet executeQuery(String sql) throws SQLException;

int executeUpdate(String sql) throws SQLException;

void addBatch( String sql ) throws SQLException;

int[] executeBatch() throws SQLException;

Connection getConnection()  throws SQLException;

ResultSet getResultSet() throws SQLException;

int getUpdateCount() throws SQLException;

default long[] executeLargeBatch() throws SQLException {
    throw new UnsupportedOperationException("executeLargeBatch not implemented");
}
  1. PreparedStatement
  • 包: java.sql.PreparedStatement, 继承 Statement
  • 包含动态参数的 sql 查询和更新
  • 基于 Statement 接口之上, 新增了添加参数的方法, 以及无参 execute
  • 基于 Connection.prepareStatement 创建时, 会传入 sql, 后续利用 PreparedStatement 传入值
  • 在 PreparedStatement 示例中已经说明了使用 ? 作为参数标识
ResultSet executeQuery() throws SQLException;

int executeUpdate() throws SQLException;

void setString(int parameterIndex, String x) throws SQLException;

void addBatch() throws SQLException;

boolean execute() throws SQLException;

ParameterMetaData getParameterMetaData() throws SQLException;
  1. CallableStatement
  • 包: java.sql.CallableStatement, 继承 PreparedStatement
  • 可以调用数据库中的存储过程
  • 提供获取参数的方法, 并且设置/获取支持基于参数名
  • 基于 Connection.prepareCall 创建时, 会传入 sql

void registerOutParameter(int parameterIndex, int sqlType)
        throws SQLException;

String getString(int parameterIndex) throws SQLException;

String getString(String parameterName) throws SQLException;

void setString(String parameterName, String x) throws SQLException;

名称解析

  1. JDBC
  • wiki
    • J DB C, Java Database Connectivity
    • Java数据库连接, 面向关系型数据库
    • JDBC API主要位于JDK中的java.sql包中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值