• JAVA JDBC connection


    前言:自己的小理解和大部分javasec内容

    JDBC

    什么是JDBC?

    JDBC本质:官方定义的一套操作所有关系型数据库的规则,即接口。 各个数据库厂商去实现了这个JDBC的接口,提供数据库驱动jar包,我们可以使用这套接口JDBC编程,真正执行代码的是驱动jar包中的实现类

    什么是"真正执行代码的是驱动jar包中的实现类",其实就是一个类去实现官方写的接口中的方法,这样就是一个实现类!

    那么厂商们要实现哪个哪个接口呢? java.sql.Driver

    跟进去看下,如下的方法都是厂商们一定需要实现的方法!!!

    public interface Driver //这是一个接口,不用说,要不然其他厂商如何实现呢!
    Connection connect(String url, java.util.Properties info)
    boolean acceptsURL(String url) //还能判断是否是正规的数据库协议
    DriverPropertyInfo[] getPropertyInfo // 该方法可以获得一些驱动的相关信息放到DriverPropertyInfo数组中
    int getMajorVersion(); //获取主版本信息
    int getMinorVersion(); //获取副版本信息
    boolean jdbcCompliant(); //判断驱动程序是否为正版JDBC
    public Logger getParentLogger() //返回此驱动程序使用的所有记录器的父记录器
    

    可以看下Mysql中的驱动包是如何写的,如下显示,这里它通过继承NonRegisteringDriver类来实现了java.sql.Driver的接口

    java.sql.DriverManager

    Java通过java.sql.DriverManager来管理所有数据库的驱动注册,所以如果想要建立数据库连接需要先在java.sql.DriverManager中注册registerDriver对应的驱动类,然后调用getConnection方法才能连接上数据库。

    跟进去简单的了解下DriverManager这个类的属性和方法

    这是一个公有类public class DriverManager

    如下属性:注册的JDBC驱动程序列表

        // List of registered JDBC drivers
        private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>(); //这个是用来保存已经注册过的驱动
        private static volatile int loginTimeout = 0;
        private static volatile java.io.PrintWriter logWriter = null;
        private static volatile java.io.PrintStream logStream = null;
    

    一个静态代码块:

        static {
            loadInitialDrivers();
            println("JDBC DriverManager initialized");
        }
    
    

    还有一些关于日志的操作:

    public static java.io.PrintWriter getLogWriter()
    public static void setLogWriter(java.io.PrintWriter out)
    ....
    ....
    

    获取数据库的连接:

    public static Connection getConnection(String url, java.util.Properties info)
    public static Connection getConnection(String url, String user, String password)
    public static Connection getConnection(String url)
    private static Connection getConnection(String url, java.util.Properties info, Class<?> caller)
    

    驱动的相关操作:

    public static Driver getDriver(String url) //获取驱动
    public static synchronized void registerDriver(java.sql.Driver driver) //注册驱动1
    public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) //注册驱动2
    public static synchronized void deregisterDriver(Driver driver) //取消驱动
    

    一个概念:Java通过java.sql.DriverManager来管理所有数据库的驱动注册,所以如果想要建立数据库连接需要先在java.sql.DriverManager中注册对应的驱动类,然后调用getConnection方法才能连接上数据库。

    java.sql.DriverManager.getConnection(xx)其实就是间接的调用了java.sql.Driver类的connect方法实现数据库连接的。数据库连接成功后会返回一个叫做java.sql.Connection的数据库连接对象,一切对数据库的查询操作都将依赖于这个Connection对象。

    JDBC连接数据库的一般步骤:

    1、注册驱动,Class.forName("数据库驱动的类名")
    2、获取连接,DriverManager.getConnection(xxx)

    正常实现的代码如下

            Class.forName("com.mysql.jdbc.Driver");
            String URL = "jdbc:mysql://localhost:3306/mysql";
            String USERNAME = "root";
            String PASSWORD = "123456";
            Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
    

    我自己学的时候反正是有疑问的,为什么注册用Class.forName("com.mysql.jdbc.Driver");来实现,然后就是DriverManager.getConnection为什么能够获得Mysql驱动包中的connection对象

    这两个问题得解决!

    为什么Class.forName能够实现注册驱动

    那么直接跟进com.mysql.jdbc.Driver的Driver类中去观察

    看下如下的内容,这是一个静态代码块,并且Class.forName("com.mysql.jdbc.Driver")使用的时候会触发类加载,从而执行该静态代码块,那么也就可以说明了,为什么能够Class.forName("com.mysql.jdbc.Driver")能够注册驱动!

    提醒,如果想拿到对应类型的Class实例,但是又不想触发类加载执行静态代码块的话,下面两种方法可以解决:

    1、使用Class.forName("xxxx", false, loader)方法,将第二个参数传入false。

    2、ClassLoader.load("xxxx");

    DriverManager.getConnection为什么能够获得Mysql

    那么也从源码中观察,老样子跟进DriverManager中,静态代码块执行的是DriverManager.registerDriver(new Driver());

    继续跟registerDriver方法,如下图所示,它会将Mysql自身Driver实例化然后放到registerDriver中

    最后还会添加到registeredDrivers属性中

    然后现在就是Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);

    我们可以看下DriverManager.getConnection的方法是怎么样的,如下图所示,它会将账号密码这些都存储起来然后放到一个info对象中,再将info作为参数传入getConnection中

    跟进去看,重点是如下的红框处,它的for循环会遍历registeredDrivers数组,取出DriverInfo类型的aDriver变量,DriverInfo这个就是之前存储到registeredDrivers数组中的内容,此时的aDriver.driver就是已经实例化的Driver对象(Mysql,Mssql等等),最后调用它们实现Driver接口之后的connect方法,返回一个connection的对象!!!

  • 相关阅读:
    一些遇到的错误的总结:
    ThinkPHP add save delete的返回说明
    一些实用函数 :去除html标签//去除空白//截取汉字
    group_concat
    linux环境下使用mkdir()函数无法创建目录的问题
    报错:Namespace declaration statement has to be the very first statement in the script的解决方法
    ThinkPHP中,字段更新加1的几种写法
    小狼毫输入法安装与简单配置(windows系统)
    对win10和win11的吐嘈
    看死亡诗社时有的一点新想法
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/13492177.html
Copyright © 2020-2023  润新知