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
) ;
String testSql = "select * from user where id = ?" ;
PreparedStatement preparedStatement = connection. prepareStatement ( testSql) ;
preparedStatement. setString ( 1 , "1" ) ;
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
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) ;
}
MySQL Driver
包: com.mysql.cj.jdbc.Driver java.sql.DriverManager.registerDriver(new Driver())
在静态代码块中, 类初始化时会加载, 注册本驱动到 DriverManager 后续获取连接也是从 DriverManager 中获取
public class Driver extends NonRegisteringDriver implements java. sql. Driver {
static {
try {
java. sql. DriverManager. registerDriver ( new Driver ( ) ) ;
} catch ( SQLException E) {
throw new RuntimeException ( "Can't register driver!" ) ;
}
}
public Driver ( ) throws SQLException {
}
}
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 ) {
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
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;
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" ) ;
}
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;
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;
名称解析
JDBC
wiki
J DB C, Java Database Connectivity Java数据库连接, 面向关系型数据库 JDBC API主要位于JDK中的java.sql包中