JDBC是J2EE的一个重要组成部分,也是我们软件开发经常使用的一项重要技术。掌握JDBC对于JAVA软件开发人员来说,是一个非常重要的技能。下面我就来讲讲我对JDBC的一些看法。
什么是JDBC
JDBC即Java DataBase Connectivity,它是由一系列JAVA接口规范组成的、用于访问数据库的标准。它只提供了标准的访问接口,但却并没有对其进行实现,而具体的实现则都是由各数据库开发厂商或者其它组织来完成的。所以通常在用JDBC访问数据库的时候,都会加载第三方软件包。
JDBC的种类
JDBC共分四种,下面我就来一一介绍分别有哪四种JDBC。
第一,JDBC-ODBC桥驱动。ODBC即Open DataBase Connectivity,它是Microsoft公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。JDBC-ODBC桥驱动即利用ODBC驱动程序提供JDBC访问。。但必须将ODBC二进制代码加载到使用该驱动程序的每个客户机上。
第二,本地API-部分用JAVA来编写的驱动程序:这种类型的驱动程序把客户机API上的JDBC调用转化为ORACLE,DB2,SQLSERVER或其它DBMS的调用。也要求将某些二进制代码加载到每台客户机上。
第三,JDBC网络纯JAVA驱动程序:这种驱动程序将JDBC转换为与DBMS无关的网络协议,然后发送到一个中间服务器上,由这些中间服务器连接到数据库并访问数据库。
第四,本地协议纯JAVA驱动程序:这种驱动程序将JDBC调用直接转换为DBMS所使用的协议。这允许客户机机器上直接调用DBMS服务器。例如ORACLE的THIN驱动就是第4类驱动。
目前3,4类驱动用得是最多的。
Driver格式
JDBC的驱动格式一般是这样子的:jdbc:<子协议>:<子名称>。
A.jdbc指的是jdbc协议。所有的Driver都是用的jdbc协议。
B.<子协议>:根据不同厂商而不同。
C.<子名称>:根据协议不同,参数也不同,但需要足够的参数能够定位数据库。
JDBC编码
在访问数据库时,经常会遇到JDBC的编码问题,比如说插入的中文,取出来如果不经显示的字符编码转换,就可以显示为乱码。这是与数据库的存储编码有关的,比如MySql如果不指定数据库的存储编码,那么默认的编码为latin1,效果和ISO-8859-1一样。如果想不用转换就能够正常显示,可以将数据库的编码设置为GBK或者其它编码。如果在数据库编码为latin1时存储也为GBK,在数据库连接url中加上一些参数,也可以实现此功能。例如MySql数据库可以这么设:url="jdbc:mysql://localhost:3306/jsp?useUnicode=true&characterEncoding=GBK"。
什么是JDBC
JDBC即Java DataBase Connectivity,它是由一系列JAVA接口规范组成的、用于访问数据库的标准。它只提供了标准的访问接口,但却并没有对其进行实现,而具体的实现则都是由各数据库开发厂商或者其它组织来完成的。所以通常在用JDBC访问数据库的时候,都会加载第三方软件包。
JDBC的种类
JDBC共分四种,下面我就来一一介绍分别有哪四种JDBC。
第一,JDBC-ODBC桥驱动。ODBC即Open DataBase Connectivity,它是Microsoft公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。JDBC-ODBC桥驱动即利用ODBC驱动程序提供JDBC访问。。但必须将ODBC二进制代码加载到使用该驱动程序的每个客户机上。
第二,本地API-部分用JAVA来编写的驱动程序:这种类型的驱动程序把客户机API上的JDBC调用转化为ORACLE,DB2,SQLSERVER或其它DBMS的调用。也要求将某些二进制代码加载到每台客户机上。
第三,JDBC网络纯JAVA驱动程序:这种驱动程序将JDBC转换为与DBMS无关的网络协议,然后发送到一个中间服务器上,由这些中间服务器连接到数据库并访问数据库。
第四,本地协议纯JAVA驱动程序:这种驱动程序将JDBC调用直接转换为DBMS所使用的协议。这允许客户机机器上直接调用DBMS服务器。例如ORACLE的THIN驱动就是第4类驱动。
目前3,4类驱动用得是最多的。
Driver格式
JDBC的驱动格式一般是这样子的:jdbc:<子协议>:<子名称>。
A.jdbc指的是jdbc协议。所有的Driver都是用的jdbc协议。
B.<子协议>:根据不同厂商而不同。
C.<子名称>:根据协议不同,参数也不同,但需要足够的参数能够定位数据库。
JDBC编码
在访问数据库时,经常会遇到JDBC的编码问题,比如说插入的中文,取出来如果不经显示的字符编码转换,就可以显示为乱码。这是与数据库的存储编码有关的,比如MySql如果不指定数据库的存储编码,那么默认的编码为latin1,效果和ISO-8859-1一样。如果想不用转换就能够正常显示,可以将数据库的编码设置为GBK或者其它编码。如果在数据库编码为latin1时存储也为GBK,在数据库连接url中加上一些参数,也可以实现此功能。例如MySql数据库可以这么设:url="jdbc:mysql://localhost:3306/jsp?useUnicode=true&characterEncoding=GBK"。
详解一
1、JDBC(Java Database Connection):java连接数据库统一接口API,底层主要通过直接的JDBC驱动和
JDBC-ODBC桥驱动实现与数据库的连接。
1>.JDBC驱动程序类型:
<1>.JDBC-ODBC桥加ODBC驱动程序:需要ODBC驱动,适合于企业网或三层结构应用程序
<2>.本地API:需要驱动程序的二进制代码支持
<3>.JDBC网络纯java驱动程序:将JDBC转换为与DBMS无关的网络协议,又被某服务器转换为一种DBMS
协议,以操作各种数据库
<4>.本地协议纯java驱动程序:将JDBC调用直接转换成JDBC所使用的网络协议
2、JDBC操作基本流程:
1>.导入驱动:实例化时自动向DriverManager注册(DriverManager.registerDriver())
<1>.Class.forName(driver)
<2>.Class.forName(driver).newInstance()
<3>.new driver()
2>.取得数据库连接(Connect to the DataBase)
<1>.用DriverManager取数据库连接
Connection cn = DriverManager.getConnection(url,uid,pwd);
<2>.用jndi(java的命名和目录服务)方式:多用于jsp
Context ctx = (Context) new InitialContext().lookup("java:comp/env");
DataSource ds = (DataSource) ctx.lookup(jndi);
Connection cn = ds.getConnection();
3>.执行sql语句(Execute the SQL)
DataSource ds = (DataSource) ctx.lookup(jndi);
Connection cn = ds.getConnection();
3>.执行sql语句(Execute the SQL)
<1>.用Statement来执行sql语句
Statement sm = cn.createStatement();
sm.executeQuery(sql); // 执行数据查询语句(select)
sm.executeUpdate(sql); // 执行数据更新语句(delete、update、insert、drop等)
sm.executeQuery(sql); // 执行数据查询语句(select)
sm.executeUpdate(sql); // 执行数据更新语句(delete、update、insert、drop等)
<2>.用PreparedStatement来执行sql语句
String sql = "insert into user (id,name) values (?,?)";
PreparedStatement ps = cn.prepareStatement(sql);
ps.setInt(1,xxx);
ps.setString(2,xxx);
...
ResultSet rs = ps.executeQuery(); // 查询
int c = ps.executeUpdate(); // 更新
PreparedStatement ps = cn.prepareStatement(sql);
ps.setInt(1,xxx);
ps.setString(2,xxx);
...
ResultSet rs = ps.executeQuery(); // 查询
int c = ps.executeUpdate(); // 更新
4>.处理执行结果:
<1>.查询语句,返回记录集ResultSet
<2>.更新语句,返回数字,表示该更新影响的记录数
<3>.ResultSet的方法:while(re.next())
<2>.更新语句,返回数字,表示该更新影响的记录数
<3>.ResultSet的方法:while(re.next())
next(),将游标往后移动一行,如果成功返回true;否则返回false
getInt("id")或getSting("name"),返回当前游标下某个字段的值
getInt("id")或getSting("name"),返回当前游标下某个字段的值
5>.释放数据库连接
rs.close();
ps.close(); /stat.close();
con.close();
3、创建可滚动、更新的记录集
1>.创建Statement时指定参数:该Statement取得的ResultSet就是可滚动的
1>.创建Statement时指定参数:该Statement取得的ResultSet就是可滚动的
Statement sm = cn.createStatement(ResultSet.TYPE_SCROLL_ENSITIVE,
ResultSet.CONCUR_READ_ONLY);
2>.创建PreparedStatement时指定参数
2>.创建PreparedStatement时指定参数
PreparedStatemet ps = cn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rs.absolute(9000);
4、批量更新
1>.Statement:可执行多个sql语句(delete、update、insert等或兼有),批量更新
Statement sm = cn.createStatement();
sm.addBatch(sql1);
sm.addBatch(sql2);
sm.addBatch(sql1);
sm.addBatch(sql2);
...
sm.executeBatch()
2>.PreparedStatement:可把一个sql语句,变换参数多次执行,一次更新
PreparedStatement ps = cn.preparedStatement(sql);
{
ps.setXXX(1,xxx);
...
ps.addBatch();
}
ps.executeBatch();
{
ps.setXXX(1,xxx);
...
ps.addBatch();
}
ps.executeBatch();
5、事务的处理
1>.关闭Connection的自动提交
cn.setAutoCommit(false);
2>.执行一系列sql语句:执行新sql前,以前的Statement(或PreparedStatemet)须close
Statement sm ;
sm = cn.createStatement(insert into user...);
sm.executeUpdate();
sm.close();
cn.setAutoCommit(false);
2>.执行一系列sql语句:执行新sql前,以前的Statement(或PreparedStatemet)须close
Statement sm ;
sm = cn.createStatement(insert into user...);
sm.executeUpdate();
sm.close();
sm = cn.createStatement("insert into corp...);
sm.executeUpdate();
sm.close();
sm.executeUpdate();
sm.close();
3>.提交
cn.commit();
4>.如果发生异常,那么回滚
cn.rollback();
cn.commit();
4>.如果发生异常,那么回滚
cn.rollback();
6、SQL语句简介:
1>.Select ... from T Where...
2>.Insert into T(...)values(...)
3>.Create Table T(...)
4>.Delete from T Where ...
5>.Update T set f1=... and f2 =... where ...
6>.Drop table T
7、JDBC示例:
7、JDBC示例:
class DBUtil{
//local variable
String driver = null;
String url = null;
Statement stat = null;
//set local variable value
public DBUtil(String driver,String url){
this.driver = driver;
this.url = url;
}
//get con
public Connection getConnection() throws ClassNotFoundException, SQLException{
Connection con = null;
Class.forName(driver);
con = DriverManager.getConnection(url);
return con;
}
//execute select sentence
public List executeQuery(String sql){
ResultSet rs = null;
Connection con = null;
try {
con = getConnection();
Statement stat = con.createStatement();
rs = stat.executeQuery(sql);
while(rs.next()){
rs.getString("");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException ce) {
ce.printStackTrace();
} finally{
try{
if( null == con){
con.close();
con = null;
}
if( null == stat){
stat.close();
stat = null;
}
if( null == rs){
rs.close();
rs = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
//execute proceduce
}
//local variable
String driver = null;
String url = null;
Statement stat = null;
//set local variable value
public DBUtil(String driver,String url){
this.driver = driver;
this.url = url;
}
//get con
public Connection getConnection() throws ClassNotFoundException, SQLException{
Connection con = null;
Class.forName(driver);
con = DriverManager.getConnection(url);
return con;
}
//execute select sentence
public List executeQuery(String sql){
ResultSet rs = null;
Connection con = null;
try {
con = getConnection();
Statement stat = con.createStatement();
rs = stat.executeQuery(sql);
while(rs.next()){
rs.getString("");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException ce) {
ce.printStackTrace();
} finally{
try{
if( null == con){
con.close();
con = null;
}
if( null == stat){
stat.close();
stat = null;
}
if( null == rs){
rs.close();
rs = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
//execute proceduce
}
本文出自 “不服不行” 博客,转载请与作者联系!