Java-Web程序設(shè)計(jì)與案例教程-第6章-數(shù)據(jù)庫(kù)整合開發(fā)_第1頁(yè)
Java-Web程序設(shè)計(jì)與案例教程-第6章-數(shù)據(jù)庫(kù)整合開發(fā)_第2頁(yè)
Java-Web程序設(shè)計(jì)與案例教程-第6章-數(shù)據(jù)庫(kù)整合開發(fā)_第3頁(yè)
Java-Web程序設(shè)計(jì)與案例教程-第6章-數(shù)據(jù)庫(kù)整合開發(fā)_第4頁(yè)
Java-Web程序設(shè)計(jì)與案例教程-第6章-數(shù)據(jù)庫(kù)整合開發(fā)_第5頁(yè)
已閱讀5頁(yè),還剩54頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第6章 數(shù)據(jù)庫(kù)整合開發(fā) 本章內(nèi)容 MySQL簡(jiǎn)介 JDBC概述 數(shù)據(jù)庫(kù)連接池 DBUtils框架簡(jiǎn)介 簡(jiǎn)易購(gòu)物商城6.1 MySQL簡(jiǎn)介MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫(kù),它由瑞典MySQL AB公司開發(fā),目前屬于Oracle旗下的產(chǎn)品。MySQL是最流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)之一,在Web應(yīng)用方面,MySQL是最好的關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(Relational DataBase Management System,RDBMS)應(yīng)用軟件。6.2 JDBC概述Java 數(shù)據(jù)庫(kù)連接技術(shù)(Java DataBase Connectivity,JDBC)是 Java 訪問(wèn)數(shù)據(jù)庫(kù)資源的標(biāo)準(zhǔn),JDBC 標(biāo)準(zhǔn)定義了一

2、組 Java API,允許用戶寫出SQL語(yǔ)句,然后交給數(shù)據(jù)庫(kù)。6.2 JDBC概述如圖6.1所示,如果沒有 JDBC 或者 ODBC,開發(fā)人員必須使用不同的一組 API 來(lái)訪問(wèn)不同的數(shù)據(jù)庫(kù);而有了JDBC 或者 ODBC,則只需要使用一組 API,再加上數(shù)據(jù)庫(kù)廠商提供的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序就可以訪問(wèn)不同的數(shù)據(jù)庫(kù)了,如圖6.2所示。所以,利用 JDBC,我們就可以把同一個(gè)企業(yè)級(jí) Java 應(yīng)用移植到另一個(gè)數(shù)據(jù)庫(kù)應(yīng)用上。6.2 JDBC概述圖6.1 應(yīng)用程序直接訪問(wèn)數(shù)據(jù)庫(kù)圖6.2 應(yīng)用程序訪問(wèn)JDBC6.2 JDBC概述JDBC主要包含兩部分:面向Java程序員的JDBC API和面向數(shù)據(jù)庫(kù)廠商的JDB

3、C Drive API。1面向 Java 程序員的 JDBC API它主要由一系列的接口定義所構(gòu)成。java.sql.DriveManager:該接口定義了用來(lái)處理裝載驅(qū)動(dòng)的程序,并且為創(chuàng)建新的數(shù)據(jù)庫(kù)連接提供支持。java.sql.Connection:該接口定義了實(shí)現(xiàn)對(duì)某一種指定數(shù)據(jù)庫(kù)連接的功能。6.2 JDBC概述java.sql.Statement:該接口定義了在一個(gè)給定的連接中作為 SQL 語(yǔ)句執(zhí)行聲明的容器以實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作。它主要包含有如下兩種子類型。java.sql.PreparedStatement:該接口定義了用于執(zhí)行帶或不帶 IN 參數(shù)的預(yù)編譯 SQL 語(yǔ)句。java.s

4、ql.CallableStatement:該接口定義了用于執(zhí)行數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程的調(diào)用。java.sql.ResultSet:該接口定義了執(zhí)行數(shù)據(jù)庫(kù)的操作后返回的結(jié)果集。2面向數(shù)據(jù)庫(kù)廠商的JDBC Drive API6.2 JDBC概述6.2.1 創(chuàng)建數(shù)據(jù)庫(kù)連接6.2.2 SQL的執(zhí)行6.2.3 SQL執(zhí)行結(jié)果的處理 6.2.1 創(chuàng)建數(shù)據(jù)庫(kù)連接在Java程序中要操作數(shù)據(jù)庫(kù),一般應(yīng)該通過(guò)如下幾步。1下載數(shù)據(jù)庫(kù)開發(fā)所需要的驅(qū)動(dòng)包用戶可以從對(duì)應(yīng)的數(shù)據(jù)庫(kù)廠商的官網(wǎng)進(jìn)行下載,例如,下載MySQL驅(qū)動(dòng)包,如圖6.3所示,選擇“JDBC DriverforMySQL”進(jìn)行下載。下載的驅(qū)動(dòng)包是一個(gè)壓縮包,將包內(nèi)

