什么是JDBC?
Java語(yǔ)言訪(fǎng)問(wèn)數據庫的一種規范,是一套API
JDBC (Java Database Connectivity) API,即Java數據庫編程接口,是一組標準的Java語(yǔ)言中的接口和類(lèi),使用這些接口和類(lèi),Java客戶(hù)端程序可以訪(fǎng)問(wèn)各種不同類(lèi)型的數據庫。比如建立數據庫連接、執行SQL語(yǔ)句進(jìn)行數據的存取操作。
JDBC規范采用接口和實(shí)現分離的思想設計了Java數據庫編程的框架。接口包含在java.sql及javax.sql包中,其中java.sql屬于JavaSE,javax.sql屬于JavaEE。這些接口的實(shí)現類(lèi)叫做數據庫驅動(dòng)程序,由數據庫的廠(chǎng)商或其它的廠(chǎng)商或個(gè)人提供。
為了使客戶(hù)端程序獨立于特定的數據庫驅動(dòng)程序,JDBC規范建議開(kāi)發(fā)者使用基于接口的編程方式,即盡量使應用僅依賴(lài)java.sql及javax.sql中的接口和類(lèi)。

JDBC驅動(dòng)程序:
什么是JDBC驅動(dòng)程序?
這些是各個(gè)數據庫廠(chǎng)家根據JDBC的規范制作的JDBC實(shí)現類(lèi)
JDBC驅動(dòng)程序的四種類(lèi)型:
1. 第一種類(lèi)型的驅動(dòng)程序的實(shí)現是通過(guò)將JDBC的調用全部委托給其它編程接口來(lái)實(shí)現的,比如ODBC。這種類(lèi)型的驅動(dòng)程序需要安裝本地代碼庫,即依賴(lài)于本地的程序,所以便攜性較差。比如JDBC-ODBC橋驅動(dòng)程序
2. 第二種類(lèi)型的驅動(dòng)程序的實(shí)現是部分基于Java語(yǔ)言的。即該驅動(dòng)程序一部分是用Java語(yǔ)言編寫(xiě),其它部分委托本地的數據庫的客戶(hù)端代碼來(lái)實(shí)現。同類(lèi)型1的驅動(dòng)一樣,該類(lèi)型的驅動(dòng)程序也依賴(lài)本地的程序,所以便攜性較差
3. 第三種類(lèi)型的驅動(dòng)程序的實(shí)現是全部基于JAVA語(yǔ)言的。該類(lèi)型的驅動(dòng)程序通常由某個(gè)中間件服務(wù)器提供,這樣客戶(hù)端程序可以使用數據庫無(wú)關(guān)的協(xié)議和中間件服務(wù)器進(jìn)行通信,中間件服務(wù)器再將客戶(hù)端的JDBC調用轉發(fā)給數據庫進(jìn)行處理
4. 第四種類(lèi)型的驅動(dòng)程序的實(shí)現是全部基于JAVA語(yǔ)言的。該類(lèi)型的驅動(dòng)程序中包含了特定數據庫的訪(fǎng)問(wèn)協(xié)議,使得客戶(hù)端可以直接和數據庫進(jìn)行通信
JDBC類(lèi)結構:
DriverManager
Driver Driver
Connection Connection
Statement Statement
Resultset Resultset
DriverManager:這個(gè)是一個(gè)實(shí)現類(lèi),它是一個(gè)工廠(chǎng)類(lèi),用來(lái)生產(chǎn)Driver對象的
這個(gè)類(lèi)的結構設計模式為工廠(chǎng)方法
Driver:這是驅動(dòng)程序對象的接口,它指向一個(gè)實(shí)實(shí)在在的數據庫驅動(dòng)程序對象,那么這個(gè)數據庫驅動(dòng)程序對象是從哪里來(lái)的呢?
DriverManager工廠(chǎng)中有個(gè)方法:getDriver(String URL),通過(guò)這個(gè)方法可以得到驅動(dòng)程序對象,這個(gè)方法是在各個(gè)數據庫廠(chǎng)商按JDBC規范設計的數據庫驅動(dòng)程序包里的類(lèi)中靜態(tài)實(shí)現的,也就是在靜態(tài)塊中
Connection:這個(gè)接口可以制向一個(gè)數據庫連接對象,那么如何得到這個(gè)連接對象呢?
是通過(guò)DriverManager工廠(chǎng)中的getConnection(String URL)方法得到的
Statement:用于執行靜態(tài)的SQL語(yǔ)句的接口,通過(guò)Connection中的createStatement方法得到的
Resultset:用于指向結果集對象的接口,結果集對象是通過(guò)Statement中的execute等方法得到的
JAVA使用JDBC訪(fǎng)問(wèn)數據庫的步驟:
1. 得到數據庫驅動(dòng)程序
2. 創(chuàng )建數據庫連接
3. 執行SQL語(yǔ)句
4. 得到結果集
5. 對結果集做相應的處理(增,刪,改,查)
6. 關(guān)閉資源:這里釋放的是DB中的資源

