今天Java老師楊樂講完了最後一節Java基礎課——-JDBC,回來以後大概瞭解了一些基礎應用。但我認爲這些是不夠的,所以去網上找了一些JDBC的應用:下面爲大家一一講解:
1、JDBC全稱爲:Java Data Base Connectivity(java數據庫連接),它主要由接口組成。
2、組成JDBC的2個包: java.sql和 javax.sql
3、一個程序的順序:
一、搭建實驗環境 :
1、在mysql中創建一個庫,並創建userinfo表和插入表的數據。
2、新建一個Java工程,並導入數據驅動。
二、編寫程序,在程序中加載數據庫驅動
DriverManager. registerDriver(Driver driver)
三、建立連接(Connection)
Connection conn = DriverManager.getConnection(url,user,pass);
四、創建用於向數據庫發送SQL的Statement對象,併發送sql
Statement st = conn.createStatement();
ResultSet rs = st.excuteQuery(sql);
五、從代表結果集的ResultSet中取出數據,打印到命令行窗口
六、斷開與數據庫的連接,並釋放相關資源
4、Jdbc程序中的DriverManager用於加載驅動,並創建與數據庫的鏈接,這個API的常用方法:
(1)DriverManager.registerDriver(new Driver()),注意:在實際開發中,並不推薦採用這個方法註冊驅動。查看Driver的源代碼可以看到,如果採用此種方式,會導致驅動程序加載兩次,也就是在內存中會有兩個Driver對象。
(2)推薦方式:Class.forName(“com.mysql.jdbc.Driver”);採用此種方式不會導致驅動對象在內存中重複出現,並且採用此種方式,程序僅僅只需要一個字符串,不需要import驅動的API,這樣可使程序不依賴具體的驅動,使程序的靈活性更高。
(3)DriverManager.getConnection(url, user, password),根據url獲取數據庫的鏈接。
5、
(1)URL的寫法爲:
jdbc:mysql:[]//localhost:3306/test ?參數名:參數值
(2)Mysql的url地址的簡寫形式: jdbc:mysql:///sid
(3)常用屬性:useUnicode=true&characterEncoding=UTF-8
6、connection這個對象的常用方法:
(1)createStatement():創建向數據庫發送sql的statement對象。
(2)prepareStatement(sql) :創建向數據庫發送預編譯sql的PrepareSatement對象。
(3)prepareCall(sql):創建執行存儲過程的callableStatement對象。
(4)setAutoCommit(boolean autoCommit):設置事務是否自動提交。
(5)commit() :在鏈接上提交事務。
(6)rollback() :在此鏈接上回滾事務。
7、Jdbc程序中的Statement對象用於向數據庫發送SQL語句, Statement對象常用方法:
(1)execute(String sql):用於向數據庫發送任意sql語句
(2)executeQuery(String sql) :只能向數據發送查詢語句。
(3)executeUpdate(String sql):只能向數據庫發送insert、update或delete語句
(4)addBatch(String sql) :把多條sql語句放到一個批處理中。
(5)executeBatch():向數據庫發送一批sql語句執行。
8、Jdbc程序中的ResultSet用於代表Sql語句的執行結果。Resultset封裝執行結果時,採用的類似於表格的方式。ResultSet 對象維護了一個指向表格數據行的遊標,初始的時候,遊標在第一行之前,調用ResultSet.next() 方法,可以使遊標指向具體的數據行,進行調用方法獲取該行的數據。
9、ResultSet既然用於封裝執行結果的,所以該對象提供的都是用於獲取數據的get方法:
(1)獲取任意類型的數據
getObject(int index)
getObject(string columnName)
(2)獲取指定類型的數據,例如:
getString(int index)
getString(String columnName)
10、ResultSet還提供了對結果集進行滾動的方法:
(1)next():移動到下一行
(2)Previous():移動到前一行
(3)absolute(int row):移動到指定行
(4)beforeFirst():移動resultSet的最前面。
(5)afterLast() :移動到resultSet的最後面。
11、
(1)Jdbc程序運行完後,切記要釋放程序在運行過程中,創建的那些與數據庫進行交互的對象,這些對象通常
是ResultSet, Statement和Connection對象。
(2)特別是Connection對象,它是非常稀有的資源,用完後必須馬上釋放,如果Connection不能及時、正確
的關閉,極易導致系統宕機。Connection的使用原則是儘量晚創建,儘量早的釋放。
(3)爲確保資源釋放代碼能運行,資源釋放代碼也一定要放在finally語句中。
12、使用JDBC對數據庫進行CRUD:
(1)Jdbc中的statement對象用於向數據庫發送SQL語句,想完成對數據庫的增刪改查,只需要通過這個對象
向數據庫發送增刪改查語句即可。
(2)Statement對象的executeUpdate方法,用於向數據庫發送增、刪、改的sql語句,executeUpdate執行完
後,將會返回一個整數(即增刪改語句導致了數據庫幾行數據發生了變化)。
(3)Statement.executeQuery方法用於向數據庫發送查詢語句,executeQuery方法返回代表查詢結果的
ResultSet對象。
13、使用executeUpdate(String sql)方法完成數據添加操作,示例操作:
Statement st = conn.createStatement();
String sql = "insert into user(….) values(…..) ";
int num = st.executeUpdate(sql);
if(num>0){
System.out.println("插入成功!!!");
}
14、使用executeUpdate(String sql)方法完成數據修改操作,示例操作:
Statement st = conn.createStatement();
String sql = "update user set name=‘’ where id=‘’";
int num = st.executeUpdate(sql);
if(num>0){
System.out.println(“修改成功!!!");
}
15、使用executeUpdate(String sql)方法完成數據刪除操作,示例操作:
Statement st = conn.createStatement();
String sql = "delete from user where id=1";
int num = st.executeUpdate(sql);
if(num>0){
System.out.println(“刪除成功!!!");
}
16、使用executeQuery(String sql)方法完成數據查詢操作,示例操作:
Statement st = conn.createStatement();
String sql = "select * from user where id=1";
ResultSet rs = st.executeUpdate(sql);
while(rs.next()){
//根據獲取列的數據類型,分別調用rs的相應方法
//映射到java對象中
}
17、PreperedStatement是Statement的孩子,它的實例對象可以通過調用Connection.preparedStatement()
方法獲得,相對於Statement對象而言:
(1)PreperedStatement可以避免SQL注入的問題。
(2)Statement會使數據庫頻繁編譯SQL,可能造成數據庫緩衝區溢出。
(3)PreparedStatement 可對SQL進行預編譯,從而提高數據庫的執行效率。
(4)並且PreperedStatement對於sql中的參數,允許使用佔位符的形式進行替換,簡化sql語句的編寫。
18、MySQL分頁的實現:
(1)Select * from table limit M,N
M:記錄開始索引位置
N:取多少條記錄。
(2)完成WEB頁面的分頁顯示
先獲得需分頁顯示的記錄總數,然後在web頁面中顯示頁碼。
根據頁碼,從數據庫中查詢相應的記錄顯示在web頁面中。
以上兩項操作通常使用Page對象進行封裝。
19、連接數據庫的代碼:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBcon {
public Connection getCon(){
Connection conn=null;
String url="jdbc:mysql://localhost:3306/users"; //url
String user="root"; //數據庫用戶
String password="123"; //連接數據庫的密碼
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}//加載驅動
try {
conn=DriverManager.getConnection
(url,user,password); //建立數據庫連接
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
}
20、使用JDBC處理大數據
(1)基本概念:大數據也稱之爲LOB(Large Objects),LOB又分爲: clob和blob clob用於存儲大文本。
blob用於存儲二進制數據,例如圖像、聲音、二進制文等。
(2)對MySQL而言只有blob,而沒有clob,mysql存儲大文本採用的是Text,Text和blob分別又分爲:
TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT
TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB
21、使用JDBC處理大文本
(1)對於MySQL中的Text類型,可調用如下方法設置: PreparedStatement.setCharacterStream(index,
reader, length);
注意length長度須設置,並且設置爲int型
(2)對MySQL中的Text類型,可調用如下方法獲取:
reader = resultSet. getCharacterStream(i);
reader = resultSet.getClob(i).getCharacterStream();
string s = resultSet.getString(i);
22、使用JDBC處理二進制數據
(1)對於MySQL中的BLOB類型,可調用如下方法設置:
PreparedStatement. setBinaryStream(i, inputStream, length);
(2)對MySQL中的BLOB類型,可調用如下方法獲取:
InputStream in = resultSet.getBinaryStream(i);
InputStream in = resultSet.getBlob(i).getBinaryStream();
23、Oracle中大數據處理
(1)Oracle定義了一個BLOB字段用於保存二進制數據,但這個字段並不能存放真正的二進制數據,只能向這
個字段存一個指針,然後把數據放到指針所指向的Oracle的LOB段中, LOB段是在數據庫內部表的一部分。
(2)因而在操作Oracle的Blob之前,必須獲得指針(定位器)才能進行Blob數據的讀取和寫入。
(3)如何獲得表中的Blob指針呢?
可以先使用insert語句向表中插入一個空的blob(調用oracle的函數empty_blob() ),這將創建一個blob
的指針,然後再把這個empty的blob的指針查詢出來,這樣就可得到BLOB對象,從而讀寫blob數據了。
24、Oracle中LOB類型的處理
(1)、插入空blob insert into test(id,image) values(?,empty_blob());
(2)、獲得blob的cursor select image from test where id= ? for update;
Blob b = rs.getBlob(“image”);
注意: 須加for update,鎖定該行,直至該行被修改完畢,保證不產生併發衝突。
(3)、利用 io,和獲取到的cursor往數據庫讀寫數據
注意:以上操作需開啓事務。
25、使用JDBC進行批處理
(1)業務場景:當需要向數據庫發送一批SQL語句執行時,應避免向數據庫一條條的發送執行,而應採用JDBC的批處理機制,以提升執行效率。
(2)實現批處理有兩種方式,第一種方式:Statement.addBatch(sql)
第一種方式:PreparedStatement.addBatch()
(3)執行批處理SQL語句executeBatch()方法:執行批處理命令clearBatch()方法:清除批處理命令
26、使用JDBC進行批處理
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConnection();
String sql1 = "insert into user(name,password,email,birthday) values('kkk','123','[email protected]','1978-08-08')";
String sql2 = "update user set
password='123456' where id=3";
st = conn.createStatement();
st.addBatch(sql1); //把SQL語句加入到批命令中
st.addBatch(sql2); //把SQL語句加入到批命令中
st.executeBatch();
} finally{
JdbcUtil.free(conn, st, rs);
}
27、獲得數據庫自動生成的主鍵
Connection conn = JdbcUtil.getConnection();
String sql = "insert into user
(name,password,email,birthday) values
('abc','123','[email protected]','1978-08-08')";
PreparedStatement st = conn. prepareStatement(sql,Statement.RETURN_GENERATED_KEYS );
st.executeUpdate();
ResultSet rs = st.getGeneratedKeys(); //得到插入行的主鍵
if(rs.next())
System.out.println(rs.getObject(1));
注:此參數僅對insert操作有效。
28、JDBC調用存儲過程
編寫存儲過程得到CallableStatement,並調用存儲過程:
CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");
設置參數,註冊返回值,得到輸出:
cStmt.registerOutParameter(2, Types.VARCHAR);
cStmt.setString(1, "abcdefg");
cStmt.execute();
System.out.println(cStmt.getString(2));
29、事務
(1)事務的概念
事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功。
(2)數據庫開啓事務命令
start transaction 開啓事務
Rollback 回滾事務
Commit 提交事務
(3)JDBC控制事務語句
Connection.setAutoCommit(false);
Connection.rollback();
Connection.commit();
(4)設置事務回滾點
Savepoint sp = conn.setSavepoint();
Conn.rollback(sp);
Conn.commit(); //回滾後必須要提交
30、事務的特性(ACID)
(1)原子性(Atomicity)(2)一致性(Consistency)(3)隔離性(Isolation)(4)持久性(Durability)
31、自動生成主鍵的實例
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ReturnKeys {
public static void main(String[] args) {
DBcon dbc = new DBcon();
Connection conn = dbc.getCon();
String sql = "insert into userinfo(uname)values('abc')";
PreparedStatement st;
try {
st = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
st.executeUpdate();
ResultSet rs = st.getGeneratedKeys();//得到插入行的主鍵
if(rs.next())
System.out.println(rs.getObject(1));
} catch (SQLException e) {
e.printStackTrace();
}
}
}