5、的“mysql-connector-java-5.1.42-bin.jar”復(fù)制到“WebRootlib”文件夾下,如圖6.4所示。6.2.1 創(chuàng)建數(shù)據(jù)庫(kù)連接圖6.3 下載MySQL驅(qū)動(dòng)包圖6.4 加載MySQL驅(qū)動(dòng)包6.2.1 創(chuàng)建數(shù)據(jù)庫(kù)連接2數(shù)據(jù)庫(kù)管理工具在開發(fā)中,我們一般會(huì)創(chuàng)建一個(gè)專用于創(chuàng)建數(shù)據(jù)庫(kù)連接和釋放數(shù)據(jù)庫(kù)連接的工具類。建立與數(shù)據(jù)庫(kù)的連接需要完成如下兩個(gè)步驟。(1)加載驅(qū)動(dòng)類到內(nèi)存Class.forName(com.mysql.jdbc.Driver);(2)創(chuàng)建與數(shù)據(jù)源的連接 Connection con=DriverManager.getConnection( String u

6、rl, String username, String password);6.2.2 SQL的執(zhí)行在實(shí)際開發(fā)中,當(dāng)需要訪問(wèn)數(shù)據(jù)庫(kù)時(shí),只需要調(diào)用以下方法: Connection conn = DBUtil.getConnection();就可以獲得一個(gè)java.sql.Connection類型的數(shù)據(jù)庫(kù)連接對(duì)象,通過(guò)這個(gè)連接對(duì)象,用戶可以操作數(shù)據(jù)庫(kù),發(fā)送目標(biāo)SQL給數(shù)據(jù)庫(kù),并接收響應(yīng)結(jié)果。6.2.2 SQL的執(zhí)行在已建立數(shù)據(jù)庫(kù)連接的基礎(chǔ)上,向數(shù)據(jù)庫(kù)發(fā)送要執(zhí)行的SQL語(yǔ)句的接口是Statement。Statement用于執(zhí)行靜態(tài)的SQL語(yǔ)句。(1)java.sql.Statementjava.sq

7、l.Statement類型的對(duì)象,是通過(guò)java.sql.Connection對(duì)象獲得的,其代碼如下:Statement st = conn.createStatement();所獲得的Statement對(duì)象st,可以用來(lái)執(zhí)行SQL語(yǔ)句,Statement執(zhí)行SQL語(yǔ)句的主要方法有兩個(gè):int executeUpdate(String sql); ResultSet executeQuery(String sql);6.2.2 SQL的執(zhí)行其中,executeUpdate(String sql)方法可用來(lái)執(zhí)行數(shù)據(jù)庫(kù)的更新操作。該方法的返回值類型為int,代表影響的記錄條數(shù),即插入了幾條數(shù)據(jù),修

8、改了幾條數(shù)據(jù),刪除了幾條數(shù)據(jù)等。而executeQuery(String sql)方法可用來(lái)執(zhí)行數(shù)據(jù)庫(kù)的查詢操作。該方法的返回值類型是java.sql.ResultSet,該類型能夠存儲(chǔ)數(shù)據(jù)庫(kù)返回的所有記錄,并支持按條讀取結(jié)果數(shù)據(jù)。6.2.2 SQL的執(zhí)行(2)java.sql.PreparedStatement接口在Statement中可以看到,動(dòng)態(tài)SQL的生成是通過(guò)字符串拼接而成的,但是字符串拼接會(huì)帶來(lái)很多的安全隱患,其中最為常見的安全漏洞就是SQL注入。下面以登錄功能為例,在.zzti.dao包下的UserDAO接口中定義登錄判斷方法,代碼如下:public UserDO findUse

9、r(String username, String password) throws SQLException;具體代碼如下:6.2.2 SQL的執(zhí)行在代碼的第6行,我們將拼接后的SQL語(yǔ)句打印到控制臺(tái)進(jìn)行觀察。在第12行處,需要將獲得的數(shù)據(jù)庫(kù)查詢結(jié)果進(jìn)行封裝,這里暫不實(shí)現(xiàn)這個(gè)功能。下面先來(lái)創(chuàng)建一個(gè).zzti.dao.impl.mysql.jdbc.test.UserDAOImplTest類,對(duì)方法findUser進(jìn)行測(cè)試,具體代碼如下。1 public UserDO findUser(String username, String password) throws SQLException

10、2 String sql = select * from user where username = +3 username+4 and password=+5 password+;6 System.out.println(登錄sql是: + sql);7 Connection conn = DBUtil.getConnection();8 Statement st = conn.createStatement();9 ResultSet rs = st.executeQuery(sql);10 if(rs.next()11 UserDO user = new UserDO();12 /將查詢

11、結(jié)果封裝到user對(duì)象中,此處先不處理13 return user;14 15 return null;16 6.2.2 SQL的執(zhí)行Assert.assertNotNull(Object o)是Junit的斷言,該斷言方法判斷對(duì)象o是否為空,為空則當(dāng)前測(cè)試方法通過(guò),否則測(cè)試方法失敗。執(zhí)行結(jié)果顯示,使用不存在的用戶名和密碼,調(diào)用登錄方法執(zhí)行結(jié)果為登錄正常。在輸出的SQL結(jié)果顯示,最終執(zhí)行的SQL如下:1 public class UserDAOImplTest 2 private UserDAO userDAO = (UserDAO) 3 DAOFactory.getDAO(.zzti.dao

12、.impl.mysql.jdbc.UserDAOImpl);4 Test5 public void testFinUser()6 String username=test or 1=1 #;7 String password=;8 try 9 Assert.assertNull(userDAO.findUser(username, password);10 catch (SQLException e) 11 e.printStackTrace();12 fail(出現(xiàn)異常,執(zhí)行失敗);13 14 15 6.2.2 SQL的執(zhí)行select * from user where username=

13、test or 1=1 # and password=在這個(gè)SQL中,“#”代表MySQL中的注釋。該語(yǔ)句的本意是從數(shù)據(jù)庫(kù)中獲取全部的數(shù)據(jù),因?yàn)椤皁r 1=1”使得這個(gè)條件恒為真。select * from user where username=test or 1=16.2.2 SQL的執(zhí)行為了避免SQL注入的問(wèn)題,JDBC提供了一種SQL預(yù)編譯的機(jī)制,即PreparedStatement。首先用戶提交的SQL中可以不指定具體的參數(shù),對(duì)于可變值部分讓用戶使用“?”(即占位符)來(lái)代替。然后再對(duì)SQL中的占位符單獨(dú)設(shè)置值,將兩者提交給數(shù)據(jù)庫(kù)引擎進(jìn)行編譯,此時(shí)數(shù)據(jù)庫(kù)引擎僅僅編譯帶有占位符“?”的S

14、QL語(yǔ)句,等到編譯完成后,在執(zhí)行SQL時(shí),將參數(shù)帶入編譯結(jié)果,此時(shí),參數(shù)就只會(huì)作為參數(shù)整體進(jìn)行數(shù)據(jù)比較,而不會(huì)作為SQL語(yǔ)法的一部分。6.2.2 SQL的執(zhí)行PreparedStatement對(duì)象的創(chuàng)建方式如下:PreparedStatement ps = conn.prepareStatement(String sql);而SQL也需要進(jìn)行相應(yīng)的改寫:String sql=select * from user where username = ? and password=?;與之前的SQL對(duì)比可以發(fā)現(xiàn),原來(lái)的形式參數(shù)部分被占位符“?”代替,那么就需要將形式參數(shù)與具體的“?”綁定。綁定操作可

15、通過(guò)調(diào)用 setXXX 方法來(lái)完成,其中,XXX 是與該參數(shù)相對(duì)應(yīng)的類型。例如,如果參數(shù)的數(shù)據(jù)類型是long,則使用的方法就是 setLong。setXXX 方法的第一個(gè)參數(shù)是要設(shè)置的參數(shù)的序數(shù)位置,第二個(gè)參數(shù)是設(shè)置給該參數(shù)的值。例如,上述SQL將第一個(gè)參數(shù)設(shè)為形式參數(shù)username,第二個(gè)參數(shù)設(shè)為形式參數(shù)password,代碼如下所示:ps.setString(1,username);ps.setString(2,password);6.2.3 SQL執(zhí)行結(jié)果處理無(wú)論是Statement,還是PreparedStatement,在執(zhí)行SQL的時(shí)候,主要應(yīng)用的執(zhí)行方法是executeQuer

16、y和executeUpdate,Statement在執(zhí)行execute*方法時(shí),需要以SQL為字符串參數(shù)進(jìn)行傳遞,而PreparedStatement則不需要參數(shù)。調(diào)用規(guī)則總結(jié)如表6.2所示。6.2.3 SQL執(zhí)行結(jié)果處理類 名方 法 定 義說(shuō) 明StatementResultSet executeQuery(String sql)執(zhí)行select等Statementint executeUpdate(String sql)執(zhí)行insert、update、delete等PreparedStatementResultSet executeQuery()執(zhí)行select等PreparedState

17、mentint executeUpdate(String sql)執(zhí)行insert、update、delete等表6.2 SQL執(zhí)行結(jié)果6.3 數(shù)據(jù)庫(kù)連接池創(chuàng)建數(shù)據(jù)庫(kù)連接是一個(gè)十分耗時(shí)的操作,也容易讓數(shù)據(jù)庫(kù)產(chǎn)生安全隱患。因此,在程序初始化的時(shí)候,集中創(chuàng)建了多個(gè)數(shù)據(jù)庫(kù)連接,并對(duì)它們進(jìn)行集中管理,以供程序使用,這樣就可以保證較快的數(shù)據(jù)庫(kù)讀/寫速度,而且更加安全可靠。數(shù)據(jù)庫(kù)連接池的運(yùn)行原理如圖6.16所示。6.3 數(shù)據(jù)庫(kù)連接池Servlet1Servlet2.ServletnDAO1.DAOmMySQLuser1.usersConnectionConnection.Connection圖6.16 數(shù)

18、據(jù)庫(kù)連接池原理6.3 數(shù)據(jù)庫(kù)連接池6.3.1 DataSource6.3.2 Tomcat數(shù)據(jù)源6.3.3 DBCP6.3.1 DataSourceJDBC1.0原來(lái)是用DriverManager類來(lái)產(chǎn)生一個(gè)對(duì)數(shù)據(jù)源的連接。JDBC2.0用一種替代的方法,使用java.sql.DataSource實(shí)現(xiàn),代碼變得更小巧精致,也更容易控制。編寫數(shù)據(jù)庫(kù)連接池需實(shí)現(xiàn)Java.sql.DataSource接口。DataSource接口中定義了兩個(gè)重載的getConnection方法:6.3.1 DataSourceConnection getConnection()Connection getConne

19、ction(String username, String password)開發(fā)數(shù)據(jù)庫(kù)連接池實(shí)現(xiàn)DataSource接口時(shí),在DataSource的實(shí)現(xiàn)類的構(gòu)造方法中批量創(chuàng)建與數(shù)據(jù)庫(kù)的連接,并把創(chuàng)建的連接加入存儲(chǔ)java.sql.Connection對(duì)象的集合中。實(shí)現(xiàn)getConnection方法,讓getConnection方法每次調(diào)用時(shí),從存儲(chǔ)java.sql.Connection對(duì)象的集合中取一個(gè)Connection返回給用戶。6.3.2 Tomcat數(shù)據(jù)源Tomcat提供了數(shù)據(jù)源和連接池的實(shí)現(xiàn),開發(fā)者直接使用即可。這里的Tomcat需要JDBC驅(qū)動(dòng),而不再是應(yīng)用程序需要JDBC驅(qū)動(dòng),

20、所以要先將對(duì)應(yīng)數(shù)據(jù)庫(kù)的JDBC驅(qū)動(dòng)類庫(kù)復(fù)制到Tomcat目錄中的lib文件夾下,供Tomcat調(diào)用。首先在Tomcat目錄中的“l(fā)ib”目錄下放入數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar包,在工程的“META-INF”目錄下創(chuàng)建一個(gè)“context.xml”文件,如圖6.17和圖6.18所示。6.3.2 Tomcat數(shù)據(jù)源圖6.17 添加MySQL驅(qū)動(dòng)包圖6.18 工程添加配置文件6.3.2 Tomcat數(shù)據(jù)源“context.xml”的配置內(nèi)容如下:這些屬性含義如表6.4所示。1 2 12 6.3.2 Tomcat數(shù)據(jù)源鍵 名含 義name指定資源相對(duì)于java:comp/env上下文的JNDI名auth指定資源的

21、管理者(默認(rèn)Container即可)type指定資源所屬的Java類的完整限定名(默認(rèn)即可)maxIdle指定連接池中保留的空閑數(shù)據(jù)庫(kù)連接的最大數(shù)目maxWait指定等待一個(gè)數(shù)據(jù)庫(kù)連接成為可用狀態(tài)的最大時(shí)間,單位毫秒username指定連接數(shù)據(jù)庫(kù)的用戶名password指定連接數(shù)據(jù)庫(kù)的密碼driverClassName指定JDBC驅(qū)動(dòng)程序類名url指定連接數(shù)據(jù)庫(kù)的URL表6.4 Tomcat數(shù)據(jù)源配置文件屬性解析6.3.2 Tomcat數(shù)據(jù)源這里元素的name屬性即為我們使用JNDI去檢索的關(guān)鍵字,在本例中為“shop”。接下來(lái)采用與之前工程相同的方式,創(chuàng)建數(shù)據(jù)庫(kù)工具類.zzti.util.t

22、omcat.DBUtil來(lái)簡(jiǎn)化對(duì)數(shù)據(jù)庫(kù)的操作。6.3.2 Tomcat數(shù)據(jù)源1 public class DBUtil2 private static DataSource ds = null;3 static4 try5 Context initCtx = new InitialContext();6 Context envCtx = (Context)initCtx.lookup(java:comp/env);7 ds = (DataSource) envCtx.lookup(shop); 8 /根據(jù)元素的name屬性值到JNDI容器中檢索連接池對(duì)象9 catch (Exception e

23、) 10 throw new ExceptionInInitializerError(e);11 12 13 public static Connection getConnection() throws SQLException 14 return ds.getConnection(); /利用數(shù)據(jù)源獲取連接15 16 6.3.3 DBCP數(shù)據(jù)庫(kù)連接池(DataBase Connection Pool,DBCP)是Java數(shù)據(jù)庫(kù)連接池的一種,由Apache開發(fā),通過(guò)數(shù)據(jù)庫(kù)連接池可以讓程序自動(dòng)管理數(shù)據(jù)庫(kù)連接的釋放和斷開。DBCP是Apache上的一個(gè)Java連接池項(xiàng)目,也是Tomcat使用的連

24、接池組件。單獨(dú)使用DBCP需要準(zhǔn)備3個(gè)包:commons-dbcp-版本.jar;commons-pool-版本.jar;commons-logging-版本.jar。6.3.3 DBCPDBCP的配置文件的內(nèi)容如下,其參數(shù)含義如表6.5所示。參 數(shù)描 述username傳遞給JDBC驅(qū)動(dòng)的用于建立連接的用戶名password傳遞給JDBC驅(qū)動(dòng)的用于建立連接的密碼url傳遞給JDBC驅(qū)動(dòng)的用于建立連接的URLdriverClassName使用的JDBC驅(qū)動(dòng)的完整有效的Java類名connectionProperties當(dāng)建立新連接時(shí)被發(fā)送給JDBC驅(qū)動(dòng)的連接參數(shù)表6.5 DBCP常見配置參數(shù)含

25、義6.4 DBUtils框架簡(jiǎn)介 Commons DBUtils是Apache組織提供的一個(gè)對(duì)JDBC進(jìn)行簡(jiǎn)單封裝的開源工具類庫(kù),使用它能夠簡(jiǎn)化JDBC應(yīng)用程序的開發(fā),同時(shí)也不會(huì)影響程序的性能。DBUtils是Java編程中的數(shù)據(jù)庫(kù)操作實(shí)用工具,簡(jiǎn)單且實(shí)用。6.4 DBUtils框架簡(jiǎn)介 DBUtils對(duì)于數(shù)據(jù)表的讀操作,它可以把結(jié)果轉(zhuǎn)換成List、Array、Set等Java集合,以便于程序員操作。對(duì)于數(shù)據(jù)表的寫操作,也變得很簡(jiǎn)單,只需寫SQL語(yǔ)句;可以使用數(shù)據(jù)源、JNDI、數(shù)據(jù)庫(kù)連接池等技術(shù)來(lái)優(yōu)化性能,重用已經(jīng)構(gòu)建好的數(shù)據(jù)庫(kù)連接對(duì)象,而不必像PHP、ASP那樣,需要費(fèi)時(shí)費(fèi)力地不斷重復(fù)構(gòu)建和

26、析構(gòu)這樣的對(duì)象。Commons DBUtils的核心類有3個(gè):mons.dbutils.ResultSetHandler、mons.dbutils.QueryRunner、mons.dbutils.DBUtils。6.4 DBUtils框架簡(jiǎn)介 6.4.1 QueryRunner6.4.2 ResultSetHandler6.4.3 資源釋放6.4.1 QueryRunner QueryRunner類簡(jiǎn)單化了SQL查詢,它與ResultSetHandler組合在一起使用可以完成大部分的數(shù)據(jù)庫(kù)操作,能夠大大減少編碼量。(1)QueryRunner類的構(gòu)造方法 默認(rèn)的構(gòu)造方法QueryRunner

27、 queryRunner = new QueryRunner();。 需要一個(gè) javax.sql.DataSource 來(lái)作參數(shù)的構(gòu)造方法。QueryRunner qr = new QueryRunner(DBUtil.getDataSource()6.4.1 QueryRunner (2)QueryRunner類的主要方法 public Object query(Connection conn,String sql,Object params, ResultSetHandler rsh) throws SQLException:執(zhí)行一個(gè)查詢操作,在這個(gè)查詢中,對(duì)象數(shù)組中的每個(gè)元素值被用來(lái)作

28、為查詢語(yǔ)句的置換參數(shù)。該方法會(huì)自行處理 PreparedStatement 和 ResultSet 的創(chuàng)建和關(guān)閉流程。 public Object query(String sql,Object params,ResultSetHandler rsh) throws SQLException:基本與第一種方法相同,唯一的不同在于它不將數(shù)據(jù)庫(kù)連接提供給方法,并且它是從提供給構(gòu)造方法的DataSource數(shù)據(jù)源或使用setDataSource方法設(shè)置的數(shù)據(jù)源。6.4.1 QueryRunner public Object query(Connection conn,String sql,Resul

29、tSetHandler rsh) throws SQLException:執(zhí)行一個(gè)不需要置換參數(shù)的查詢操作。 public int update(Connection conn,String sql,Object params) throws SQLException:用來(lái)執(zhí)行一個(gè)更新操作,如插入、更新或刪除。 public int update(Connection conn,String sql) throws SQLException:用來(lái)執(zhí)行一個(gè)不需要置換參數(shù)的更新操作。6.4.2 ResultSetHandlerResultSetHandler接口用于處理java.sql.Resul

30、tSet,將數(shù)據(jù)按要求轉(zhuǎn)換為另一種形式。ResultSetHandler接口提供了一個(gè)單獨(dú)的處理java.sql.ResultSet的方法: Object handle(java.sql.ResultSet rs)6.4.2 ResultSetHandler(1)查詢類操作方法介紹ResultSetHandler接口的實(shí)現(xiàn)類見表6.6,下面對(duì)每個(gè)接口的實(shí)現(xiàn)類的具體使用方式進(jìn)行介紹。功 能實(shí) 現(xiàn) 類單行數(shù)據(jù)處理ScalarHandler、ArrayHandler、MapHandler、BeanHandler多行數(shù)據(jù)處理BeanListHandler、ArrayListHandler、MapLis

31、tHandler、 ColumnListHandler、KeyedHandler、BeanMapHandler可供擴(kuò)展的類BaseResultSetHandler表6.6 ResultSetHandler接口實(shí)現(xiàn)類說(shuō)明6.4.2 ResultSetHandler ArrayHandler:把結(jié)果集中的第一行數(shù)據(jù)轉(zhuǎn)換成對(duì)象數(shù)組,示例代碼如下。 ArrayListHandler:把結(jié)果集中的每一行數(shù)據(jù)都轉(zhuǎn)換成一個(gè)對(duì)象數(shù)組,再存放到List中,示例代碼如下。1 public static void queryToArray(Connection conn) throws SQLException 2

32、 QueryRunner queryRunner = new QueryRunner();3 String sql = select * from auction;4 Object rs = queryRunner.query(conn, sql, new ArrayHandler();5 for (int i=0;irs.length;i+)6 System.out.print(第一列:+rsi+t);7 8 System.out.print(n);9 1 public static void queryToArrayList(Connection conn) throws SQLExcep

33、tion 2 QueryRunner queryRunner = new QueryRunner();3 String sql = select * from auction;4 List rs = queryRunner.query(conn, sql, new ArrayListHandler();5 for(Object record : rs)6 System.out.println(Arrays.toString(Object)record);7 8 6.4.2 ResultSetHandler BeanHandler:把結(jié)果集中的第一行數(shù)據(jù)封裝到一個(gè)對(duì)應(yīng)的JavaBean實(shí)例中,示

34、例代碼如下。 BeanListHandler:把結(jié)果集中的每一行數(shù)據(jù)都封裝到一個(gè)對(duì)應(yīng)的JavaBean實(shí)例中,再存放到List中,示例代碼如下。1 public static void queryToBean(Connection conn) throws SQLException 2 QueryRunner queryRunner = new QueryRunner();3 4 AuctionDO auc = queryRunner.query(conn,5 select * from auction,6 new BeanHandler( AuctionDO.class);7 System.

35、out.println(auc);8 1 public static void queryToBeanList(Connection conn) throws SQLException 2 String sql = select * from auction;3 QueryRunner queryRunner = new QueryRunner();4 List list = queryRunner.query(conn, sql, 5 new BeanListHandler(AuctionDO.class);6 for (int i = 0; i list.size(); i+) 7 Sys

36、tem.out.println(list.get(i);8 9 6.4.2 ResultSetHandler MapHandler:把結(jié)果集中的第一行數(shù)據(jù)封裝到一個(gè)Map中,key是列名,value就是對(duì)應(yīng)的值,示例代碼如下。 MapListHandler:把結(jié)果集中的每一行數(shù)據(jù)都封裝到一個(gè)Map中,然后再存放到List,示例代碼如下。1 public static void queryToMap(Connection conn) throws SQLException 2 String sql = select * from auction;3 QueryRunner queryRunner

37、 = new QueryRunner();4 Map map = queryRunner.query(conn, sql, new MapHandler();5 SetEntry set = map.entrySet();6 for (Entry entry : set) 7 System.out.println(entry.getKey() + : + entry.getValue();8 9 1 public static void queryToMapList(Connection conn) throws SQLException 2 String sql = select * fro

38、m auction;3 QueryRunner queryRunner = new QueryRunner();4 istMap list = queryRunner.query(conn,sql, new MapListHandler();5 for (Map mapValue : list) 6 SetEntry set1 = mapValue.entrySet();7 for (Entry entry : set1) 8 System.out.println(entry.getKey() + : + entry.getValue();9 10 116.4.2 ResultSetHandl

39、er ColumnListHandler:把結(jié)果集中的某一列的數(shù)據(jù)存放到List中,示例代碼如下。 KeyedHandler:把結(jié)果集中的每一行數(shù)據(jù)都封裝到一個(gè)Map中(List),再把這些Map存到一個(gè)Map里,其key為指定的列,示例代碼如下。1 public static void queryToColList(Connection conn) throws SQLException2 QueryRunner queryRunner = new QueryRunner();3 String sql = select * from auction;/where id=14 List lis

40、t = (List) queryRunner.query(conn, sql, 5 new ColumnListHandler(name);6 System.out.println(list);7 1 public static void queryToKeyedHandler(Connection conn) throws SQLException2 QueryRunner queryRunner = new QueryRunner();3 String sql = select * from users;4 MapInteger, Map rs1 = queryRunner.query(c

41、onn,sql, 5 new KeyedHandler(1);6 System.out.println(KeyedHandler: + rs1);7 MapInteger, Map rs2 = queryRunner.query(conn,sql, 8 new KeyedHandler(title);9 System.out.println(KeyedHandler: + rs2);10 6.4.2 ResultSetHandler BeanMapHandler:用于獲取所有結(jié)果集,將每行結(jié)果集轉(zhuǎn)換為Javabean作為value,并指定某列為key,封裝到HashMap中。相當(dāng)于對(duì)每行數(shù)據(jù)進(jìn)

42、行與BeanHandler相同的處理后,再指定列值為Key封裝到HashMap中。1 public static void queryToBeanMap(Connection conn) throws SQLException2 QueryRunner queryRunner = new QueryRunner();3 String sql = select * from auction;4 Map rs = queryRunner.query(conn, sql, 5 new BeanMapHandler(AuctionDO.class,1);6 System.out.println(Bea

43、nMapHandler: + rs);7 6.4.2 ResultSetHandler ScalarHandler:獲取結(jié)果集中第一行數(shù)據(jù)指定列的值,常用來(lái)進(jìn)行單值查詢,示例代碼如下。(2)更新類操作方法介紹在執(zhí)行insert、delete、update等更新數(shù)據(jù)庫(kù)方法時(shí),將調(diào)用QueryRunner的update方法,該方法返回影響的記錄條數(shù)。1 public static void queryToBeanMap(Connection conn) throws SQLException2 QueryRunner queryRunner = new QueryRunner();3 String

44、 sql = select * from auction;4 int rs = runner.query(conn,sql, new ScalarHandler();5 System.out.println(ScalarHandler: + rs); 6 String rs = runner.query(conn,sql, new ScalarHandler(2);7 / 或者 String rs = runner.query(conn,sql, new ScalarHandler(userName);8 System.out.println(ScalarHandler: + rs); 9 6

45、.4.3 資源釋放DBUtils 框架提供了關(guān)閉連接、裝載JDBC驅(qū)動(dòng)程序等常規(guī)工作的工具類,里面的所有方法都是靜態(tài)的。主要方法如下: public static void close() throws SQLExceptionDBUtils類提供了3個(gè)重載的關(guān)閉方法。這些方法檢查所提供的參數(shù)是否為NULL,如果不是,它們就關(guān)閉Connection、Statement和ResultSet6.5 簡(jiǎn)易購(gòu)物商城使用DBCP作為數(shù)據(jù)庫(kù)連接池連接數(shù)據(jù)庫(kù),與DBUtils框架整合來(lái)改寫簡(jiǎn)易購(gòu)物商城的前臺(tái)系統(tǒng),將商品、用戶、個(gè)人信息持久化存儲(chǔ)到MySQL數(shù)據(jù)庫(kù)中。6.5 簡(jiǎn)易購(gòu)物商城6.5.1 數(shù)據(jù)庫(kù)設(shè)計(jì)

46、6.5.2 DAO接口實(shí)現(xiàn)6.5.1 數(shù)據(jù)庫(kù)設(shè)計(jì)根據(jù)前面章節(jié)的需求分析,簡(jiǎn)易購(gòu)物商城前臺(tái)系統(tǒng)共設(shè)計(jì)數(shù)據(jù)庫(kù)表三張,首先創(chuàng)建數(shù)據(jù)庫(kù)shop,然后在數(shù)據(jù)庫(kù)shop中設(shè)計(jì)auction、user和personalInfo三張數(shù)據(jù)表,具體表結(jié)構(gòu)如圖6.23圖6.25所示。圖6.23 action商品表圖6.24 user用戶表圖6.25 personal個(gè)人信息表6.5.2 DAO接口實(shí)現(xiàn)首先在工程中導(dǎo)入相關(guān)的jar包,并創(chuàng)建.zzti.dao包中各個(gè)接口的具體實(shí)現(xiàn)類,放在.zzti.dao.impl.mysql包下,如圖6.26和圖6.27所示。圖6.26 導(dǎo)入相關(guān)jar包圖6.27 基于DBUtil

47、s的DAO實(shí)現(xiàn)6.5.2 DAO接口實(shí)現(xiàn)各個(gè)實(shí)現(xiàn)類的具體實(shí)現(xiàn)代碼如下所示。(1)AuctionDAOImpl1 public class AuctionDAOImpl implements AuctionDAO2 Override3 public AuctionDO getAuction(String id) throws SQLException 4 QueryRunner queryrunner = new QueryRunner(DBUtil.getDataSource();5 String sql=select * from auction where id = ?;6 Auction

48、DO auctionDO = queryrunner.query(sql,7 new BeanHandler(AuctionDO.class), id);8 return auctionDO;9 10 Override11 public void addAuction(AuctionDO auc) throws SQLException 12 QueryRunner queryrunner = new QueryRunner(DBUtil.getDataSource();13 String sql=insert into auction values(?,?,?,?);14 Object pa

49、rams = new ObjectUUID.randomUUID().toString(),15 auc.getTitle(),auc.getDescription(),auc.getPrice();16 queryrunner.update(sql, params);17 6.5.2 DAO接口實(shí)現(xiàn)各個(gè)實(shí)現(xiàn)類的具體實(shí)現(xiàn)代碼如下所示。(1)AuctionDAOImpl18 Override19 public List getAll() throws SQLException 20 QueryRunner queryrunner = new QueryRunner(DBUtil.getDataS

50、ource();21 String sql=select * from auction ;22 List list = queryrunner.query(sql, 23 new BeanListHandler(AuctionDO.class);24 return list;25 26 Override27 public void deleteAuction(String id) throws SQLException 28 QueryRunner queryrunner = new QueryRunner(DBUtil.getDataSource();29 String sql=delete

51、 from auction where id=?;30 queryrunner.update(sql, id);31 32 Override33 public void updateAuction(AuctionDO auc) throws SQLException 34 QueryRunner queryrunner = new QueryRunner(DBUtil.getDataSource();35 String sql=update auction set title=?,description=?,price=? where id=?;36 Object params = new O

52、bjectauc.getTitle(),37 auc.getDescription(),auc.getPrice(),auc.getId();38 queryrunner.update(sql, params);39 40 6.5.2 DAO接口實(shí)現(xiàn)(2)PersonalDAOImpl1 public class PersonalDAOImpl implements PersonalDAO2 Override3 public PersonalInfoDO getPersonalInfo(String username) throws SQLException 4 QueryRunner queryrunner = new QueryRunner(DBUtil.getDataSource();5 String sql=select * from personalInfo where username = ?;6 Per

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論