1、描述:JDBC作为一种中间件,以实现Java应用程序与数据库之间的接口功能。JDBC API把java命令转换为通用SQLY语句,提交此查询给JDBC Driver,由JDBC Driver把查询转换为特定数据库所能理解的形式。JDBC Driver也检索SQL查询的结果,并把它转换为可为Java应用使用的等价的JDPC API类与对象。JDBC实际上包含了一组类与接口,这些编程接口定义在Java API的java.sql程序包和javax.sql程序包中。
2、
§Driver接口:每一个数据库驱动程序都必须实现Driver接口。在编写程序需要连接数据库时,需要装载由数据库厂商提供的数据库驱动程序。装载方法:Class.forname("相应驱动程序");
§DriverManager类:JDBC的管理层,作用于用户和驱动程序之间。DriverManager类跟踪可用的驱动程序,并在数据库和相应程序之间建立连接,同时也处理诸如驱动程序登录时间控制及登录和跟踪信息的显示等事务。DriverManager类激发getConnection()方法时,DriverManager类首先从它已经加载的驱动程序连接池中找一个可以接受该数据库的URL的驱动程序,然后请求驱动程序使用相关的数据库URL去连接数据库。
§Connection接口:在加载的Driver和数据库之间建立连接,必须创建一个Connection class的实例,其中包括数据库的基本信息。连接过程包括执行SQL语句和返回SQL语句的结果,一个应用程序可以同时连接多个数据库,但一般在开发过程中只有一个。DriverManager的getConnection()方法将建立在JDBC URL中定义的数据库的Connection连接上,如:Connection conn=DriverManager.getConnection(url,user,password);
§Statement接口:Statement是提供在基层上运行SQL语句的,Connection接口提供了生成Statement的方法,如:Statement stmt=conn.createStatement();。Statement接口定义了三种执行SQL语句的方法来处理返回不同结果的SQL命令:
executeQuery()方法执行DML中的查询语句,并返回ResultSet接口对象。
executeUpdate()方法一般执行数据更新语句,返回值为所影响的行数。也可以执行DDL语句,此时不返回任何内容。
execute()方法通常用来执行返回多个值的SQL语句,如果SQL返回ResultSet接口对象,则execute()方法返回boolean值true;如果SQL语句返回的是更新行数,则execute()方法返回false。
§ResultSet接口:Result是包含查询结果的结果集,该接口把查询出来的结果作了封装,能过ResultSet.next()方法可以把当前指针向下移动,进行读取,列从1开始编号。为了获得最大的可移植性,应该按从左到右的顺序读取每行中的结果集列,而且每列只能读取一次。当把起始指针指向结果集的最后一条记录时,就可以通过此方法把查询结果倒序输出。
§PreparedStatement接口:用于实现发送带参数的预编译SQL语句到数据库并返回执行结果的功能,这在循环中重复执行某条语句时非常有效。PreparedStatement接口对象可以为作为IN参数的变量设置占位符“?”,这些参数用setX方法进行设置。设置IN参数的setX方法必须指定与定义的输入参数的SQL数据类型兼容的类型。
§CallableStatement接口用于实现调用数据库存储过程的功能。
§DatabaseMetaData接口可获得数据库的特定信息,其对象生成方式:
DatabaseMetaData dmd=conn.getMetaData();
§ResultSetMetaData接口可用于获取关于ResultSet对象中列的类型和属性信息。
§ParameterMetaData接口可用于获取关于PreparedStatement对象中参数的类型和属性信息。
3、JDBC直接连接Oracle数据库
(1)加载及注册驱动程序:
Class.forName("oracle.dbc.driver.OracleDriver").newInstance();
加载驱动程序后,一般会建立一个Driver对象,并经由调用DriverManager.registerDriver()来自动注册此对象。
附:导入驱动程序的方式,如果使用eclipse开发工具,在你的项目上单击右键,选择properties,打开属性对话框,从“Java Build Path”选项中选择“Libraries”选项卡,单击“Add External JARs”找到文件classes12.jar或ojdbc14.jar,将其导入。如果你仅仅使用控制台调试程序,可以把两个文件中的一个解压,找到oracle文件夹,复制到你含装载驱动程序语句的类所在的目录即可。这两个文件均在...\jdbc\lib目录下,个目录是oracle安装目录,根据你的情况寻找,如D:\oracle\ora92\jdbc\lib。
(2)建立连接:
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="scott";
String password="tiger";
Connection conn=DriverManager.getConnection(url,user,password);
jdbc url 的标准语法如下:::
protocol:主要通讯协议
subprotocol:次要的通讯协议,其驱动的名称
data source identifier:数据来源
如例子: "jdbc:oracle:thin"是通讯协议,@后"为有效的主机地址,然后是端口号,默认的是:1521,然后是你的数据源 。也可以采用如下连接方式:
connection con= drivermanager.getconnection("jdbc:oracle:thin:user/password@localhost:1521:wzz");
(3)发送并执行sql语句:
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
(4) 清理工作
例子:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Test
{
public static void main(String[] args)
{
String sql="select * from emp";
try
{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="scott";
String password="tiger";
Connection conn=DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())
{
System.out.print(rs.getString(1)+" ");
System.out.print(rs.getString(2)+" ");
System.out.print(rs.getString(3)+" ");
System.out.print(rs.getString(4)+" ");
System.out.println();
}
rs.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
4 、一个JDBC 连接数据库的综合操作:对book表进行操作
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.Date;
public class OracleCon
{
private Connection conn=null;
private Statement stmt=null;
OracleCon()
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="mxy";
String password="606606";
conn=DriverManager.getConnection(url,user,password);
}
catch (Exception e)
{
e.printStackTrace();
}
}
//查询数据库中的数据
public void selectDb(String sql)throws SQLException
{
stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while (rs.next())
{
for (int i = 1; i <=rs.getMetaData().getColumnCount(); i++)
{
System.out.print(rs.getString(i) + " ");
}
System.out.println();
}
}
//增、删、改数据库中的数据
public boolean updateDb(String sql)throws SQLException
{
boolean isOk=false;
stmt=conn.createStatement();
isOk=stmt.executeUpdate(sql)>0;
return isOk;
}
//使用PredparedStatement接口,进行预编译,实现插入数据
public boolean psDb(String NO,String TITLE,String AUTHOR,
String PUBLISH,Date PUB_DATE,Double PRICE)throws SQLException
{
//如果insert into的字段与关键字重名,应改为[NO],这里假定NO是关键字
String strUpdate="insert into book(NO,TITLE,AUTHOR," +
"PUBLISH,PUB_DATE,PRICE) values(?,?,?,?,?,?)";
PreparedStatement stat=conn.prepareStatement(strUpdate);
stat.setString(1, NO);
stat.setString(2,TITLE);
stat.setString(3,AUTHOR);
stat.setString(4,PUBLISH);
stat.setDate(5,PUB_DATE);
stat.setDouble(6,PRICE);
return stat.executeUpdate()>0?true:false;
}
//断开和数据库的连接
public void dbClose()
{
try
{
if(conn!=null)
{
conn.close();
conn=null;
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
import java.sql.Date;
public class Test
{
public static void main(String[] args)
{
Date date=Date.valueOf("2007-09-01");
OracleCon dbCon=null;
try
{
dbCon=new OracleCon();
//查询book表的信息
dbCon.selectDb("select * from book");
//往book表插入一条数据
dbCon.updateDb("insert into book values" +
"(100009,'完全自学java手册','马军等','机械工业出版社'," +
"TO_DATE('20070901','yyyy-mm-dd'),49.00)");
//修改book表中的数据
dbCon.updateDb("update book set author='马军、王灏等' where no=100009");
//删除book表中的数据
dbCon.updateDb("delete from book where NO=100009");
//发送带参数的预编译SQL语句向book插入一条数据;
dbCon.psDb("100009","完全自学java手册", "马军等", "机械工业出版社",
date,49.00);
//删除book表中的数据
dbCon.updateDb("delete from book where NO=100009");
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
dbCon.dbClose();
dbCon=null;
}
}
}
5 、预处理与存储过程
预处理就是先构造好SQL语句,然后再发给SQL解释器,第一次解释的结果将会被保留下来,以后重新执行预处理语句时,使用该解释,运行速度会更快。存储过程与预处理思想很相似,它是SQL语句和可选控制流语句的预处理集合,以一个名称作一个单元处理,而不像预处理只有单个语句,这使得客户端发送到数据库的请求减少了,可以有效地减少网络拥塞情况的发生。
CallableStatement接口用于实现调用数据库存储过程的功能。
例子:调试中~~
6、数据库元数据操作
元数据是一种关于数据的数据,用来描述数据库的功能与配置,通常包括数据库元数据、结果集元数据和参数元数据。下面是一个结果集元数据的例子:
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
public class Test
{
public static void main(String args[])
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@localhost:1521:wzz";
String user="mxy";
String password="606606";
Connection conn=DriverManager.getConnection(url,user,password);
Statement stat=conn.createStatement();
ResultSet rs=stat.executeQuery("select * from dept");
ResultSetMetaData rsmd=rs.getMetaData();
ArrayList<String> al=new ArrayList<String>();
for (int i=1;i<=rsmd.getColumnCount();i++)
{
al.add(rsmd.getColumnName(i));
}
for(int i=0;i<al.size();i++)
{
System.out.println(al.get(i));
}
conn.close();
}
catch(Exception err)
{
err.printStackTrace();
}
}
}