深入剖析jdbc

之前在面试的时候被问到在使用jdbc的时候为什么需要注册驱动的步骤,在注册驱动之后驱动代码是怎么被执行到的,之前只知道简单的使用,被问到具体原理的时候就懵逼了。现在有空来深入总结一下jdbc的使用原理。

一.jdbc的使用

主要分为5个步骤:

  1. 注册驱动
  2. 获取数据库连接Connection
  3. 获取数据库操作对象Statement
  4. 执行SQL语句
  5. 处理查询结果集ResultSet
  6. 关闭资源 倒序依次关闭

源码地址:https://github.com/shelimingming/jdbc-demo

package com.sheliming.jdbc.demo;

import java.sql.*;

/**
 * jdbc使用demo
 */
public class JDBCDemo {
    public static void main(String[] args) {
        Connection conn = null;// 数据库连接对象
        Statement stmt = null;// 数据库操作对象
        ResultSet rs = null;// 查询结果集对象
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //手动注册
            //Driver driver = new com.mysql.jdbc.Driver();
            //DriverManager.registerDriver(driver);

            //2.获取数据库连接
            String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
            String user = "root";
            String password = "123456";
            conn = DriverManager.getConnection(url, user, password);
            System.out.println(conn);

            //3.获取数据库操作对象
            stmt = conn.createStatement();
            System.out.println(stmt);

            //4.执行SQL语句之DML语句
            String sql = "select * from user";
            rs = stmt.executeQuery(sql);
            System.out.println(rs);

            /*
			+----+--------+------+------------------+
			| id | name   | sex  | email            |
			+----+--------+------+------------------+
			 */
            //5、处理查询结果集
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String sex = rs.getString("sex");
                String email = rs.getString("email");
                System.out.println("编号" + id + "\t" + "姓名" + name + "\t" + "性别" + sex + "\t" + "邮箱" + email);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 6、关闭资源 倒序依次关闭
            //6.1 当查询结果集不为空时,先关闭结果集对象
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //6.2 当数据库操作对象不为空时,再关闭数据库操作对象
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //6.3 当数据库连接对象不为空时,最后关闭数据库连接对象
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }
}

建表语句:

/*
Navicat MySQL Data Transfer

Source Server         : local
Source Server Version : 80013
Source Host           : localhost:3306
Source Database       : test

Target Server Type    : MYSQL
Target Server Version : 80013
File Encoding         : 65001

Date: 2019-01-30 23:06:00
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `sex` varchar(2) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'aaa', 'a', 'a');
INSERT INTO `user` VALUES ('2', 'bbb', 'b', 'b');
INSERT INTO `user` VALUES ('3', 'ccc', 'c', 'c');

二.驱动加载过程

这里所谓的驱动,其实就是实现了java.sql.Driver接口的类。如oracle的驱动类是 oracle.jdbc.driver.OracleDriver,mysql就是com.mysql.jdbc.Driver。

//加载Oracle数据库驱动  
Class.forName("oracle.jdbc.driver.OracleDriver");  
//加载SQL Server数据库驱动  
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");  
//加载MySQL 数据库驱动  
Class.forName("com.mysql.jdbc.Driver"); 

Class.forName()将对应的驱动类加载到内存中,然后执行内存中的static静态代码段,代码段中,会创建一个驱动Driver的实例,放入DriverManager中,供DriverManager使用。

首先我们看下com.mysql.jdbc.Driver这个类,在新版本的mysql连接包中使用com.mysql.cj.jdbc.Driver.
在这里插入图片描述
如下:
其中最要的就是这个静态代码块,在反射出这个对象之后就会执行这块静态代码块,将Driver对象放到DriverManager中,这就回答了一开始的那个问题。
在这里插入图片描述
主要实现了java.sql.Driver这个接口
在这里插入图片描述

三.手动加载驱动 Driver 并实例化进行数据库操作的例子

package com.sheliming.jdbc.my;

import java.sql.Connection;
import java.sql.Driver;
import java.util.Properties;

public class MyJdbc {
    public static void driverTest() {
        try {
            //1.加载mysql驱动类,并实例化
            Driver driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance();
            //甚至可以直接这样写
            //Driver driver = new com.mysql.jdbc.Driver();

            //2.判定指定的URL mysql驱动能否接受
            boolean flag = driver.acceptsURL("jdbc:mysql://localhost:3306/test?serverTimezone=UTC");
            System.out.println("协议测试:" + flag);

            //3.创建真实的数据库连接:
            String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
            Properties props = new Properties();
            props.put("user", "root");
            props.put("password", "123456");
            Connection connection = driver.connect(url, props);

            System.out.println(connection);

        } catch (Exception e) {
            System.out.println("加载mysql类失败!");
            e.printStackTrace();
        } finally {

        }
    }

    public static void main(String[] args) {
        driverTest();
    }
}

可见自己注册Driver是一种非常麻烦的事情,所以jdbc提供了DriverManage的东西,我们就可以像第一个demo一样使用DriverManage去获取Connection。这样可以同时管理多个驱动程序,根据传入的参数不同,返回不同的数据连接。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值