JDBC是一个Java API,用中文能够通俗的解释为,使用Java语言访问访问数据库的一套接口集合。这是调用者(程序员)和实行者(数据库厂商)之间的协议,能够访问任何类型表列数据,特别是存储在关系数据库中的数据。JDBC(java database connection)html
既然JDBC也是由Java类和接口组成,那么首先要学习的是,它属于哪一个包下面。
在JDBC中包含了两个包:java.sql和javax.sqljava
能够看出JDBC在图中的位置,前文说过是程序员与数据库厂商之间的协议。首先Java提拱了JDBC的接口,服务器厂商提供了JDBC的驱动,这样咱们经过JDBC Driver Manager来进行管理数据库。mysql
DriverManager: 这个类管理数据库驱动程序的列表。 肯定内容是否符合从Java应用程序使用的通讯子协议正确的数据库驱动程序的链接请求。 识别JDBC在必定子协议的第一个驱动器将被用来创建数据库链接。 Driver: 此接口处理与数据库服务器通讯。 不多直接直接使用驱动程序(Driver)对象,通常使用DriverManager中的对象, 它用于管理此类型的对象。它也抽象与驱动程序对象工做相关的详细信息 Connection : 此接口与接触数据库的全部方法。 链接对象表示通讯上下文,即,与数据库中的全部的通讯是经过此惟一的链接对象。 Statement : 可使用这个接口建立的对象的SQL语句提交到数据库。 一些派生的接口接受除执行存储过程的参数。 ResultSet: 这些对象保存从数据库后,执行使用Statement对象的SQL查询中检索数据。 它做为一个迭代器,能够经过移动它来检索下一个数据。 SQLException: 这个类用于处理发生在数据库应用程序中的任何错误。
①Class.forName("com.mysql.jdbc.Driver");
Java规范中明确规定,全部的驱动程序必须在静态初始代码块中将驱动注册到驱动程序的管理器中,程序员
static{ try{ Class.forName(driver); } catch(Exception ex){ ex.printStackTrace(); } }
这样作的好处是,再类被加载到工程时就被执行了,并且之执行一次,数据库驱动只要加载一次就能够了。sql
【知识点】 Class类
在这里面咱们看到了,这个里面有一个Class类,它调用了一个forName()方法,那么这个Class类是个什么东西呢?
Class类是在java.lang包下的,因此不用手动的导入。
看一下Class的构造方法[1]数据库
private Class(ClassLoader loader){ classLoader = loader; }
不用去管什么ClassLoader,看了一眼private关键字,应该就知道了,当private修饰构造方法的时候,说明该类是不能在类的外面进行实例化的。因此Class类不能像普通的类同样,以new Xxx()
的形式进行建立对象,它的对象只能由JVM建立。[2]编程
Class类究竟是什么呢?不妨咱们通俗的说一下,Java程序在运行的时候,咱们会让它建立一些对象,系统经过RTTI对全部的对象进行运行时类型表示。bootstrap
【知识点】RTTI
RTTI(runtime type Identification),经过运行时类型信息程序可以使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。
咱们把它叫成运行时类型信息,或许更加的好理解。这个是Java语言中很强大的机制。
首先要知道的运行时都会存在哪些类型信息呢?若是一个类继承自另外一个类,在建立子类的对象时,须要RTTI存储这些关系,他会有typeid操做符,返回指针和引用所指的实际类型,typeid函数等等,咱们简要的理解为Java的RTTI里面就是记录着各类类型的信息。
如下是一些经常使用的方式。缓存
咱们能够针对于基类来编程,从而下降程序的耦合度,以Java来讲经常经过继承的方式,来达到这种效果。服务器
public class Demo { public static void main(String[] args) { Animal [] animals = new Animal[2]; animals[0] = new Tiger(); animals[1] = new fish(); for (Animal animal : animals) { animal.breath(); } } } abstract class Animal { abstract void breath(); } class Tiger extends Animal{ @Override void breath() { // TODO Auto-generated method stub } } class fish extends Animal{ @Override void breath() { // TODO Auto-generated method stub } }
像这种继承关系,之因此可以编译经过,是由于Tiger和FIsh都会向上转为基类,他们自身的类型信息会丢失,可是程序运行的时候,当咱们调用animal.breath();
它们却能准确的找到所属类型的方法进行调用,这是为何呢?这就是运行时绑定(动态绑定)机制。
进一步分析,RTTI里面就是存储着程序运行时类型的方法列表,继承结构等等信息。
java xxx.class
,这个时候类才开始加载到虚拟机,通常来讲一个class只会被加载一次,下一次就会从Jvm的class缓存中获取,不会再去文件系统中获取了。具体的过程是:java这个命令是java.exe进行的,java.exe找到jre,再找到JRE中的jvm.dll,这个就是Java 虚拟机,这个时候虚拟机启动,它首先就加载了第一个类加载器--Bootstrap Loader,这个BootstrapLoader又加载了第二个类加载器ExtClassLoader,设定parent为null(本质上是bootstraploader,可是它是由C++编写的,没法找到这个实例)这个BootstrapLoader又加载了最后一个类加载器APPClassLoader,设定它的parent为ExtClassLoader。Class类原理:当各种被实例化后,JVM会自动建立该类的Class对象,或者经过类加载器defineClass()方法生成。
全部的类都继承自Object
类,Object类有一个getClass()
方法,这个方法能够获取某个对象的Class引用,这个引用就是指向的是Class类的对象。
由于是针对类的关系而言,因此一个Class对象对应多个类的实例化。
获取Class对象:
经过类名来获取:
public class Hello{} Class hello = Class.forName("Hello");
经过对象来获取。
public class Hello{} Hello h = new Hello(); Class hello = h.getClass();
经过类字面量来获取
public class Hello{} Class hello = Hello.class;
【注】使用第三种方法来获取Class对象,Jvm不会加载类,也就不会初始化,而其余两种方法,会自动加载并初始化类。
回到正题。第二种注册数据库驱动的方法是。
②
Driver drv = new oracle.jdbc.driver.OracleDriver(); DriverManager.registerDriver(drv);
③ 编译时在虚拟机中加载驱动
java -D jdbc.drivers = 驱动全名 类名 例如: javac -D jdbc.drivers = oracle.jdbc.driver.OracleDrvier xxx.java
【问题】如下是知乎的问题
JDBC注册数据库驱动,啥意思?
Class.forName("com.mysql.jdbc.Driver")不是反射么,获得这个类的信息,和注册数据库驱动有啥关系?
答:
做者:木女孩
连接:https://www.zhihu.com/questio...
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
建立一个Connection
对象,创建物理链接
static final String USER = "XXX"; static final String PASSWORD = "xxx"; System.out.println("database is connecting"); Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.23:1521:tarena",USER,PASSWORD);
回想以前的结构图,咱们能够知道,经过DriverManager
能够操做数据库的驱动,从而进行数据库的相关操做。
这里Connection
链接就是经过DriverManager
的静态方法getCOnnection()
来获得的,这个方法的实质是把参数传到实际的Driver
中的connect()
方法来忽的数据库的链接的。
下面是一些格式的补充:
Oracle URL的格式:jdbc:oracle:thin:(协议)@XXX.XXX.X.XXX:XXXX(IP地址及端口号):XXXXXX(所使用的库名)
MySql URL:jdbc:mysql://192.168.8.21:3306/test
SQLServer URL 的写法 jdbc:microsoft:sqlserver://192.168.8.21:1433
经过Connection
对象createStatement()
来建立Statement对象
Statement stm = conn.createStatement();
经过Statement来执行
stm.excuteQuery(Sring sql); //返回一个查询结果集 stm.excuteUpdate(String sql); //返回值为 int 型,表示影响记录的条数。 stm.excute(String sql);//返回 true,表示查询;返回 false,表示其它操做。
经过excuteQuery(String sql)
可使用select语句进行查询,而且返回一个结果集ResultSet。ResultSet的next()方法会操做一个游标从第一条记录的前面开始读取,直到最后一条记录。
【注】只有执行select语句才有结果集返回。
while(rs.next()){ System.out.println(rs.getInt("id)); System.out.println(rs.getString("name")); }
rs.close(); stm.close(); conn.close()
应该顺序关闭,若是先关闭Connetction后面可能还须要其余的Statement链接。
[1] 浅谈Java中的Class类
[2] Java中Class类及用法
[3] RTTI
[4] 深刻Java类型信息:RTTI
[5] 类加载的全过程
[6] java类加载过程
[7] 深刻理解java类加载起ClassLoader