day14--dbutils的使用,事務處理,多表操作,oracle大數據處理_第1頁
day14--dbutils的使用,事務處理,多表操作,oracle大數據處理_第2頁
day14--dbutils的使用,事務處理,多表操作,oracle大數據處理_第3頁
day14--dbutils的使用,事務處理,多表操作,oracle大數據處理_第4頁
day14--dbutils的使用,事務處理,多表操作,oracle大數據處理_第5頁
已閱讀5頁,還剩13頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、dbutils的使用,事務處理,多表操作,oracle大數據處理作者:呂鵬時間:2011-08-08首先還是簡單的回顧一下昨夭我們講的什么,我們昨天講了數據庫連接池,為防止頻繁訪問 數據庫而建芷的連接池的實現有兩種一個是自定義連接池,使用動態代理方式,另外一個是 使用DBCRC3P0,Tomcat等服務器口帯的,都可以實現連接池 I、午講了動編寫口(2的 JDBC框架,簡化了 CRUD操作,為我們今天講這個DBUtils打下一個基礎。目錄:一、DBUtils框架的使用1、使用dbutils做增刪改查,批處理以及人文本操作2、使用DBUtils框架管理事務。(模擬銀行轉賬)二、使用JDBC操作多

2、個表1、一對多(部門與員工)2、多對多(學生和老師 學生與課程)3、一對一(人和身份證)三、關于Oracle數據對于二進制數據的存取(面試題)一、DBUltk框架的使用jj apidocs2011/8/8 16:29文件夾common dbutils-1.22011/8/8 16:29文件交t I commons-dbutils-1.2.jar2009/3/15 12:04Executable Jar Filecommonsdbirtilsl'jaYadoc,jar2009/3/15 12:05Executable Jar Filecommons-dbutils-1.2-sources

3、 jar2009/3/15 12:05Executable Jar Fileg LICENSE.txt2009/3/15 12:04.NOTICE.txt2009/3/15 12:04文4,RELEASE-NOTES.txt2Q09/3/15 12:04文本文旨1、使用dbutils做增刪改査,批處理以及大文本操作package cn itcast dbutils. demo;import java.io.File;import j ava .10 FilelnputStream;import java.io.FileReader;impert java.util.List;import ja

4、vax sql rowset senal SenalBlob;import javax sql.rowset.senal.SenalClob;import org apache coninions.dbutils QueiyRumier;import org apache commons.dbutils handlers BeanHandler;import mons.dbutils handlers.BeaiiListHaiidler; Import org.jumt.BefbreClass;import orgjumt.Test;import cn. itcast. dbutil. JDB

5、CU tils;/*使用dbutils做增刪改杳批處理大文本操作* (author 呂鵬* public class DemoO 1 /"創建demo表+| Field | Type| Null | Key | Default | Extra | "4*|id | mt(ll) I YES I I NULL |I name | varchar(lO) | YES | NULL |+/static QuetyRuiiner runner.BefbreClasspublic static void befbreClass()獲取一個QueryRiumer對象(構造方法帶數據源

6、口動完成連接創建和釋放) rufiner= new QueiyRumier(JDBCUtilszZ?/f75<2/r();/*執行插入操作/Testpublic void testlnsert()throws Exception!Strmg sql = "insert into demo values(?,?)H; J!, IsqlObject params = 2畀insert”;/初始化參數/7/7/:update(sql, params);/查詢對象操作 throws Exception/Testpublic void testObjectQueryO throws Ex

7、ceptionStrmg sql = ”select from demo where id = ?M;Demo demo = (Demo)廠科甲謝予(sg 1、newBeanHandler(DemoSystem /z/.pniitlii(MID:,t+demo.getId()+H Name:H+demo.getName();*執行刪除操作 throws Exception/Testpublic void testDelete() throws Exception Stiing sql = Hdelete from demo where id = ?H;刃 update(sql, 1);/*執行

8、更新操作 ©throws Exception/Testpublic void testUpdate() throws Exception Strmg sql = "update demo set name=? where id="Object params =update”,】;刃:update(sqL params);*査詢列表操作 throws Exception/Testpublic void testListQueiyO throws Exception String sql = Mselect from demo”;List<Demo> li

9、st =(List vDemo>)q . query (sq LnewBeanListHandler(Demo class):for(int i=O;i<list. size();i+) System.d?/.pnntln(HID:H+list.get(i).getIdO+H 姓名是:H+list.get(i).getName();/*批處理操作 throws Exception/Testpublic void testBatch() throws Exception Strmg sql = "insert mto demo value (?,?)";Objec

10、t paiains = new Object10; for(int i=0;i<10;i+)paramsfi = new Objectbatch”;Z7/w/7:batch(sql, paiains);/*人文本操作 throws Exception/Testpublic void testClobO throws ExceptionStrmg sql = "insert mto clob values(?)H;File file = new File(Hc:/a txtH);Long 1 = file.lengthO;char buffer = new a

11、lue();FileReader reader = new FileReader(file); reader read(buffer);SenalClob clob = new SenalClob(buffer);刃:update(sql, clob);/*二進制圖像操作 throws Exception/Testpublic void testBlobO throws Exception String sql = "insert into blob values(?)H;File file = new File(Mc:/ajpgH);Long 1 = file.lengtliO;b

12、yte buffer = new bytel int alueO;Fileinputstream input = new hilelnputstream(file); input, read(buffer);Sena IB lob blob = new SenalBlob(buffer); update(sql,blob);以上代碼是使用DButils框架完成的增刪改差批處理以及大文本操作,其中,使用了 QueryRiumer這個類,這個類是專門負責處理sql語句的,有四個構造方法,我們經常使用 到的是一個無參的構造方法和一個有參的,參數就是數據源,當我們給其提供數據源的時候 就是讓框架為我們

13、口動的創建數據庫連接,并釋放連接,當這是處理一般操作的時候,當我 們要進行事務處理的時候,那么連接的釋放就要由我們口己來決定了,所以我們就不再使用 帶參數的QueryRuimer構造方法了。具體用法下面詳解。2、使用DBUtils框架管理事務。剛才我們的增刪改差是為了演示我們的例子,所以我們忽略了異常也沒有使用事務,現在我 們使用爭務模擬一個銀行轉賬,看一下DBUtils框架是如何幫助我們完成爭務管理的。在講解事務之前,需要讓大家理解一件爭情就是,我們使用弔務就不能使用其QueryRimner 的有參構造方法I大1為我們要自己定義爭務的開關,如果使用帶參數的構造就要讓框架幫 助我們關閉數據庫連

14、接了,所以這里首先人家要明白.那么我們如何將我們的連接傳遞給持 久層呢,有同學說使用構造方法,是挺好的,通過構造方法將我們的conn傳遞給持久層, 但是為了降低耦合度,我們不想在業務層出現持久層的代碼,那我們就使用一個類幫助我們 把這個連接傳遞過去,就相當于使用匸廠幫我們生成持久層對彖一樣,那我們使用什么類呢, 我們使用ThreadLoacl這個類關于TlireadLocal這個類,可以查閱幫助文檔了解,在這里我簡單的說明一下它的作用, 它的作用是在一個線程當中記錄我們的變龜,這個變鼠可以是任意變晟,包括我們的連接, 就是說我們生成一個連接以后可以放在這個線程中,這樣,只要是這個線程中任何對象

15、都町 以共享這個連接,當這個線程結束以后,線程要刪除這個連接。具體使用方法:聲明線程共享變量public static TlireadLocal<Connection> container = new TlireadLocal<Conuection>();獲取共享變量public static ThreadLocal<Coiinection> getContainerOreturn cont(iuiet這樣,那么我們就可以幫有關審務的操作,這些操作原本應該在業務層出現的代碼,現 在我們都把它放在工具類中,因為不管是事務開啟還是事務提交,回滾,都是利連接關聯的

16、.我們把連接放在了這個共享的線程當中,那么其方法也是共享的:工其類如下:package cn.itcast.dbutil;import j ava sql Comiection;Import java.sql.SQLException;Import javax.sql DataSoiirce;import com.mchaiige.v2c3pO.ComboPooledDataSource,public class JDBCUtils c3pO連接池public static ComboPooledDataSomce ds= new ComboPooledDataSource();聲明線程共享變

17、量public static ThreadLocal<Coiinection> con tain er- new TlireadLocal<Comiection>();/獲取共享變量public static TlireadLocal<Coiinection> getContainerOreturn container.*獲取數據源/public static DataSource getDataSourceOfreturn ds/*茯取當前線程上的連接 開啟事務public static void startTransactionO Connection

18、comi = containerfi 先茯取 j 前'戈 fT 的連接 if(comi = null) /如果連接為空conn = gerCofmecnofiQ 從連接池中獲収連接 cotitmner. set(conn); 7 將此連接丿,?上comi.setAutoComiuit(false); 11: t ); catch (SQLException e) throw new RuntuneException(e.getMessage(),e); /*提交事務/public static void coinmitO Connection conn = containerJ!從當前

19、 I .獲取連接 if (conn != nuD) /如杲連接為字,則不做處理coiin commitO;/. 捉 龍!;并 catch (SQLException e) throw new RuntimeExceptionCe.getMessageO, e);/*回滾事務/public static void rollback。Connection conn = container.getO; V 化打前錢丘'l. m 1? 丫匚連綏 if(comi != null)try coiin.rollbackO;/ 回滾 M 務/container.removeO;/如果回滾了,就移除這個

20、連接 catch (SQLException e) throw new RimtimeException(e.getMessage(),e);/*關閉連接/public static void close()Connection conn = contmner Q if(conii != null)trycoiin.close(); catch (SQLException e) throw new RmituneException(e.getMessageO,e); finally e加0:remove();從當前纟戈程移除連接 切記*獲取數據庫連接 return數據庫連接 連接方式(連接池

21、錯c3pO)/public static Connection getCoiinection() try return .getComiectionO; catch (Exception e) throw new RuntuneException();在這個工具類里要特別注意,在關閉連接方法的里面,finally里需要將這個線程的連接 移除,不然這個線程的連接得不到釋放。這個明白了以后再看我們的銀行轉賬的模擬程序:首先我們在模擬的DAO中完成査找賬戶和修改賬戶的方法:(1) 査找賬戶和修改賬戶代碼:*模擬DAO查詢賬戶更新賬戶* ©author 呂鵬*/class AccouiitD

22、AO 聲明連接private Connection conn;public AccountDAO() this.conn = JDBCUtils.g刃6加0().getO;/,線 共'? X>j 象獲収連接/*8*根據ID資找賬戶/public Account findAccount(int id) 處理事務,無參構造Query Runner nrnner = new QueryRuiiner();Strmg sql = "select * from account where id=?H;Object params=id;try 附加連接 處理者為BeanHandle

23、rreturn (Account) ruimer.qtt«=y(conih sql, params, newBeanHandler(Account daw): cateh (Exception e) System.(2/.pnntln(HeeeeeeeeeeeeeeeH);throw new RuntuneException(e getMessage(),e);/*更新賬戶 param a/public void updateAccount(Account a)QueiyRumier nurner = new QueryRunner();String sql = "upda

24、te account set money=? where id=?M;Object params = a.getMoneyO,a getld();try rumier.update(comi, sql、params); catch (SQLException e) throw new RuntmieException(e getMessage(),e);(2) 完成業務邏輯層的轉賬事務class AccountSerxice /*r*轉賬方法 param fromlD 原始賬戶 param toID 目標賬戶 param money轉入多少錢/public void tiafferAccoun

25、t(lnt fiomID,int toID,float money)tryJDBCUtils jTW"刀 丿 I 丿匸'K 務AccountDAO dao = Factory疥Z屜伽rcO.getAccountDAOO;/注意這彳亍代碼一定要放在開啟事務之后,連接才會被創建Account from = dao. findAccount(fioinlD);Account to = dao findAccount(tolD);from setMoney(from.getNIoney()-money); to.setMoney(to.getMoiiey()靜態工廠獲取操作對象* a

26、uthor 3 鵬*/class Factory 私有靜態工廠實例private static Factory itistance - null:私有構造private FactoryO /*提供一個靜態公共方法獲取工廠實例 retum/public static Factoiy getlnstance() if instance null) synchronized (Factory class) If ltisfance null) instance = new FactoryO;moiiey);dao.update Accoiuit(from);dao.updateAccoimt(to)

27、;JDBCUtils e加O 捉交事務System out. printing 轉 賬成功”); catch (Exception e) System.67/.pnntlnC* 轉賬失敗”);JDBCUtils.rollbacki >1 滾'"務throw new RuntuneException();finaUyJDBCUtils.r/jO;被標注紅色的代碼要注意,其重點不只是工廠模式的使用,更重要的一點要明白,我們的持 久層的連接是在其構造方法中獲取的,如果我們把這個代碼放在前面的話,就提前構造了其 對象,但是我們的連接卻是在半務開啟的時候才創建的,如此我們的連接就

28、無法傳遞到持久 層當中了。所以這段代碼要放在之后。待我們的連接被放置在當前線程以后再去調用工廠構 造我們的對象。(3) 靜態工廠獲取實例return uistance./*獲取操作對象簡化代碼不讀配置文件了* return/public AccountDAO getAccouutDAO() return new AccountDAOO;public AccountSemce getAccountSenrice() return new AccouiitSeiviceO;(4)測試類:*轉賬測試類* anthor i_i 鵬*/public class Test public static vo

29、id mam(Stniig aigs) 使用工廠模式生成業務層對象AccountSen ice semce = Factory.77加7?zr0 getAccoimtService(); 調用業務層的方法從1號賬戶轉賬100到2號賬戶 semce.trafferAccoiuit( 1, 2, 100);效果:mysql> select from account;+| id I name money |I1 I tom I 30011 2|cc I 1700|2 rows m set (0.00 sec)轉賬成功。從這個模擬的銀行轉賬我們學到了 :(1)在業務層完成事務的處理,持久層只負責

30、操作數據庫(1) DBUtils對事務的操作流程(2) 使用ThreadLoacl共享單線程信息二、使用JDBC操作多個表學習使用JDBC操作多個表是學習Hibernate的基礎,掌握了 JDBC對多表的操作其實就是 在學習Hibernate實現多表操作的底層原理。下面我們來看一下,使用JDBC如何完成對多 表的操作,學習多表操作之前我們需要明白什么叫多表操作:多表操作其實就是對多個對象的關系的操作,如果對帶仃關系的對象進行數據庫操作就是 對操作操作。那對象和對象之間又有什么關系呢?(1) 一對多(2) 多對多一對一O O O O1、一對多關系操作我們舉部門和員工的例子,部門和員工就是典型的一

31、對多的范例,那么我們如何描述他們之 前的關系呢?要使用到外鍵,首先我們來看他們的表如何設計:package cn.itcast dao;import java.util. Set;import org. apache .commons dbutils. QueiyRumier;import nions.dbutils handlers.BeaiiHandler;import org mons.dbutils handlers BeanListHandler;Impert cn.itcast.dbutils.JDBCUtils;import cn. itcast.domain Departmen

32、t;import cn. itcast. domain Employee;pubtic class DepeitinentDAO /*增加一個部門同時増加其員工 param depart/public void addDepai1meiit(Depaitment depart) tryQueryRunner mn = new QuetyRunner( JDBCUtils getDafaSourci)Stnng sql = "insert mto department value(?,?,?)H;Object params = 1/開發部" nin.update(sql, p

33、aiains); 執行插入一個部門Set<Employee> eins = depait. getEmployeesO;7 血詢;t :部 Xj 繚:rj 員 1* 集介for(Employee e : ems)Stiing sql2 = Minsert into employee value(?,?,?) where departed = ?”; Object params? = e.getld(),e getName(),e.getMoneyO,depart getld(); iiui.update(sql2, paiams2); /執行插入女個員 Lcatch(Excepti

34、on e)throw new RuntnneException();*査詢一個部門.同時資詢其部門下的員工public Department fiiidDepartment(int id)Department depart = null;try首先查詢部門QueryRunner runner = new QueryRunner(JDBCUtils.gw/Z>"/5b/5f4);Stnng sql = "select * fi om department where id = ?”;depart = (Department) runnerid、new EeanHandl

35、er(Departnieiit da翦);根據部門的ID也就是員工的外鍵查詢員工集合 設置到depart的屬性當中去 Stnng sql2 = "select from employee where departed = ?H;Set<Employee> emps = (SetvEmployee>) runner 申tefy(sql2、id, newBeanListHandlerCEmplovee class):depart.setEmployees(emps); catch (Exception e) throw new RuntnneException(e ge

36、tMessage(),e);return depart;2、多對多的關系多對多足比牧復雜的,在數據庫中我們需要三張表米維護他們的關系,一張中間表,但實體 對彖只有兩個,拿學生和課程來講,一個學生可以選擇務門課程而,而一個課程又可以彼多 個學生選擇,如果維護他們的關系呢,我們看例子: package cn.itcast.dao;import j ava.util. Set;impert moiis.dbutils.QueiyRuniier;impert mons.dbutils handlers.BeaiiHandler;impert org mons.dbutils handlers Bean

37、ListHandler;import cn.itcast.dbutils.JDBCUtils;import cn.itcast.domam Cowse;impert cn. itcast. domain Strident;public class StudentDAO *添加一個學生,同時添加其選課課程/public void addStudent(Student student) tryQueryRuiiner mn = new Quer)rRunner( JDBCUtils getDataSourc) String sqll = Minsert into student values(?,

38、?)H;Object params fl = student.getId(),stiident.getNameO;Set<Coiirse> courses = student.getCoiirses();for(Course c : courses"Stiing sql2=Hinsert into couise values(?,?)H;Object params2 = c.getId(),c.getName();nm update(sql2, params2);Stiing sql3=Hinsert into shident_course value(?,?)tf;Ob

39、ject params3=student getldO,c.getld(); iTui.update(sql3, paiains3);catch(Exception e)throw new RuntnneException(e getMessage(),e);/*査詢一個學生,同時將其選課信息査詢出來*/public Student findSUident(int id)Student student = null;try QueryRunner ninner = new QueryRunner(JDECUtils.gwzQ"A75切"();Stnng sql = &quo

40、t;select * from student where id = ?M;student = (Student) iTmner.quefy(sqL id, new BeanHandler(Student class);/這句話什么意思呢?就是說我們要査詢學生的課程,要保證兩個條件(1)保證學生的id和中間表中的學生m是一樣的才能保證你要找的是這個學 生(2)保證課程的ID和中間表中的課程ID是一樣的才能保證你要找的是這些課 程兩者缺一不可,只有同時保證這個兩個條件才能確認這些課程就是這個學生 的。Stnng sql2 = "select fiom shident_course sc

41、,course c where sc.sid=? and sc.cid= c.id”;Set<Coiirse> courses = (SetvCourse>) runner.e«eF¥(sal2, id, new BeanListHandler(Course.d>,$):stiident.setCourses(courses); catch (Exception e) throw new RimtiineException(e.getMessaeeO,e);return student;(3) 對一的關系身份證和人的關系不就是一對一嗎? packag

42、e cn itcast dao;import org. apache.conimons. dbutils. QueiyRumier;import org apache, conunons. dbutils handlers. BeaiiHandler;import cn.itcast.dbutils.JDBCUtils;import cn.itcast.domam Card;import cn. itcast. domam Person;public class PersonDAO /*增加一個人,同時増加一個身份證號碼 param person/public void addPerson(P

43、ei-son person) tryQueryRminer 11m = new QueryrRumier( JDB CUt 1 Is getDaraSourc);Stnng sqll = "insert into person values(?,?)M;Object paiains = persoiLgetId():person.getName(); nin.updateCsqll, params);Card card = person.getCard();Stnng sql2 = "insert into card values(?,?)M,Objectf params2

44、 = card getIdO,card.getCard_idO; run update(sql2, params2); catch(Exception e)throw new RuntuneException(e.getMessage(),e);/*查詢一個人,同時査詢這個人的身份證號碼/public Person findPerson(int id)Person person = null,try QueryRunner ninner = new QueryRimner(JDBCUtils.gwzU7/N5切 “(); Stnng sql = "select * from pers

45、on where id = ?M;person = (Person) runner.QueFy(scil, id: new BeanHandlei(Persoii«l>w):String sql2 = "select from card where person_id = ?”;Card card = (Card) runner.<ftieF¥(sql2, kL newBeanHaiidleifCardclass);person setCard(card); cateh (Exception e) throw new RuntHiieException

46、(e.getMessage(),e);return person;注意事項:不管的對象存在何種關系,反映到關系型數據庫中,都是使用外鍵表示紀錄(即對象) 的關聯關系。設計4"對象如涉及到多個對象相互引用,要盡量避免使用一對多,或多對多關系,而應 使用多對一描述對象之間的關系(或使用延遲加載的方式人三.Oracle中大數據的處理注意:面試題.如何在Oracle數據庫中保存圖片(二進制數據)?Oracle定義了一個BLOB字段用于保存二進制數據,但這個字段并不能存放真正的二進制 數據,只能向這個字段存一個指針,然后把數據放到指針所指向的Oracle的LOB段中, LOB段是在數據庫內部表

47、的一部分。因而在操作O“cle的Blob之前,必須獲得指針(定位器才能進行Blob數據的讀取和寫 入.如何獲得表中的Blob指針呢?可以先使用insert語句向表中插入一個空的blob (調用 orade的函數empty blobO )»這將創建一個blob的指針,然后再把這個empty的blob 的指針查詢出來,這樣就可得到BLOB對象,從而讀寫blob數據了。1、插入空blobinsert into test(id4nuige) values(?>empty_blobO);2、獲得 blob 的 cursorselect image from test where ld=

48、? for update;Blob b = rs.getBlob( "image");注意:須加for update,鎖定該行,直至該行被修改完畢,保證不產生并發沖突。3、利用io,和獲取到的cursoi往數據庫讀寫數據注意:以上操作需開啟事務.package cn.itcast.oracle;import java.io File;import j a va. io. F llelnputS tream,import j a va. io. F lleOutputS tream;import j ava.io IiiputStream;import j ava io Outputstream;Import j ava. sql. Connection;import j ava. sql Dn verN lanager;import j ava. sql PreparedStatement;import j ava .sql Result Set;impert java.sql.Statement;import org.junit.Test;Impert oracle.sql BLOB;public class TestOracleBLOB 將圖片存入Oracle數據庫 Testpublic void

溫馨提示

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

評論

0/150

提交評論