版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quá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應用方面,MySQL是最好的關(guān)系數(shù)據(jù)庫管理系統(tǒng)(Relational DataBase Management System,RDBMS)應用軟件。6.2 JDBC概述Java 數(shù)據(jù)庫連接技術(shù)(Java DataBase Connectivity,JDBC)是 Java 訪問數(shù)據(jù)庫資源的標準,JDBC 標準定義了一
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 應用移植到另一個數(shù)據(jù)庫應用上。6.2 JDBC概述圖6.1 應用程序直接訪問數(shù)據(jù)庫圖6.2 應用程序訪問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ù)的預編譯 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ù)庫,一般應該通過如下幾步。1下載數(shù)據(jù)庫開發(fā)所需要的驅(qū)動包用戶可以從對應的數(shù)據(jù)庫廠商的官網(wǎng)進行下載,例如,下載MySQL驅(qū)動包,如圖6.3所示,選擇“JDBC DriverforMySQL”進行下載。下載的驅(qū)動包是一個壓縮包,將包內(nèi)
5、的“mysql-connector-java-5.1.42-bin.jar”復制到“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ā)中,當需要訪問數(shù)據(jù)庫時,只需要調(diào)用以下方法: Connection conn = DBUtil.getConnection();就可以獲得一個java.sql.Connection類型的數(shù)據(jù)庫連接對象,通過這個連接對象,用戶可以操作數(shù)據(jù)庫,發(fā)送目標SQL給數(shù)據(jù)庫,并接收響應結(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是否為空,為空則當前測試方法通過,否則測試方法失敗。執(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預編譯的機制,即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也需要進行相應的改寫:String sql=select * from user where username = ? and password=?;與之前的SQL對比可以發(fā)現(xiàn),原來的形式參數(shù)部分被占位符“?”代替,那么就需要將形式參數(shù)與具體的“?”綁定。綁定操作可
15、通過調(diào)用 setXXX 方法來完成,其中,XXX 是與該參數(shù)相對應的類型。例如,如果參數(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的時候,主要應用的執(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ū)動,而不再是應用程序需要JDBC驅(qū)動,
20、所以要先將對應數(shù)據(jù)庫的JDBC驅(qū)動類庫復制到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、管理者(默認Container即可)type指定資源所屬的Java類的完整限定名(默認即可)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需要準備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當建立新連接時被發(fā)送給JDBC驅(qū)動的連接參數(shù)表6.5 DBCP常見配置參數(shù)含
25、義6.4 DBUtils框架簡介 Commons DBUtils是Apache組織提供的一個對JDBC進行簡單封裝的開源工具類庫,使用它能夠簡化JDBC應用程序的開發(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那樣,需要費時費力地不斷重復構(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)造方法 默認的構(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ù)封裝到一個對應的JavaBean實例中,示
34、例代碼如下。 BeanListHandler:把結(jié)果集中的每一行數(shù)據(jù)都封裝到一個對應的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就是對應的值,示例代碼如下。 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中。相當于對每行數(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)首先在工程中導入相關(guān)的jar包,并創(chuàng)建.zzti.dao包中各個接口的具體實現(xiàn)類,放在.zzti.dao.impl.mysql包下,如圖6.26和圖6.27所示。圖6.26 導入相關(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)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 環(huán)保檢測信息共享協(xié)議
- 房屋買賣定金合同意向金
- 會計稅務申報服務合同
- 招標文件備案全教程
- 車輛服務合同的簽訂程序
- 職業(yè)裝制作合同樣式
- 政府采購合同的培訓課程
- 居家護工護理合同
- 企業(yè)年度采購合同案例
- 磚瓦殘骸購銷協(xié)議
- 全國青島版初中信息技術(shù)第四冊第二單元第9課《初識物聯(lián)網(wǎng)》教學設(shè)計
- AQ/T 1023-2006 煤礦井下低壓供電系統(tǒng)及裝備通 用安全技術(shù)要求(正式版)
- 內(nèi)容營銷策劃管理合同
- 2024河北工業(yè)職業(yè)技術(shù)大學教師招聘考試筆試試題
- 國際物流運輸管理智慧樹知到期末考試答案章節(jié)答案2024年上海海事大學
- 銀行轉(zhuǎn)賬截圖生成器制作你想要的轉(zhuǎn)賬截圖
- 食管早癌的內(nèi)鏡診斷
- 幼兒園進餐案例及分析總結(jié)
- 2024年中考英語第一次模擬考試(南京卷)
- 2023-2024學年江西省南昌二十八中教育集團八年級(上)期末英語試卷
- 輔助生殖科輔助生殖技術(shù)診療規(guī)范與技術(shù)操作規(guī)范
評論
0/150
提交評論