程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> Jsp連接數據庫小結

Jsp連接數據庫小結

編輯:關於JSP

找rs.absolute()時,看到了這篇文章,很不錯。。只可惜轉不過來。。我就只好復制,粘貼了。。。

JDBC 主要接口:
java.sql.DriverManager類用於處理驅動程序的調入並且對新的數據庫連接提供支持。
java.sql.Connection,指應用程序與特定數據庫的連接。
java.sql.Statement,用於一般sql語句的執行(可以是查詢、更新甚至可以創建數據庫的執行過程)
java.sql.ResultSet,查詢所返回的結果保存在此對象中,用它可以浏覽和存取數據庫內的記錄。

1,通過jdbc-odbc橋使用odbc數據庫(並不需要jdbc Drivers)

先在odbc DSN(Data Source Name)設置處設置pubs sysDSN,sa為username,密碼為pwd
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//加載驅動程序

con=DriverManager.getConnection("jdbc:odbc:pubs","sa","pwd"); //jdbc:odbc:pubs
con.close();
//應當catch ClassNotFoundException和SQLException
Connection的getWarning方法返回一個SQLWarning對象,在連接之前應當先檢查。
使用jdbc-odbc的最大好處是:免費的。但是性能受odbc的限制,而且一般odbc驅動比較昂貴。

2,使用專門的jdbc驅動程序。//此處是mm jdbc Driver
先將jar文件放在ClassPath裡面。
Class.forName("org.gjt.mm.mysql.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname","root","");
con.close();

可見使用何種方式連接何種數據庫與數據庫的操作和連接數據庫是無關的。

三,查詢數據庫
Statement stmt=con.createStatement();
stmt.setMaxRows()可以控制輸出記錄最大數量;
ResultSet rs=stmt.executeQuery("select .....");

ResultSet指向當前記錄:
int userId=rs.getInt("userid");
String userName=rs.getString("username");
...或者用序號(從1開始的)
int userId=rs.getInt(1);
Stirng userName=rs.getString(2);

ClassNotFoundException是由於Class.forName()無法載入jdbc驅動程序觸發的
SQLException是jdbc在執行過程中發生問題時產生。有一個額外的方法getNextException()
catch(SQLException e){
out.println(e.getMessage());
while(e=e.getNextException()){
out.println(e.getMessage());
}
}

一般來說並不建議在jsp中編寫數據庫的訪問程序,可以將數據庫的訪問封裝在一個javabean中。

四,ResultSet深入

1,ResultSetMetaData
ResultSet rs=stmt.executeQuery("select....");
ResultSetMetaData rsmd=rs.getMetaData(); //獲取ResultSetMateData對象
int numberOfColumns=rsmd.getColumnCount();//返回列數
boolean b=rsmd.isSearchable(int i);//返回第i列是否可以用於where子句
String c=rsmd.getColumnLabel(int i);//獲取第i列的列標
Objcet obj=rs.getObject();
if(obj!=null)out.println(obj.toString());
else println("");

2,
rs.absolute(...)允許你指定結果集的絕對位置,如果沒有它,假如你要取第1000條記錄的數據,就只能rs.next()1000次了:)
rs.isAfterLast()是一種特殊的狀態,表征已到達結果集的結尾,此時你如果調用rs.next()就會拋出異常
rs.next();//向後滾動
rs.getRow();//得到當前行號
rs.absolute(n);//光標定位到n行
rs.relative(int n);//相對移動n行

3,null
int i=rs.getInt("age");
if(!rs.wasNull())....//RecordSet::wasNull()用來檢查null

4,存取大字符串和二進制文本
對於數據庫中longvarchar和langvarbinary進行流操作
ResultSet rs=stmt.executeQueryString("select ...");
BufferedReader br=new BufferedReader(new InputStream(rs.getAsciiStream("vol1")));//長文本串
BufferedReader br=new BufferedReader(new InputStream(rs.getUnicodeStream("vol1")));
BufferedReader br=new BufferedReader(new InputStream(rs.getBinaryStream("vol2")));//長二進制文本
//取數據必須在rs.getAsciiStream(), rs.getUnicodeStream(), rs.getBinaryStream()等之後馬上進行

五,浏覽ResultSet
1,JDBC2.0提供了更多浏覽ResultSet的方法
首先,確定你的jdbc驅動程序支持jdbc2.0
其次,由Connection生成Statement時要指定參數
Statement stmt=con.getStatement("游標類型", "記錄更新權限");
游標類型:
ResultSet.TYPE_FORWORD_ONLY:只可以向前移動
ResultSet.TYPE_SCROLL_INSENSITIVE:可卷動。但是不受其他用戶對數據庫更改的影響。
ResultSet.TYPE_SCROLL_SENSITIVE:可卷動。當其他用戶更改數據庫時這個記錄也會改變。
記錄更新權限:
ResultSet.CONCUR_READ_ONLY,只讀
ResultSet.CONCUR_UPDATABLE,可更新

