从一个hibernate配置文件中了解到的东西
2019獨角獸企業重金招聘Python工程師標準>>>
業務場景:
????? 先展示一份hibernate配置文件,然后來詳細說里面蘊含的東西。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="cn.com.besttone.report.domain.ReportCompOrderDetail" table="REPORT_COMP_ORDER_DETAIL"dynamic-update="true" dynamic-insert="true" optimistic-lock="version" schema="BESTTONETICKET"><cache usage="nonstrict-read-write" /><id name="id" unsaved-value="null" type="java.lang.Long" column="ID" length="19"><generator class="sequence" ><param name="sequence">SEQ_REPORT_COMP_ORDER_DETAIL</param></generator></id><property name="statusFlag" type="java.lang.String" column="STATUS_FLAG" /><property name="checkAccountStatus" type="java.lang.String" column="CHECK_ACC_STATUS" /><property name="checkAccountDate" type="java.util.Date" column="CHECK_ACC_DATE" /><property name="spWriteBackStatus" type="java.lang.String" column="SP_WRITE_BACK_STATUS" /><property name="dataSource" type="java.lang.String" column="DATA_SOURCE" /><property name="cpId" type="java.lang.Long" column="CPID" /><property name="cardType" type="java.lang.String" column="CARD_TYPE" /><property name="insuranceProvideCode" type="java.lang.String" column="INSURE_PROVIDER_CODE" /></class> </hibernate-mapping>在這里主要分析xml里面配置的屬性,我們用的是oracle數據庫
schema:oracle的schema定義:A schema is a collection of database objects (used by a user.)。就是一個數據庫對象的集合,包括了tables, views, sequences, stored procedures, synonyms, indexes, clusters, and database links。一個用戶一般對應一個schema,該用戶的schema名等于用戶名,并作為該用戶缺省schema。比如我們在訪問數據庫時,訪問scott用戶下的emp表,通過select * from emp; 其實,這sql語句的完整寫法為select * from scott.emp。所以相對而言,我們在hibernate查詢數據的時候,可以配置schema,也可以不進行配置,因為schema,默認為用戶名。
dynamic-update="true" dynamic-insert="true" :因為在hibernate幫我我們生成實際的sql語句的時候,當屬性為null,他也會生成對應的sql,如果我們配置了這兩個屬性,就可以只生成不為null的屬性值,對應的有更新,和插入。
例:update HBTEST set VAL1=?,VAL2=? where ID=?
同樣的操作如果把設置為true的話,sql語句只包含更新的字段:update HBTEST set VAL1=? where ID=?
optimistic-lock
悲觀鎖:通常是由數據庫機制實現的,在整個過程中把數據鎖住(查詢時),只要事務不釋放(提交或回滾),任何用戶都不能查看和修改。
當有一個方法通過悲觀鎖機制加載某個對象的時候,對這個對象進行了一系列的操作,在進行操作的時候,也就是只要事務未提交,這個鎖就一直存在。當另外一個方法加載這個對象的時候(兩個對象是一個對象,即唯一標示符的值是相同的)只會發出查詢語句,停止不動,因為,前一個方法使用了悲觀鎖機制加載的這個對象,并沒有結束事務(提交或回滾),因此這時是排他的。當第一個方法提交了事務,第二個方法才可以加載成功并按照自己的意愿執行其所有操作。
悲觀鎖的使用:悲觀鎖解決了更新丟失( lost update )問題,但是也帶來了并發問題 à 并發不好
樂觀鎖:
觀鎖其實不是一種鎖,也就不是鎖住的問題,而是給數據庫表加入了一個字段(可以使版本號( version ),也可以使一個時間戳( timestamp )),或是進行全部字段 / 臟數據字段比較(這種方式適合于以前遺留下來的系統,在不更改原來表結構的時候使用這種策略)來確定數據是否被修改過,一般的應用是采用數據版本的方式( version )實現,在讀取數據的時候將 version 讀取出來,在保存數據的時候判斷 version 的值是否小于數據庫中的 version 的值,小于則不允許更新,否則可以更新。
使用 version 實現樂觀鎖(推薦使用):在一個事務提交后就會更改數據庫,數據庫中 version 的值會自動加 1 。實現步驟 à 1 、在持久化類中加入 version 屬性,生成其 getter 和 setter 方法。 2 、在配置文件中的 <class> 標簽中配置一個屬性 optimistic-lock=”version” (這個屬性的默認值就是 version ,可以不進行配置,但建議配置上) 3 、對 version 字段進行映射,使用 version 標簽(這個字段的映射必須在 id 標簽的后面第一位) à <version? name=”version”/>
細節分析 à 在一個事務加載某個持久化類時,對這個對象進行了一系列操作,但是還沒有提交事務,于此同時,另外一個事物也加載了這個持久化類,并完成了一系列的操作后提交了事務,然后,第一個事務這時也要提交事務了,這樣就會拋出一個異常 à org.hibernate.StableObjectStateException:Rows was updated or deleted by another transaction… ,原因是這樣的:當一個事務提交時會發出這樣一條 SQL 語句 à update 表名 set 所有表屬性 =? where id( 唯一標示符值 )=? andversion=? 這個語句中 version=? 是最關鍵的。以上說的那個例子中,第一個事務拿的是自己的舊的 version 值,進行更更新,而第二個事務在提交后,已經改變了 version ,變成了新的 version 值了,這樣第一個事務提交事務時發出的 update 表名 set 所有表屬性 =? where id( 唯一標示符值 ) =? and version=? 這條語句將會失敗!就會拋出以上異常信息。
樂觀鎖:適合于高并發。
轉載于:https://my.oschina.net/u/731676/blog/268403
總結
以上是生活随笔為你收集整理的从一个hibernate配置文件中了解到的东西的全部內容,希望文章能夠幫你解決所遇到的問題。