JDBC简介 | 事务处理 | 批处理 | 可滚动和可更新结果集 | 我的博客 | |
JDBC驱动程序 | 数据库URL | 预处理语句 | 使用可滚动和可更新结果集 | v512工作室 | |
JDBC—ODBC编程 | BLOB/CLOB类型 | 调用存储过程 | 通过OCI方式访问Oracle数据库 | 中科院新科海学校 |
数据库简介
概念:数据库(DB,Data Base)和数据库管理系统(DBMS,Data Base Management System)
当今主流的数据库是关系型数据库。所谓关系型数据库就是其中的数据以行和列的形式进行存储。由多个列组成的一系列的行称之为表
若干个数据表就能够组成一个数据库。关系型数据库的各个数据项之间,或者各个数据表之间使用关系进行组织
比如一个表内部的字段之间的联系,记录(即行)之间的联系,表之间的联系,都称之为关系
通过所谓的关系可以比较灵活的实现数据的操纵。用户也可以非常方便的使用查询语句检索数据库中的数据
SQL:即Structured Query Language,使用关系模型的数据库语言,用于和各类数据库的交互,提供通用的数据管理和查询功能
SQL语言本身不是一种完备的单独使用的一种语言。常用SQL指令有SELECT、INSERT、DELETE、UPDATE、CREATE、DROP
SQL语言最初由IBM公司开发,最早是为了实现关系型数据库中信息的检索,后来经过不断的修改和完善
被美国的国家标准学会ANSI和国际标准化组织ISO联合发布作为国际标准。最新标准是SQL99标准,此前曾有过SQL92、97等标准
ODBC:即Open DataBase Connectivity,开放式数据库互连。ODBC标准是由微软公司开发的一套数据库系统应用程序接口规范
ODBC支持应用程序以标准的ODBC函数和SQL语句操作各种不同类型的数据库
ODBC驱动程序相当于一个转换开关,它负责将应用程序发出的标准SQL指令转化成某一种特定数据库相关的指令格式
然后再传递给具体的数据库的驱动程序,驱动程序再去调用底层的数据库的功能,然后再将处理结果回送给顶层的应用程序
这样在开发的时候,应用程序只需要面对统一格式的ODBC数据源,而不必针对各种数据库进行不同的设置
这样程序能够具有比较好的通用性或者说可移植性。当然也可以实现在一个应用程序中很方便的同时访问多种不同类型的数据库
JDBC简介(Java DataBase Connectivity,即Java的数据库连接)
功能:支持基本SQL语句,在Java程序中实现数据库操作功能并简化操作过程
提供多样化的数据库连接方法。并为各种不同的数据库提供统一的操作界面
原理:Java应用程序不直接和底层数据库打交道,而是在程序中调用JDK提供的通用的JDBC API。具体数据库驱动程序一般由数据库厂商提供
API:java.sql.DriverManager类:驱动程序管理器类,提供了对于多种不同的数据库的驱动程序的管理功能
在操纵某种数据库时,需要将该数据库驱动程序注册到或者说加载到内存中,注册到DriverManager
将来在数据库连接和操纵的过程中,DriverManager会自动的调用底层的数据库驱动程序
java.sql.Driver接口:所有的数据库驱动程序类都必须实现Driver接口。它提供了自动加载本驱动程序类到DriverManager的功能
java.sql.Connection接口:表示到一个特定数据库的连接。只有连接成功,获取了一个Connection对象之后才能进行下一步操作
java.sql.Statement接口:提供了真正执行SQL语句的功能
java.sql.ResultSet接口:它得到的是一个集合,里面返回的是多条记录,可以对它进行遍历
JDBC编程步骤:1)加载驱动程序。即向系统注册所需的JDBC驱动程序
2)建立到指定数据库的连接
3)提交数据库查询
4)取得查询结果。。程序运行结束前,还应关闭已经建立的数据库连接,释放所占用的资源
JDBC驱动程序
驱动概念:所谓的驱动程序就是为了让操作系统能够操纵某种硬件或软件所提供的接口程序
数据库驱动程序就是对某种特定的数据库进行操纵的一个函数或代码的集合。也可以把它理解成是一个小的软件模块
驱动分类:JDBC-ODBC桥:把应用程序对数据库的JDBC调用转换成JDBC—ODBC桥式调用,借助于操作系统转发给Windows的ODBC数据源
由于比较通用,所以JDK中已经提供了该驱动方式,并且大部分数据库厂商都对其产品提供了相应的ODBC驱动程序
因为这种方式几乎能够访问各种现有的数据库类型,因此使用起来比较方便。但它只能工作在Windwos平台上
现在的主流开发已经不再提倡使用这种方式,而建议使用纯JDBC的方式来连接数据库
Java到本地API:将Java应用程序中JDBC调用指令转化为对本地计算机的API,也就是对相应的代码模块的调用
所谓本地API主要指在本机上已经安装好的数据库的客户端的API,也就是数据库厂商提供的本地代码
这些代码通常是使用C或C++编写的。最终也实现了与远程数据库的通信,但也不是直接连接到数据库
该驱动方式在速度上要比桥式驱动快一些,但必须在本地安装目标数据库的客户端程序,因此不适合在Internet上通用
Java到网络协议:使用与具体的数据库无关的网络通信协议,将应用程序中的JDBC调用指令发送给数据库服务器
它发送给数据库服务器的过程中所使用的指令与具体的数据库无关,还是一种通用的网络协议指令
服务器端的数据库需要有相应的中间件,也就是程序模块
将接收到的基于通用性的,与数据库无关的网络协议指令再转换成特定的数据库的指令格式
它是属于纯Java的,即不需要在客户端加载有关数据库的特定的模块,或者说代码库
因此单个的驱动程序就可以对多种不同的数据库进行访问,它的可扩展性比较好
但是数据库服务器端需要提供相应的中间层软件,即提供进一步的转换功能
由于多了一层中间层将网络协议指令再转换成特定的数据库的指令格式,所以它的效率也要稍微低一些
Java到数据库协议:直接使用特定的数据库相关的协议将JDBC的请求发送到目标数据库服务器
也就是说实现客户端和数据库之间的通信协议是数据库相关的,它也是纯Java的驱动程序
这种驱动方式最直接,速度也最快。但是它必须针对不同的数据库都提供一份不同的驱动程序
比如最常用的Oracle数据库的JDBC方式连接使用thin协议就属于此类
数据库URL
概述:JDBC技术中使用数据库URL来标识目标数据库。因此比较适合于访问网络上的数据库服务器
格式:jdbc:<子协议名>:<子名称>
释一:jdbc为协议名,确定不变
<子协议名>指定目标数据库的种类和具体连接方式
<子名称>指定具体的数据库或者说数据源连接信息(如数据库服务器IP/通信端口号、ODBC数据源名称、连接的用户名/密码等)
子名称的格式和内容随子协议的不同而改变
释二:要实现客户端到服务器端的通信,就必须访问服务器端某一个特定的端口
也就是服务器端的数据库程序一直在监听的通信端口,否则是不可能建立连接的
举例:jdbc:oracle:thin:@166.111.78.98:1521:ora9其中oracle:thin是子协议,166.111.78.98:1521:ora9是子名称
jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=pubs
另外也可以使用属性文件配置环境,即将数据库连接信息(URL、用户名/密码等)保存到专门的属性文件中,而不在程序中直接给出
JDBC—ODBC编程
原理:JDBC驱动程序管理器并不直接操纵数据库驱动程序,而是调用JDBC—ODBC桥驱动程序操纵ODBC驱动程序,进而连接各类型数据库
它的好处就是Java应用程序不需要关心底层用的是哪一种数据库,它所操纵的就是ODBC数据源
而不需要程序来干预由Windows操纵系统进行维护和管理的ODBC数据源的内部的实现
步骤:1)创建ODBC数据源。即把要连接的目标数据库封装成一个ODBC数据源
2)在程序中连接并操作ODBC数据源
通过OCI方式访问Oracle数据库
概述:之前都是采用thin子协议的方式访问Oracle数据库,而thin的驱动方式是纯Java的,即直接Java到数据库,它的效率也比较高
但是还有另外一种选择,即使用OCI(Oracle Call Interface),也就是第二种驱动方式Java到本地API
首先要调用本地已经安装好的Oracle客户端,然后再通过客户端去连接远程的数据库。而OCI的效率也是挺高的
虽然Oracle公司也一直在大力推介OCI的方式,但实际开发中,使用OCI比使用thin的方式还是要少一些
配置:有三种方式,分别为使用Net Configuration Assistant、、使用Net Manager图形化工具、、直接修改数据库配置文件"tnsnames.ora"
可滚动和可更新结果集
概述:早年SUN公司制定的JDBC1.0规范中,结果集只能使用next()从头到尾单向的遍历,不可以向前回滚
而且结果集只能是只读的,即不可以通过结果集更新相应的数据库表中的记录
后来在JDBC2.0中增加了多项新特性,其中就包括支持可滚动和可更新的结果集
类型: 不可滚动:即FORWARD_ONLY。遍历这种结果集的时候只能使用next()单向的向前移动指针,不能反向回滚
滚动敏感:即SCROLL_SENSITIVE。在结果集滚动的过程中,如果数据库中的数据发生了变化,当前的结果集能够感受到这种变化
滚动不敏感:即SCROLL_INSENSITIVE。结果集滚动的过程中,如果数据库表中的数据发生了变化,不它是感受不到这种变化的
敏感说明:比如在执行查询操作之后,滚动结果集的过程中,数据库表中又更新了一些新的符合查询条件的记录
但这些记录不会出现在不敏感的结果集之中。而是会立即出现在敏感的结果集之中
并发模式:只读的(READ_ONLY):不允许对结果集中的数据进行更新,也就是说不允许通过结果集修改数据库中相应的记录
可更新的(UPDATABLE):允许对结果集中的数据进行更新,同时会把对结果集的修改直接同步的保存到数据库中
获取结果:Connection接口中提供的重载方法createStatement()用于获取可滚动/可更新结果集
方法格式为Statement createStatement(int type, int concurrency)
使用可滚动和可更新结果集
对于可滚动结果集,可以使用ResultSet接口中定义的下述方法进行遍历
boolean next() //指向下一条记录
boolean previous() //移到前一条记录
boolean first() //移到第一行记录
boolean last() //移到最后一行记录
void beforeFirst() //移到第一行记录的前面,此时只有在执行完next()后才能指向第一条记录
void afterLast() //移动结果集的末尾,即最后一行的后面
boolean relative(int rows) //按照相对的行数进行位移,正数是向后,负数是向前
boolean absolute(int row) //进行绝对的位移,即移到指定的某行记录
int getRow() //返回当前行号,它的下标是从1开始的
对于可更新结果集,可以使用ResultSet接口中定义的下述方法进行更新操纵
void updateXXX(String columnName,XXX x) //用x值更新指定列。它并没有真正的修改数据库中的数据
void updateXXX(int columnIndex,XXX x) //它更改的只是JVM内存中结果集的内容
void updateRow() //将当前行的更新操作同步到数据库中
void moveToInsertRow() //在当前结果集中插入新的一行
void insertRow() //将插入行的内容插入到此ResultSet对象和数据库中
void moveToCurrentRow() //将光标移动到记住的光标位置,通常为当前行
void deleteRow() //删除当前记录
void cancelRowUpdates() //撤销updateXXX()对当前行的更新操作
预处理语句
概述:java.sql.PreparedStatement接口提供了执行预编译SQL语句的功能,它继承了java.sql.Statement接口
Connection对象的prepareStatement(String sql)方法可创建并返回PreparedStatement对象
预处理语句在执行过程中,效率会稍微高一点。当重复执行同样格式的SQL指令时,可以考虑使用预处理语句
方法:void setXXX(int parameterIndex,XXX x) //设定预处理语句中不确定的参数。。这里parameterIndex是从1开始计算的
ResultSet executeQuery() //执行预处理语句
int executeUpdate() //执行实现更新操作的预处理语句
调用存储过程
概述:java.sql.CallableStatement接口提供了调用数据库服务器端存储过程(Procedure)的功能,它继承了PreparedStatement接口
Connection对象的prepareCall(String sql)方法可创建并返回CallableStatement对象,它会封装具体的调用存储过程的指令
方法:void setXXX(int parameterIndex,XXX x) //设定调用存储过程过程中的参数
boolean execute() //执行它所要调用的存储过程
事务处理
概述:和数据库中的事务管理模式相对应,JDBC中的Connection对象也可分为自动提交和非自动提交两种模式
所谓的自动提交是指对数据库的任何更新操作都立即提交并永久生效,即不可反悔,不可撤销
对于非自动提交是指在DML操作过程中,可以进行回滚或者一定程度的撤销
JDBC驱动程序的默认事务管理模式为"自动提交"
方法:Connection接口提供的事务处理相关方法如下
voic setAutoCommit(boolean autoCommit) //设置是否自动提交,默认为自动提交
boolean getAutoCommit() //获取当前自动提交的状态
void commit() //提交先前未提交的事务。前提是在非自动提交的状态下
void rollback() //回滚(撤销)先前所有未提交的事务。前提是在非自动提交的状态下
部分回滚:从JDBC3.0开始支持在事务中使用保存点(Savepoint)以实现对数据库事务的进一步控制,即支持部分回滚功能
java.sql.Savepoint接口表示数据库事务中的保存点
在Connection对象的rollback()方法中可以对当前事务中的保存点进行引用,从而将事务回滚到该保存点
批处理
概述:从JDBC2.0开始提供了对数据库操作的批处理(Batch Processing)功能
使用批处理功能避免了向数据库进行一连串的调用,从而可以显著提高程序的运行效率
实际是将多条语句(通常是insert、update、delete)使用批处理功能一次性的传给数据库
方法:Statement接口提供了批处理的相关方法
void addBatch(String sql) //向当前的批处理任务队列中加入一条新的指令
int[] executeBatch() //执行当前的批处理任务
void clearBatch() //清除当前的批处理的任务序列
BLOB/CLOB类型——高级SQL类型
概述:JDBC2.0开始引入了对应于SQL99标准的多种高级数据类型,其中最重要的是两种大对象类型BLOB和CLOB
BLOB(Binary Large OBject,二进制大对象)类型用于保存大规模的二进制数据
CLOB(Character Large OBject,文本大对象)类型用于保存大规模的文本数据。单个字段的最大容量可以达到4G
补充:在数据库客户端工具中执行普通的select * from table;查询语句,是不能够完美的获取和显示BLOB或CLOB字段的