您好,登錄后才能下訂單哦!
JDBC執(zhí)行數(shù)據(jù)庫操作語句,首先需要將sql語句打包成為網(wǎng)絡字節(jié)流,傳遞給數(shù)據(jù)庫,數(shù)據(jù)庫經(jīng)過解包,然后編譯sql語句,最后執(zhí)行,然后將結(jié)果通過字節(jié)流的形式返回給JDBC API
簡單的來說大致分為以下幾點:
JDBC打包sql語句
發(fā)送字節(jié)流至數(shù)據(jù)庫
數(shù)據(jù)庫解包
檢查sql語法,編譯sql
執(zhí)行sql語句
<br/>
注冊驅(qū)動 (Driver)
建立連接(創(chuàng)建Connection)
創(chuàng)建執(zhí)行sql語句(通常是創(chuàng)建Statement或者其子類)
執(zhí)行語句
處理執(zhí)行結(jié)果(在非查詢語句中,該步驟是可以省略的)
案例
@Test
public void wholeExample(){
try {
//1.注冊驅(qū)動
Class.forName("com.mysql.jdbc.Driver");
//2.獲取數(shù)據(jù)庫連接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root","123456");
//3.創(chuàng)建執(zhí)行句柄
Statement stmt = conn.createStatement();
//4.執(zhí)行sql語句
ResultSet rs = stmt.executeQuery("select * from user");
//5.處理執(zhí)行結(jié)果
while(rs.next()){
System.out.println("id:"+rs.getInt(1)+"\tname:"+rs.getString(2)+"\tbirthday:"+rs.getDate(3)+"\tmoney:"+rs.getFloat(4));
}
//6.釋放資源
rs.close();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
<br/>
當我們存放大量的文本信息時,數(shù)據(jù)庫中的varchar或者varchar2肯定是不能滿足的,varchar2好像最多只能有4000個長度,存放一篇很長的文章或者一個文本信息,我們采用CLOB類型
針對二進制文件進行的存取,比如圖片,音頻等信息
//stream文件流
PreparedStatement.setBlob(index, stream)
<br/>
數(shù)據(jù)庫的事務是保證數(shù)據(jù)完整性的一種機制,簡而言之,就是怎樣確保數(shù)據(jù)的執(zhí)行過程要么都成功,要么都失敗
<br/>
原子性(atomicity):組成事務處理的語句形成了一個邏輯單元,不能只執(zhí)行其中的一部分
一致性(consistency):在事務處理執(zhí)行前后,數(shù)據(jù)庫是一致的(兩個賬戶要么都變,或者都不變)
隔離性(isolcation):一個事務處理對另一個事務處理沒有影響
Jdbc的事務默認是打開的,也就是說執(zhí)行每一步操作的話,事務都會隱式的進行提交,在拋出異常之前,我們的更改操作已經(jīng)同步到了數(shù)據(jù)庫中去
//提交事務
//回滾事務
通常所說的跨庫事務,要求幾個數(shù)據(jù)庫的事務在一個應用中保持一致,JTA就是為了解決這個問題而誕生的
在數(shù)據(jù)庫操作中PreparedStatement會帶來很大的方便,減少拼寫sql字符串帶來的麻煩,防止SQL注入的發(fā)生.
PreparedStatement是Statement的子類
在數(shù)據(jù)庫操作中調(diào)用數(shù)據(jù)庫中的存儲過程
案例:執(zhí)行有參數(shù)有返回值的存儲過程
create or replace procedure test1(in id integer,in name varchar(20),in money float,out counter integer)
as
begin
insert into user values(id,name,now(),money);
select count(1) into counter from user;
commit;
end test1;
@Test
public void callProcedureWithParamWithResult() throws SQLException{
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try {
conn = ConnCreate.getConnection("jdbc:mysql://localhost:3306/test",
"root", "123456");
String sql = "{call test1(?,?,?,?)}";
stmt = conn.prepareCall(sql);
stmt.setInt(1, 17);
stmt.setString(2, "test");
stmt.setFloat(3, 6000);
stmt.registerOutParameter(1, Types.INTEGER);
stmt.executeUpdate();
int counter = stmt.getInt(4);
System.out.println(counter);
} finally {
ConnCreate.close(conn, stmt, rs);
}
}
<br/>
//添加一條條的sql
// 執(zhí)行批處理
利用sql語句進行分頁(eg: mysql的limit ? ?, 一個offsize偏移量,另一個pagesize頁面數(shù)量)
@Test
public void page() throws SQLException{
page(100,20);
}
static void page(int start,int total) throws SQLException{
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = ConnCreate.getConnection("jdbc:mysql://localhost:3306/test",
"root", "123456");
String sql = "select * from user limit ?,?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, start);
stmt.setInt(2, total);
rs = stmt.executeQuery();
while(rs.next()) //向下滾動
{
System.out.println("name:"+rs.getString(2)+"id:"+rs.getInt(1));
}
} finally {
ConnCreate.close(conn, stmt, null);
}
}
使用jdbc最大的開銷之一就是創(chuàng)建數(shù)據(jù)庫,當我們頻繁的創(chuàng)建數(shù)據(jù)庫時,勢必影響應用的效率,或者在數(shù)據(jù)庫關(guān)閉出現(xiàn)問題時,我們不能馬上釋放,時間長一些,整個數(shù)據(jù)庫的 資源將會被我們的應用耗盡
C3P0
如果我們不知道我們的一個sql語句查詢了幾列結(jié)果集,并且每列的列名,類型等信息,這個時候我們應該使用ResultSetMetaData
<br/>
@Test
public void resultMeta() throws SQLException{
String sql="select * from user";
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = ConnFactory.getConnection();
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
for(int i=1;i<=count;++i){
System.out.println("Type:"+rsmd.getColumnType(i));
System.out.println("ColumnName:"+rsmd.getColumnName(i));
System.out.println("ColumnLable:"+rsmd.getColumnLabel(i));
}
} finally{
ConnFactory.close(conn, stmt, rs);
}
}
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。