getStatement()缺省參數:getStatement(ResultSet.TYPE_FORWORD_ONLY, ResultSet.CONCUR_READ_ONLY)

2,如果ResultSet是可卷動的,以下函數可以使用:
rs.absolute()//絕對位置,負數表示從後面數
rs.first()第一條
rs.last()最後一條
rs.previoust()前一條
rs.next()後一條
rs.beforeFirst()第一條之前
rs.afterLast()最後之後
rs.isFirst(),rs.isLast(),rs.isBeforeFirst(),rs.isAfterLast
注意,剛打開的時候是處於第一條記錄之前的

六,更新數據庫
1,stmt.executeUpdate("strSql"),strSql是一條sql更新語句。update,insert,delete返回影響到的條數
2,stmt.execute()方法在不知道sql語句是查詢還是更新的時候用。如果產生一條以上的對象時,返回true,此時可用 stmt.getResultSet()和stmt.getUpdateCount()來獲取execute結果,如果不返回ResultSet對象則返回false.
3,除了Statement的executeUpdate之外還可以用ResultSet:
rs.updateInt(1,10);
rs.updateString(2,"sfafd");
rs.updateRow();

七,使用預編譯PreparedStatement
PreparedStatement對象和Statement對象類似,都可以用來執行SQL語句。不同在於,數據庫會對PreparedStatement的SQL語句進行預編譯,而且仍舊能輸入參數並重復執行編譯好的查詢速度比未編譯的要快。
PreparedStatement stmt=con.preparedStatement("Insert Into users(userid, username) values(?,?)");
stmt.clearParameters();
stmt.setInt(1,2);
stmt.setString(2,"Big");
stmt.executeUpdate();

八,執行存儲過程
1,JDBC調用存儲過程,並使用存儲過程的返回值。這樣可以將處理工作分為服務端和客戶端兩部分,並大大加快系統的設計和開發的時間。比如可以重復使用服務器上的組件。使用存儲過程之後大量諸計算工作可以交給數據庫服務器來處理,這將降低Web服務器的負載,從而提高整個系統的性能。
2,有兩個表UserMain{UserID,UserName,UserType},UserRef{BrefID, UserID, UserBrief}
下面的存儲過程可以接受jdbc傳來的參數,新增內容到UserMain和UserRef,並輸出一個OutUserID.
CREATE PROCEDURE ap_adduser
(
@OutUserID int output, //此為輸出參數,output標記
@UserName varchar(25), //參數表示方法:"@XXX"為變量名,"變量名 類型 [output]"
@UserType tinyint,
@UserBrief varchar(255),
)
AS
Declare @UserID int //定義局部變量
insert into UserMain(UserName, UserType)
values(@UserName,@UserType)
select @UserID=@@IDENTITY //賦值用select,此處自動獲得ID
insert into UserRef(UserID, UserBrief)
select @OutUserID=@UserID
GO/*結束,基本結構:
CREATE PROCEDURE procedureName(
parameters
)
AS
actions
GO
*/

JSP頁面中這樣使用:
CallableStatement stmt=con.prepareCall("{call ap_adduser(?,?,?,?)}");
stmt.registerOutParameter(1,Types.INTEGER,1);//注冊輸出變量
stmt.setString(2,"edmund");
stmt.setInt(3,1);
stmt.setString(4,"description");
stmt.execute();
int userid=stmt.getInt(1);
stmt.close()

八,使用事務
1,事務中的操作是一個整體,要麼都執行成功要麼都不成功:事務開始後,如果所有的改變都正確,則使用commit方法將這些動作全部存入數據庫,否則就使用rollback取消所有的改變動作,而這時數據庫中的數據和執行事務前的是相同的。
2,使用事務時應當先用 con.setAutoCommit(false),最後使用commit或者rollback
3,rollback一般在catch段執行
九,數據庫連接池
1,如果有一個數據庫連接請求並且連接中沒有連接,則生成一個新的連接。這個連接使用完之後並不關閉它,而是將它放入連接池。在這個過程中,還要判斷連接池中的連接是否超期。如果超期則將它關閉。
2,有很多已有的Connection Pool包可以使用。
3,一般將Connection Pool作為一個application作用域的變量使用
<jsp:useBean id="pool" scope="application" class="javastart.tools.ConnectionPool" />
<%@page import="java.sql.*"%>
<%@page import="javastart.tools.*"%>
<!--javastart.tools是你的Connection Pool所在的地方-->
DBConnection con=null;
try{
con=pool.getConnection("sun.jdbc.odbc.JdbcOdbcDriver","jdbc:odbc:access","","");
Statement stmt=con.createStatement();
stmt.setMaxRows(10);
String query=request.getParameter("quey");
ResultSet rs=stml.executeQuery(query);
ResultSetMetaData rsmd=rs.getMetaData();
}
.....
finally{
pool.releaseConnection(con);
}
也可以使用一個Servlet初始化連接池。


有不對的地方提出來哈,別客氣 。。。。

漂泊小柒的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved