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

下載本文檔

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

文檔簡介

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

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

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

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

5、的“mysql-connector-java-5.1.42-bin.jar”復(fù)制到“WebRootlib”文件夾下,如圖6.4所示。6.2.1 創(chuàng)建數(shù)據(jù)庫連接圖6.3 下載MySQL驅(qū)動包圖6.4 加載MySQL驅(qū)動包6.2.1 創(chuàng)建數(shù)據(jù)庫連接2數(shù)據(jù)庫管理工具在開發(fā)中,我們一般會創(chuàng)建一個專用于創(chuàng)建數(shù)據(jù)庫連接和釋放數(shù)據(jù)庫連接的工具類。建立與數(shù)據(jù)庫的連接需要完成如下兩個步驟。(1)加載驅(qū)動類到內(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í)行在實際開發(fā)中,當(dāng)需要訪問數(shù)據(jù)庫時,只需要調(diào)用以下方法: Connection conn = DBUtil.getConnection();就可以獲得一個java.sql.Connection類型的數(shù)據(jù)庫連接對象,通過這個連接對象,用戶可以操作數(shù)據(jù)庫,發(fā)送目標(biāo)SQL給數(shù)據(jù)庫,并接收響應(yīng)結(jié)果。6.2.2 SQL的執(zhí)行在已建立數(shù)據(jù)庫連接的基礎(chǔ)上,向數(shù)據(jù)庫發(fā)送要執(zhí)行的SQL語句的接口是Statement。Statement用于執(zhí)行靜態(tài)的SQL語句。(1)java.sql.Statementjava.sq

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

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

9、r(String username, String password) throws SQLException;具體代碼如下:6.2.2 SQL的執(zhí)行在代碼的第6行,我們將拼接后的SQL語句打印到控制臺進行觀察。在第12行處,需要將獲得的數(shù)據(jù)庫查詢結(jié)果進行封裝,這里暫不實現(xiàn)這個功能。下面先來創(chuàng)建一個.zzti.dao.impl.mysql.jdbc.test.UserDAOImplTest類,對方法findUser進行測試,具體代碼如下。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對象中,此處先不處理13 return user;14 15 return null;16 6.2.2 SQL的執(zhí)行Assert.assertNotNull(Object o)是Junit的斷言,該斷言方法判斷對象o是否為空,為空則當(dāng)前測試方法通過,否則測試方法失敗。執(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=在這個SQL中,“#”代表MySQL中的注釋。該語句的本意是從數(shù)據(jù)庫中獲取全部的數(shù)據(jù),因為“or 1=1”使得這個條件恒為真。select * from user where username=test or 1=16.2.2 SQL的執(zhí)行為了避免SQL注入的問題,JDBC提供了一種SQL預(yù)編譯的機制,即PreparedStatement。首先用戶提交的SQL中可以不指定具體的參數(shù),對于可變值部分讓用戶使用“?”(即占位符)來代替。然后再對SQL中的占位符單獨設(shè)置值,將兩者提交給數(shù)據(jù)庫引擎進行編譯,此時數(shù)據(jù)庫引擎僅僅編譯帶有占位符“?”的S

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

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

16、y和executeUpdate,Statement在執(zhí)行execute*方法時,需要以SQL為字符串參數(shù)進行傳遞,而PreparedStatement則不需要參數(shù)。調(diào)用規(guī)則總結(jié)如表6.2所示。6.2.3 SQL執(zhí)行結(jié)果處理類 名方 法 定 義說 明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ù)庫連接池創(chuàng)建數(shù)據(jù)庫連接是一個十分耗時的操作,也容易讓數(shù)據(jù)庫產(chǎn)生安全隱患。因此,在程序初始化的時候,集中創(chuàng)建了多個數(shù)據(jù)庫連接,并對它們進行集中管理,以供程序使用,這樣就可以保證較快的數(shù)據(jù)庫讀/寫速度,而且更加安全可靠。數(shù)據(jù)庫連接池的運行原理如圖6.16所示。6.3 數(shù)據(jù)庫連接池Servlet1Servlet2.ServletnDAO1.DAOmMySQLuser1.usersConnectionConnection.Connection圖6.16 數(shù)

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

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

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

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

22、omcat.DBUtil來簡化對數(shù)據(jù)庫的操作。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容器中檢索連接池對象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ù)庫連接池(DataBase Connection Pool,DBCP)是Java數(shù)據(jù)庫連接池的一種,由Apache開發(fā),通過數(shù)據(jù)庫連接池可以讓程序自動管理數(shù)據(jù)庫連接的釋放和斷開。DBCP是Apache上的一個Java連接池項目,也是Tomcat使用的連

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

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

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

27、 queryRunner = new QueryRunner();。 需要一個 javax.sql.DataSource 來作參數(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í)行一個查詢操作,在這個查詢中,對象數(shù)組中的每個元素值被用來作

28、為查詢語句的置換參數(shù)。該方法會自行處理 PreparedStatement 和 ResultSet 的創(chuàng)建和關(guān)閉流程。 public Object query(String sql,Object params,ResultSetHandler rsh) throws SQLException:基本與第一種方法相同,唯一的不同在于它不將數(shù)據(jù)庫連接提供給方法,并且它是從提供給構(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í)行一個不需要置換參數(shù)的查詢操作。 public int update(Connection conn,String sql,Object params) throws SQLException:用來執(zhí)行一個更新操作,如插入、更新或刪除。 public int update(Connection conn,String sql) throws SQLException:用來執(zhí)行一個不需要置換參數(shù)的更新操作。6.4.2 ResultSetHandlerResultSetHandler接口用于處理java.sql.Resul

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

31、tHandler、 ColumnListHandler、KeyedHandler、BeanMapHandler可供擴展的類BaseResultSetHandler表6.6 ResultSetHandler接口實現(xiàn)類說明6.4.2 ResultSetHandler ArrayHandler:把結(jié)果集中的第一行數(shù)據(jù)轉(zhuǎn)換成對象數(shù)組,示例代碼如下。 ArrayListHandler:把結(jié)果集中的每一行數(shù)據(jù)都轉(zhuǎn)換成一個對象數(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ù)封裝到一個對應(yīng)的JavaBean實例中,示

34、例代碼如下。 BeanListHandler:把結(jié)果集中的每一行數(shù)據(jù)都封裝到一個對應(yīng)的JavaBean實例中,再存放到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ù)封裝到一個Map中,key是列名,value就是對應(yīng)的值,示例代碼如下。 MapListHandler:把結(jié)果集中的每一行數(shù)據(jù)都封裝到一個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ù)都封裝到一個Map中(List),再把這些Map存到一個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)于對每行數(shù)據(jù)進

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ù)指定列的值,常用來進行單值查詢,示例代碼如下。(2)更新類操作方法介紹在執(zhí)行insert、delete、update等更新數(shù)據(jù)庫方法時,將調(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ū)動程序等常規(guī)工作的工具類,里面的所有方法都是靜態(tài)的。主要方法如下: public static void close() throws SQLExceptionDBUtils類提供了3個重載的關(guān)閉方法。這些方法檢查所提供的參數(shù)是否為NULL,如果不是,它們就關(guān)閉Connection、Statement和ResultSet6.5 簡易購物商城使用DBCP作為數(shù)據(jù)庫連接池連接數(shù)據(jù)庫,與DBUtils框架整合來改寫簡易購物商城的前臺系統(tǒng),將商品、用戶、個人信息持久化存儲到MySQL數(shù)據(jù)庫中。6.5 簡易購物商城6.5.1 數(shù)據(jù)庫設(shè)計

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

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

評論

0/150

提交評論