目录

方式一(最初始方法):

方式二:

方式三:

方式四:

后话:为什么Class.forName(driverName)可以实现驱动的加载呢?

在正式讲连接方式前我们应先明确JDBC连接的四个要素: 

要素一Driver接口实现类

  • java.sql.Driver
  • 在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类 java.sql.DriverManager
  • MySQL的驱动为com.mysql.jdbc.Driver 

要素二URL

  • URL定义了连接数据库时的协议、子协议、数据源标识。
  • URL格式:jdbc:<子协议>:<子名称>,我们在mysql连接中子协议为mysql,子名称包含主机名、端口号、数据库名
  • Mysql连接URL示例:jdbc:mysql://locoalhost:3306/Conan 

要素三数据库用户名

要素四数据库密码

  •     user和password均可以通过  'name' = 'value' 的形式设置 

别急,开始前我们还要简单说一下JDBC连接的步骤:

  1. 加载驱动程序,我们需要将驱动类加载到JVM
  2. 提供连接所需参数
  3. 建立数据库连接

正篇开始:

方式一(最初始方法): 

    1. 首先获取Driver的实现类对象,com.mysql.jdbc.Driver位于第三方jar包中

Driver driver = new com.mysql.jdbc.Driver();

        2. 提供url,指明要操作的的数据库

String url = "jdbc:mysql://localhost:3306/Conan?useSSL=false";
//locoalhost为可选ip地址
//mysql默认本地端口号为3306
//Conan为要操作的数据库名称
//u'seSSL=false为可选项,视数据库版本而定,MySQL8.0及以上版本需要指明

   3. 提供Properties对象,并设置用户名及密码

Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password", "xxxxxx");

    

    4. 通过Driver类中的connect方法获取连接,connect方法源码如下

pg数据库 获取当前库schema_其他

Connection connection = driver.connect(url, properties);
//得到一个Connection类的对象

    数据库连接获取完成。 

方式二:

    1. 我们可以通过java.lang.Class类的静态方法forName(String  className)实现驱动的加载驱动

Class clazz = Class.forName("com.mysql.jdbc.Driver");

        2. 提供url,指明要操作的的数据库

String url = "jdbc:mysql://localhost:3306/Conan?useSSL=false";

        3. 提供Properties对象,并设置用户名及密码

Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password", "xxxxxx")

          4. 通过Driver类中的connect方法获取连接

Driver driver = clazz.newInstance();
//通过instance方法获取类的实例
//newInstance方法自jdk9.0之后弃用,建议写法为clazz.getDeclaredConstructor().newInstance()
Connection connection = driver.connect(url, properties);
//得到一个Connection对象

    数据库连接获取完成。(2、3、4步与方式一一致) 

方式三:

    1. 通过静态方法forname加载驱动

Class.forname("com.mysql.jdbc.Driver");
//注意,这里与方式二不同,没有实例化Class类对象

        2. 使用DriverManager类中的静态方法 

getConnection(String url,String user,String password)

       请求获得Connection对象

String url = "jdbc:mysql://localhost:3306/Conan?useSSL=false";
String user = "root";
String password = "xxxxxx";
Connection conn = DriverManager.getConnection(url, user, password);

        数据库连接获取完成。 

方式四:

    1. 通过配置文件加载要素信息;

(此方法实现了代码和数据的分离,修改信息只需要修改配置文件,而不需要 接触代码 ,而且省去重新编译的过程。)

 

      首先我们先建立一个配置文件(.properties)并在其中写入要素如下

pg数据库 获取当前库schema_其他_02


InputStream inputstream = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
//通过流读取配置文件中内容
Properties properties = new Properties();//提供Properties对象
properties.load(inputstream);//通过load方法讲流中配置文件信息设置到对象中

        2. 通过properties对象获取配置文件内容

String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driverClass = properties.getProperty("driverClass");

        3. 通过静态方法forname加载驱动

Class.forname("driverClass");

     4. 使用DriverManager类中的静态方法 

 getConnection(String url,String user,String password)

       请求获得Connection对象

Connection conn = DriverManager.getConnection(url, user, password);

        数据库连接获取完成。

         至此,我们得到了四种获得数据库连接的方式 

后话:为什么Class.forName(driverName)可以实现驱动的加载呢?

驱动加载实际上就是JVM将.class字节码文件加载到内存,而加载过程分为三步

pg数据库 获取当前库schema_经验分享_03

其中, 在链接的准备阶段会为类变量(static变量)分配存储空间并设置默认初始值。

先来看看源码中forname方法是怎样写的

public static Class<?> forName(String className)throws ClassNotFoundException {
       Class<?> caller = Reflection.getCallerClass();
       return forName0(className, true, ClassLoader.getClassLoader(caller), caller);}
//这里调用了另一个方法forname0
那么forname0又是个什么方法呢
private static native Class<?> forName0(String name, boolean initialize,ClassLoader loader,Class<?> caller)
//name为全限定类名
//initializeb表示是否初始化该类,默认为true
//loader为对应的类加载器
//caller为对应类的对象

所以调用forname方法不仅会将类加载到JVM中去,还会进行初始化,也就意味着会执行static块中的代码

而上文我们用Class.forName(driverName)实现驱动的加载,就是利用了这样的机制。

pg数据库 获取当前库schema_java_04

 我们看到mysql的Driver类中静态代码块中有一个registerDriver方法,正是执行静态代码块时,该方法替我们加载了驱动程序。真相大白了呢! 

留个问题,我们可不可以用这个方法加载驱动呢?

ClassLoader.getSystemClassLoader().loadClass(String name);