設置classpath:
1. 在java文件中起的包名一定要是工程基目錄下的子目錄,classpath:基目錄
2. .jar包,需要將這個(gè).jar包的路徑包括這個(gè)文件的全名添加到classpath中來(lái)
Oracle連接字符串的書(shū)寫(xiě)格式:
“oracle:jdbc:thin:@ip:1521: 數據庫名”,”數據庫用戶(hù)名”,”數據庫密碼”
簡(jiǎn)單的例子:
package moudule1.first;
import java.sql.*;
public class FirstJdbc
{
public static void main(String[] args)
{
String sql="select * from yuchen_user";
Connection con=null;
Statement st=null;
ResultSet rs=null;
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:name", "scott","tiger");
st=con.createStatement();
rs=st.executeQuery(sql);
while(rs.next())
{
System.out.println(rs.getInt("id"));
System.out.println(rs.getString("name"));
}
}catch(Exception e)
{
e.printStackTrace();
}finally
{
try
{
con.close();
}catch(Exception e)
{}
try
{
st.close();
}catch(Exception e)
{
}
try
{
rs.close();
}catch(Exception e)
{
}
}
}
}
常用數據庫的驅動(dòng)程序及JDBC URL:
Oracle數據庫:
驅動(dòng)程序包名:ojdbc14.jar
驅動(dòng)類(lèi)的名字:oracle.jdbc.driver.OracleDriver
JDBC URL:jdbc:oracle:thin:@dbip:port:databasename
說(shuō)明:驅動(dòng)程序包名有可能會(huì )變
JDBC URL中黑色字體部分必須原封不動(dòng)的保留,為該驅動(dòng)識別的URL格式。紅色字體部分需要根據數據庫的安裝情況填寫(xiě)。其中各個(gè)部分含義如下:
dbip –為數據庫服務(wù)器的IP地址,如果是本地可寫(xiě):localhost或127.0.0.1。
port –為數據庫的監聽(tīng)端口,需要看安裝時(shí)的配置,缺省為1521。
databasename –為數據庫的SID,通常為全局數據庫的名字。
舉例如果要訪(fǎng)問(wèn)本地的數據庫allandb,端口1521,那么URL寫(xiě)法如下:
jdbc:oracle:thin:@localhost:1521:allandb 下載地址如下:
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html
SQL Server數據庫
驅動(dòng)程序包名:msbase.jar mssqlserver.jar msutil.jar
驅動(dòng)類(lèi)的名字:com.microsoft.jdbc.sqlserver.SQLServerDriver
JDBC URL:jdbc:microsoft:sqlserver://dbip:port;DatabaseName=databasename
說(shuō)明:驅動(dòng)程序包名有可能會(huì )變
JDBC URL中黑色字體部分必須原封不動(dòng)的保留,為該驅動(dòng)識別的URL格式。紅色字體部需要根據數據庫的安裝情況填寫(xiě)。其中各個(gè)部分含義如下:
dbip –為數據庫服務(wù)器的IP地址,如果是本地可寫(xiě):localhost或127.0.0.1。
port –為數據庫的監聽(tīng)端口,需要看安裝時(shí)的配置,缺省為1433。
databasename –數據庫的名字。
舉例如果要訪(fǎng)問(wèn)本地的數據庫allandb,端口1433,那么URL寫(xiě)法如下:
jdbc: microsoft: sqlserver:@localhost:1433; DatabaseName =allandb
下載地址:http://www.microsoft.com/downloads/details.aspx
MySQL數據庫
驅動(dòng)程序包名:mysql-connector-java-3.1.11-bin.jar
驅動(dòng)類(lèi)的名字:com.mysql.jdbc.Driver
JDBC URL:jdbc:mysql://dbip:port/databasename
說(shuō)明:驅動(dòng)程序包名有可能會(huì )變
JDBC URL中黑色字體部分必須原封不動(dòng)的保留,為該驅動(dòng)識別的URL格式。紅色字體部需要根據數據庫的安裝情況填寫(xiě)。其中各個(gè)部分含義如下:
dbip –為數據庫服務(wù)器的IP地址,如果是本地可寫(xiě):localhost或127.0.0.1。
port –為數據庫的監聽(tīng)端口,需要看安裝時(shí)的配置,缺省為3306。
databasename –數據庫的名字。
舉例如果要訪(fǎng)問(wèn)本地的數據庫allandb,端口1433,那么URL寫(xiě)法如下:
jdbc:mysql://localhost:3306/allandb
下載地址:http://dev.mysql.com/downloads/connector/j/
Access數據庫
驅動(dòng)程序包名:該驅動(dòng)程序包含在JavaSE中,不需要額外安裝。
驅動(dòng)類(lèi)的名字:sun.jdbc.odbc.JdbcOdbcDriver
JDBC URL:jdbc:odbc:datasourcename
說(shuō)明:該驅動(dòng)只能工作在Windows系統中,首先需要在操作系統中建立一個(gè)可以訪(fǎng)問(wèn)Access數據庫的本地數據源(ODBC),如果名字為allandb,那么URL寫(xiě)法如下:
jdbc:odbc:allandb
PreparedStatement接口:
預編譯的sql語(yǔ)句對象
作用: 解決了書(shū)寫(xiě)sql語(yǔ)句時(shí)一些特殊的字符與sql保留字符沖突的問(wèn)題,非常方便
/**
*知識點(diǎn):
*PreparedStatement接口及方法的使用
*程序目標:
*java文件:
*PreparedInsert.java:連接數據庫,插入一條數據
*JdbcUtil.java:實(shí)現一個(gè)工具類(lèi),功能:1.連接數據庫 2.關(guān)閉資源
*/
package moudule1.preparedstatement;
import java.sql.*;
import moudule1.com.*;
public class PreparedInsert
{
public static void main(String[] args)
{
String sql="insert into yuchen_user (id,name) values (?,?)";
System.out.println(sql);
Connection con=null;
PreparedStatement ps=null;
try{
con=JdbcUtil.getConnection();
ps=con.prepareStatement(sql);
ps.setInt(1,2);
ps.setString(2,"zhangsan");
ps.executeUpdate();
ps.setInt(1,3);
ps.setString(2,"lisi");
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.close(con,ps);
}
}
}
package moudule1.com;
import java.sql.*;
public class JdbcUtil{
public static Connection getConnection() throws Exception{
Class.forName("oracle.jdbc.driver.OracleDriver");
return DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:name", "scott","tiger");
}
public static void close(Connection con,Statement st){
close(con);
close(st);
}
public static void close(Connection con,Statement st,ResultSet rs){
close(con,st);
close(rs);
}
public static void close(Connection con){
try{
con.close();
}catch(Exception e){
}
}
public static void close(Statement st){
try{
st.close();
}catch(Exception e){
}
}
public static void close(ResultSet rs){
try{
rs.close();
}catch(Exception e){
}
}
}
數據庫的增刪改查的例子:
/**
*知識點(diǎn):
*JDBC+SQL+ORACLE
*程序目標:
*UserDao.java:實(shí)現了數據庫的增刪改查
*JdbcUtil.java:工具類(lèi),有連庫和關(guān)閉資源的方法
*/
package moudule1.idus;
import java.sql.*;
import moudule1.com.*;
public class UserDao{
private String sql;
private Connection con;
private Statement st;
private ResultSet rs;
public UserDao(){
sql=null;
con=null;
st=null;
rs=null;
}
public void insert(){
sql="insert into yuchen_user (id,name) values(";
sql+="4,‘zhouwu‘)";
System.out.println(sql);
try{
con=JdbcUtil.getConnection();
st=con.createStatement();
st.executeUpdate(sql);
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.close(con,st);
}
}
public void delete(){
sql="delete from yuchen_user where id=2";
System.out.println(sql);
try{
con=JdbcUtil.getConnection();
st=con.createStatement();
st.executeUpdate(sql);
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.close(con,st);
}
}
public void update(){
sql="update yuchen_user set name=‘liumang‘ where id=1";
System.out.println(sql);
try{
con=JdbcUtil.getConnection();
st=con.createStatement();
st.executeUpdate(sql);
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.close(con,st);
}
}
public void select(){
sql="select * from yuchen_user";
System.out.println(sql);
try{
con=JdbcUtil.getConnection();
st=con.createStatement();
rs=st.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getInt(1));
System.out.println(rs.getString(2));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.close(con,st,rs);
}
}
public static void main(String[] args){
UserDao ud=new UserDao();
ud.select();
ud.insert();
ud.select();
ud.update();
ud.select();
ud.delete();
ud.select();
}
}
一些常用的方法:
/**
*知識點(diǎn):
*execute方法,getResultSet(),getUpdateCount()
*程序目標:
*JdbcUtil.java:工具類(lèi),連接數據庫,關(guān)閉資源
*sqlExecutor.java:命令行參數輸入sql語(yǔ)句,并執行該語(yǔ)句
*/
package moudule1.fangfa;
import java.sql.*;
import moudule1.com.*;
public class sqlExecutor{
public static void main(String[] args){
Connection con=null;
Statement st=null;
try{
con=JdbcUtil.getConnection();
st=con.createStatement();
boolean str=st.execute(args[0]);
if(str){
ResultSet rs=st.getResultSet();
while(rs.next()){
System.out.println(rs.getInt("id")+":"+rs.getString("name"));
}
rs.close();
}else{
int row=st.getUpdateCount();
System.out.println(row);
}
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtil.close(con,st);
}
}
}
2. 補充
加載及注冊JDBC驅動(dòng)程序
Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.jdbc.Driver").newInstance();
JDBC URL 定義驅動(dòng)程序與數據源之間的連接
標準語(yǔ)法:
<protocol(主要通訊協(xié)議)>:<subprotocol(次要通訊協(xié)議,即驅動(dòng)程序名稱(chēng))>:<data source identifier(數據源)>
MySQL的JDBC URL格式:
jdbc:mysql//[hostname][:port]/[dbname][?param1=value1][¶m2=value2]….
示例:jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password
常見(jiàn)參數:
user 用戶(hù)名
password 密碼
autoReconnect 聯(lián)機失敗,是否重新聯(lián)機(true/false)
maxReconnect 嘗試重新聯(lián)機次數
initialTimeout 嘗試重新聯(lián)機間隔
maxRows 傳回最大行數
useUnicode 是否使用Unicode字體編碼(true/false)
characterEncoding 何種編碼(GB2312/UTF-8/…)
relaxAutocommit 是否自動(dòng)提交(true/false)
capitalizeTypeNames 數據定義的名稱(chēng)以大寫(xiě)表示
建立連接對象
String url="jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password";
Connection con = DriverManager.getConnection(url);
建立SQL陳述式對象(Statement Object)
Statement stmt = con.createStatement();
執行SQL語(yǔ)句
executeQuery()
String query = "select * from test";
ResultSet rs=stmt.executeQuery(query);
結果集ResultSet
while(rs.next())
{rs.getString(1);rs.getInt(2);}
executeUpdate()
String upd="insert into test (id,name) values(1001,xuzhaori)";
int con=stmt.executeUpdate(upd);
execute()
示例:
try{
}
catch(SQLException sqle)
{
}
finally
{
}
Java類(lèi)型和SQL類(lèi)型 技術(shù)手冊P421
PreparedStatement(預編語(yǔ)句)
PreparedStatement stmt = conn.prepareStatement("insert into test(id,name)values(?,?)");
stmt.setInt(1,id);
stmt.setString(2,name);
注:一旦設定語(yǔ)句的參數值后,就可以多次執行改語(yǔ)句,直到調用clearParameters()方法將他清除為止
CallableStatement(預儲程序)技術(shù)手冊P430
JDBC2.0使用
ResultSet對象中的光標上下自由移動(dòng)
Statement stmt = con.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs=stmt.executeQuery("select * from test");
public Statement createStatement(int resultSetType,int resultSetConcuttency) throws SQLException
resultSetType
TYPE_FORWARD_ONLY 只能使用next()方法。
TYPE_SCROLL_SENSITIVE 可以上下移動(dòng),可以取得改變后的值。
TYPE_SCROLL_INSENSITIVE 可以上下移動(dòng)。
resultSetConcuttency
CONCUR_READ_ONLY 只讀
CONCUR_UPDATABLE ResultSet對象可以執行數據庫的新增、修改、和移除
直接使用ResultSet對象執行更新數據
新增數據
Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLE);
ResultSet uprs=stmt.executeQuery("select * from test");
uprs.moveToInsertRow();
uprs.updateInt(1,1001);
uprs.updateString(2,"許召日");
uprs.insertRow;
更新數據
Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLE);
ResultSet uprs=stmt.executeQuery("select * from test");
uprs.last();
uprs.updateString("name","xuzhaori");
uprs.updateRow;
刪除數據
Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_PUDATABLE);
ResultSet uprs=stmt.executeQuery("select * from test");
uprs.absolute(4);
uprs.deleteRow();
批處理
con.setAutoCommit(false); 關(guān)閉自動(dòng)認可模式
Statement stmt=con.createStatement();
int[] rows;
stmt.addBatch("insert into test values(1001,xuzhaori)");
stmt.addBatch("insert into test values(1002,xuyalin)");
rows=stmt.executeBatch();
con.commit(); 沒(méi)有任何錯誤,執行批處理stmt.executeBatch();
JNDI-數據源(Data Source)與連接池(Connection Pool)
Tomcat的JDBC數據源設置 技術(shù)手冊P439
連接池工具-Proxool Var 0.8.3 技術(shù)手冊P446
設置web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--<?xml version="1.0" encoding="GB2312"?>-->
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
….
<servlet>
<servlet-name>ServletConfigurator</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
<init-param>
<param-name>propertyFile</param-name>
<param-value>WEB-INF/classes/Proxool.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
后端統計端口添加下列
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/Admin</url-pattern>
</servlet-mapping>
….
</web-app>
配置Proxool.properties
jdbc-0.proxool.alias=JSPBook
jdbc-0.proxool.driver-class=com.mysql.jdbc.Driver
jdbc-0.proxool.driver-url=jdbc:mysql://localhost:3306/sample_db?user=root&password=browser&useUnicode=true&characterEncoding=UTF-8
jdbc-0.proxool.maximum-connection-count=10
jdbc-0.proxool.prototype-count=4
jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE
jdbc-0.proxool.verbose=true
jdbc-0.proxool.statistics=10s,1m,1d 后端統計接口添加此行
jdbc-0.proxool.statistics-log-level=DEBUG
使用Proxool連接池
Connection con = DriverManager.getConnection("proxool.JSPBook");
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String query = "SELECT * FROM employee";
ResultSet rs = stmt.executeQuery(query);
聯(lián)系客服