# 0512 Hibernate 物件導向就是用別人寫好的代碼 用new 跟.來呼叫 分工、寫一次重複利用概念->dao/service 能提早下班,不用加班。 現在老闆一次派多個專案給工程師, 所以偶爾要加班 病毒越寫越小,感染速度快,又高你就出名了->windows,效率是2的N次方倍 grandle/maven都是透過網路,demo那天沒網路就無法報告了 所以最好都準備,包含錄影檔/雲端+本機 ![](https://hackmd.io/_uploads/SyiGbms4h.png) --- ### nvarchar varchar差別 2byte 1byte來儲存 --- Alt +F5 強制更新 pom.xml 資料夾和package name通常都小寫開頭 hbm跟bean綁 ,之後都用@annotation cfg設定檔 之後 --- ### Hibernate雲端講義 https://1drv.ms/f/s!Ans47I9-Pkiv9TEYxd8FIGHtlYq- --- ![](https://hackmd.io/_uploads/S1PuEPh4h.png) - 先在eclipse 上encoding設定成UTF-8 - windows/preferences/web/ - HTML - CSS - JSP --- ### MAVEN 設定 1. 去Maven的conf資料夾中找到settings檔,並加入這行 ![](https://hackmd.io/_uploads/HkbPNvnN2.png) ==開始在Eclipse更改== ![](https://hackmd.io/_uploads/rJjKNv3N3.png) ==Installation== ![](https://hackmd.io/_uploads/SygpEDn4n.png) ==User Settings== ![](https://hackmd.io/_uploads/SyIpVDnV3.png) ![](https://hackmd.io/_uploads/ryg0Vwh4h.png) ![](https://hackmd.io/_uploads/BysANP2E2.png) ### 如果localrepository 設錯要更改的處理方式 1. 在setting.xml裡的localrepository標籤內先更改路徑 2. 去把global setting 裡的library刪除,有兩種方式 - 第一種是,刪除下圖的jar檔 ![](https://hackmd.io/_uploads/HyUcxbwB3.png) - 第二種是,刪除下圖資料夾內的jar檔 ![](https://hackmd.io/_uploads/ryp1--vS2.png) 3. 最後再去user setting在設定一次路徑,就完成了 --- ### Tomcat server container ![](https://hackmd.io/_uploads/HymkBw2Vh.png) ![](https://hackmd.io/_uploads/Hk9xrP342.png) --- ### new Java Project ![](https://hackmd.io/_uploads/H1xtHDhVn.png) ![](https://hackmd.io/_uploads/rylyIP34n.png) --- ### 轉換成maven project ![](https://hackmd.io/_uploads/ry7FUv2V2.png) ![](https://hackmd.io/_uploads/S1KFLvhE3.png) ![](https://hackmd.io/_uploads/rkXoIDnNh.png) --- ## 工具箱設定可以從遠端連線 SQL Server2022設定管理員 ![](https://hackmd.io/_uploads/SkEZuHOBh.png) - 通常不建議用sa - watcher - P@ssw0rd - @和數字0 ![](https://hackmd.io/_uploads/ryRaUvnVh.png) 通常不會設定這麼高權限 ![](https://hackmd.io/_uploads/rkzlPvhEh.png) ![](https://hackmd.io/_uploads/HyUxDPnV3.png) ![](https://hackmd.io/_uploads/S15xvD34h.png) --- ### maven dependency [hibernate-core ](https://mvnrepository.com/artifact/org.hibernate/hibernate-core) [Microsoft JDBC Driver For SQL Server](https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc) 貼完dependency儲存之後,可以按Alt +F5 強制更新 mac 是fn+option +f5 ![](https://hackmd.io/_uploads/HJeTDw3Nn.png) --- - final +在屬性前 只能給值一次 - 習慣用法 屬性第一個字不會用大寫,要用小寫。 - 不然getter/setter會找不到,會出錯。 - 也不要用底線_ ==下面這張圖是錯誤示範== ![](https://hackmd.io/_uploads/rkUzdv343.png) >避免找bug,可以節省30%時間 --- P.38 給native 決定型別,他又不會實際上自己決定型別,所以不推薦用native --- @column 如果欄位跟屬性名字一樣就不需要寫 欄位名稱一樣不是可以不打 ![](https://hackmd.io/_uploads/r1DWFPn43.png) ![](https://hackmd.io/_uploads/Sk3CODnEn.png) ![](https://hackmd.io/_uploads/rkBJYv3E2.png) --- ![](https://hackmd.io/_uploads/B1AgKv2V2.png) --- ![](https://hackmd.io/_uploads/H1K4KD2Vn.png) --- ### Thread-Safe Thread-Safe,動作沒執行完,其他執行緒要等待執行,所以很佔資源 訂票不能Thread-Safe ,因為多人可以同時搶同一張票 --- ### Singleton 單一物件設計模板 ``` static 靜態代表載入記憶體時只會初始化一次 private static final private不能直接存取 final只能給值一次 ``` - 只會產生一個SessionFactory物件,保證整個應用程式只會使用到同一個SessionFactory物件 - 有static 在其他類(像是main方法實際執行時)可以不用new 一個物件就能呼叫來使用 --- ### 資料庫隔離種類 1. 最嚴格程度: 排隊等的人,但看不到裡面情況,什麼動作都不能做,只有裡面的人才能操作。 2. 排隊的人看的到裡面,但只能查詢(唯讀),裡面的人才能新增修改刪除。 3. 先搶先贏,最鬆散,項演唱會搶票 --- ### SessionFactory: 1.openSession(): * 一個thread 可以開多個連線,一個連線可以開多個交易 * 要自己產生物件和關閉連線 2.getCurrentSession(): * 一個thread 可以開一個連線,一個連線可以開一個交易 * 不用自己產生物件和關閉連線 * 要在cfg.xml 設定與thread結合 ```java= <property name="hibernate.current_session_context_class">thread</property> ``` * getCurrentSession(): 遇到commit 或rollback就會自動close() --- update ->merge delete - >remove 來取代 ![](https://hackmd.io/_uploads/B1N-cw3Vn.png) --- model2: javaBean, dao,service --- 不同權限存取等級,用朋友來比喻不同等級能在你家做什麼事情: 1. 閨密等級: default, protected 2. 好朋友: 3. 普通朋友: 4. 陌生人: --- 跟資料庫存取 ,要確保在persistent階段 --- GC: java利用preference(C++的pointer)來配置記憶體,系統會自動GC回收物件的記憶體 --- 註冊時要你填緊急聯絡人或其他親朋好友,覺得不可以出賣朋友,所以會自發性的停止註冊。 ajax技術,你每填完一行欄位,系統就會送資料到後端去儲存,所以你沒送出表單,也會記錄你的資訊。 --- view顯示畫面之前不可以關連線, fliter 控管哪時候開關連線,開關交易。 可以避免lazy Initialization。 --- delete -> remove remove 會移除一個persistence物件,要有ID才能刪除 load跟get都是查詢ID load ->get 兩者都是用ID去搜尋 ID外查詢用createQuery方式(String queryString, 指定回傳的bean型態) update -> merge 來取代 ![](https://hackmd.io/_uploads/B1-o1lWrn.png) 設定檔除了加入那行之外,update, delete還要搭配flush ![](https://hackmd.io/_uploads/H17h1eZH2.png) --- 通常看錯誤訊息是從上面往下面看(try),console的第三個訊息 ![](https://hackmd.io/_uploads/Hkva1l-rh.png) --- ``` List<Bean> ``` List 按順序儲存,允許重複 Set 按他自己順序,不允許重複。 >Linked HashSet 按資料表順序儲存 ,按順序又不允許重複 HashSet 別名樂透彩券 >LinkedLiset Set / ArrayList 差別 Array.sort 陣列排序 comparable ,然後 減號 就能排序 --- ![](https://hackmd.io/_uploads/B1ZWex-Bn.png) ![](https://hackmd.io/_uploads/ByCMgxWS2.png) --- merge 找的到物件就幫你更新,找不到就幫你新增 DAO : 先做一個框(介面), 再透過class實作介面來實現功能 --- HQL是能使用ID之外的自定義方法,最後一章 createQuery(hql) 說你想要顯示的結果,還有你發生的錯誤,你目前是怎麼做的。 請問老師要怎麼更改才能得到我要的結果? --- 在Web應用程式中,可以藉助Filter來進行Session管理,在需要的時候開啟Session,並在Request結束之後關閉Session --- session.beginTransaction(); HouseBeanDao hDao = new HouseBeanDao(session); 通過建構子把資料型態Session傳進dao裡面來建立連線。 預設數值是null 去呼叫裡面的get甚麼都是null 所以我們從外部帶什麼鬼近來 才能確定連線是同一個 一個連線負責一個交易 單一執行緒 --- service: 經紀人、助理幫你把雜事(介面)都做好,透過service(操作介面、聯絡窗口)去呼叫dao,避免直接存取造成明星困擾(緩衝區),拉高明星dao層次,間接找明星 --- DTO就是bean Service 就是大一點的DAO, dao放基本CRUD操作方法 service能結合單獨的CRUD方法,比方說R+C+R --- 關聯: 我的PK就是你的FK 中介table 處理多對多,利用兩個一對多的表來關聯 ![](https://hackmd.io/_uploads/rksZMxWHh.png) 為啥在資料庫有identity?再java還要有? 暫時結論就是資料庫有identity , 沒+這行會報錯 @GeneratedValue(strategy = GenerationType.IDENTITY) ![](https://hackmd.io/_uploads/HJrzzg-Hh.png) 剛好是PK 不然是只有寫joincolumn @PrimaryKeyJoinColumn 這行 噩夢阿,要一直關聯 一個表跟兩個表有一對多關聯,action時候就要各set2次=總共set4次 --- ![](https://hackmd.io/_uploads/BJMdGeWHn.png) New 會產生實例,所以不能在迴圈外new bean ,否則只會把最後一筆資料指向的記憶體位置加到list裡面 Bean先宣告成null; while(rs.next) 迴圈裡面才建立bean 物件 bean= new Bean(); 才能把每一筆資料都加到list裡面 >先設成null有兩種解讀,第一種是空值,之後裝東西進來。第二種是之後再new 物件,建立記憶體位置。 --- = 就表示把右邊的值賦值到左邊的變數(setter的概念) 等號右邊去get,set到左邊的變數上 --- GetInsert那裡的錯誤處理,例子 原本main方法的try裡面正確的都會執行,每次呼叫方法時候都跳去執行方法裡的內容 第一個查ID沒問題,但是要印出時,中間夾了一行錯誤的dao方法,GetInsert 因為沒有填入要執行的參數,所以發生錯誤, 方法內只執行到stmt.executeQuery()這行,以下都跳過不執行, 因為throw,所以回到main同一行,發生錯誤, 所以GetInsert以下的程式都跳過不執行,直接跳到catch印出索引集目前沒有資料, 所以原本下一行的查單筆ID才印不出來,因為發生錯誤,以下的程式都會跳過 --- ## for-each 迴圈 當我們想要存取一個陣列或集合裡面的元素時,for-each迴圈是個簡單且有效率的方法 for-each迴圈的格式如下: for(元素型態 迴圈控制變數 : 集合或陣列名稱)    //迴圈主體; for-each有幾項注意要點 1.只能從頭開始走訪每個元素,不能從集合或陣列的尾端向前走訪 2.只能取出集合或陣列裡的元素不能置換 3.foe-each迴圈裡面的變數是區域變數 4.只適用於Java5.0 以後的版本 ``` public class HelloDate { public static void main(String args[]) { int arr[]={5,3,8}; //傳統for迴圈 for(int i=0;i<arr.length;i++){ System.out.print(arr[i]+" "); } System.out.println(); //for-each loop for(int i:arr){ System.out.print(i+" "); } } } ``` --- 設置@reverse 會員刪除,但已付費的訂單資料會保留 目標是刪除資料,讓使用者看不到資料,但實際上資料還存在資料庫上 --- ![](https://hackmd.io/_uploads/r1otvTZSn.png) HashSet有預設初始大小16,彈性縮放 lazy延遲初始,節省記憶體 mappedby 對應關係,cascade 我做什麼對方就跟著做什麼 ![](https://hackmd.io/_uploads/r1Niw6Zr2.png) @GeneratedValue(strategy = GenerationType.IDENTITY) 只要資料庫有idrntity一定要加這行 值是由資料庫產生的 ![](https://hackmd.io/_uploads/ry_3wpWB3.png) ![](https://hackmd.io/_uploads/r1JaPpbB3.png) 1. - 在主表Book class內 的bookDetail(要關聯屬性的屬性)上標示一個關聯關係的annotation - mappedby屬性設置為主表的java屬性,對應到副表關係關係annotation 下的java屬性book - 因為是透過PK來join column,所以會多這 一行 @GenericGenerator(name="generator", strategy = "foreign", parameters = @Parameter(name="property",value = "book")) - mappedBy 要多對應屬性值book 2. - 如果是一般欄位來join column,就只要注意兩個地方, - mappedBy 要對應到副表java屬性book - 通常也會對應到主表的class =table name - 通常主表table name 也跟著一起被對應到,也會是小寫的 --- @GenericGenerator(name="generator", strategy = "foreign", parameters = @Parameter(name="property",value = "book")) 這個值是由book給的 不是由資料庫產生 由book給值是什麼意思? book class嗎?還是 book table? --- ![](https://hackmd.io/_uploads/SJeX51mS2.png) ![](https://hackmd.io/_uploads/r1Hv5JmBh.png) ![](https://hackmd.io/_uploads/rJdQq17rh.png) 要印東西就要寫else --- ![](https://hackmd.io/_uploads/SkcN9y7B3.png) 就不用打完完整的句子,直接打ID ![](https://hackmd.io/_uploads/rJZucymr3.png) HQL語句是"from Game",它表示從Game實體類別中選擇所有物件。 Game.class參數指定了查詢的結果類型為Game類別。 - 左邊是bean的名稱,右邊是回傳的類型 --- ### 建立hibernate web 專案 ![](https://hackmd.io/_uploads/rkJTckmBh.png) ![](https://hackmd.io/_uploads/HJTwiyQS3.png) 記得勾起來 --- pom.xml放置jar檔用的(maven幫你從網路上下載) --- ![](https://hackmd.io/_uploads/BJKyjkmH2.png) ![](https://hackmd.io/_uploads/H1bxoyQHh.png) 之後可以改成自己的database name p.181可以不寫 ![](https://hackmd.io/_uploads/HySKRkXr3.png) 182頁的XXX對應180頁的 name ![](https://hackmd.io/_uploads/H1wc0y7r3.png) ![](https://hackmd.io/_uploads/Hy69C1mB2.png) @WebFilter("/*") 記得加 --- FetchType.LAZY只在用到時才載入關聯的物件。 意思就是查詢時並不立刻將stockTransactions物件載入記憶體,透過呼叫stockTransactions.get() getter 方法時候才會存取 ```<StockTransaction>```物件的方法時,才會載入記憶體 service: 經紀人、助理幫你把雜事(介面)都做好,透過service(操作介面、聯絡窗口)去呼叫dao,避免直接存取造成明星困擾(緩衝區),拉高明星dao層次,間接找明星