SSH框架

一、使用hibernate進行更新操做時,首先調用了findById方法獲取要修改的對象,此時session沒有被關閉,接着從新建立一個對象,將要修改的屬性值賦值給這個對象。調用修改方法拋出以下異常:html

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

緣由:在session緩存中已經存在一個與當前傳遞進來的修改對象具備相同標識符(主鍵)的對象。Hibernate的機制是隻能存在一個具備惟一標示的對象,不然增刪改就會出錯。java

解決辦法:sql

:在使用過濾器/攔截器時,每次開啓session,操做後就關閉session。數據庫

session.evict(Object object),從緩存中清除指定的對象。json

ƒsession.clear(),是將session緩存中的對象所有清除,殺傷面太大了,不建議使用。緩存

 

二、HibernateSessionFactory類中有一個線程ThreadLocal類的對象,它用來分配session對象,經測試後發現,由它每回獲取的session都不一樣,有時爲空,有時能夠獲得以前存進去的session對象。session

 

三、若是使用struts+hibernate框架實現數據庫的增刪改,使用過濾器去開啓和提交事務時,有時增刪改會沒有效果,由於action沒有被過濾器過濾,這個使我困惑了好久,由於以前的項目均可以被過濾到,後面我想用攔截器攔截action,在攔截器中開啓和提交事務,試驗以後發現此法可行。框架

 

四、使用hibernate+struts框架開發項目時,系統拋出以下異常:異步

Exceptionjsp

java.lang.reflect.InvocationTargetException

root Cause:

java.lang.NoSuchMethodError: antlr. Collections.AST.getLine()I

 

緣由:因爲我用的是MyEclipse自動生成的struts和hibernate類庫,hibernate中有個antlr-2.7.7.jar,而struts中有個antlr-2.7.2.jar。異常的緣由就是說沒有找到antlr.Collections.AST類中的getLine()方法,高版本的jar中有getLine()方法,而低版本中沒有getLine()方法,系統默認使用的是低版本的jar包。

解決辦法:去除struts類庫中的antlr.jar包便可,還須要清理並構建這個項目,由於有的項目的配置信息一時更改不過來。

 

五、Struts的類型轉換器用於將String類型轉化爲指定的數據類型,還能夠將指定的數據類型轉化爲String類型。開發項目時很方便。

實現方法:

:新建一個類繼承StrutsTypeConverter類,實現其中的兩個抽象方法,做爲轉換器類。

‚:新建局部屬性文件或者全局屬性文件

 

 

局部屬性文件:放置在相關action類同級目錄下,文件名格式:action類名-conversion.properties

裏面存放鍵值對,如:hobbies=util.ListConverter

hobbies就是要轉化的屬性名,util.ListConverter就是轉換器類的徹底限定名。

全局屬性文件:放置在src目錄下,文件名格式:xwork-conversion.properties

裏面存放鍵值對,如:java.util.Date=util.DateConverter

java.util.Date就是要轉化的數據類型,util.DateConverter

就是轉換器類的徹底限定名。

注意:若是咱們使用<s:property/>標籤,那麼它會調用轉換其中的convertToString(),若是使用EL表達式,那麼就不會調用該方法了。

 

六、針對類型轉換出錯的處理--在頁面上顯示友好提示:

類型轉換出錯時,要拋出一個運行時異常,程序會根據創建的屬性文件,顯示錯誤提示。

實現方法:

:新建局部屬性文件或者全局屬性文件

局部屬性文件:放置在相關action類同級目錄下,文件名格式:action類名.properties

裏面存放鍵值對,如:invalid.fieldvalue.time=mistake

invalid.fieldvalue.time就是出錯的字段名,mistake是錯誤提示信息。

全局屬性文件:放置在src目錄下,文件名格式:message.properties,屬性文件的名稱不做要求。

還要在struts.xml中配置一個常量:

<constant name="struts.custom.i18n.resources" value="message"/>

屬性文件中存放鍵值對,如:xwork.default.invalid.fieldvalue=fieldname is {0} is error

這是固定的格式,{0}表明錯誤的字段名,系統會自動賦值。

fieldname is {0} is error 即是提示信息。

 

七、Struts框架有相似於html的標籤,可是它有必定的格式,

可是咱們能夠在struts.xml中配置一個常量,去掉它的格式。

     <constant name="struts.ui.theme" value="simple"/>

 

八、當咱們顯示錯誤信息的時候,會發現錯誤信息會以列表的形式顯示,這樣就不美觀了,達不到咱們想要的標準。因此咱們能夠用另外的方式輸出錯誤信息。

例如我如今增長了兩個錯誤信息:

this.addFieldError("username","用戶名太長!");

this.addFieldError("username","2222!");

那麼我就可使用如下四種方法輸出錯誤信息:

    <s:property value="errors.username[0]"/>  

   ‚ <s:property value="fieldErrors.username[0]"/> 

   ƒ ${errors["username"][0] }

   4 ${fieldErrors["username"][0] }

原理:在值棧中有fieldErrorserrors兩個對象,這兩個對象中存儲着錯誤信息,利用<s:debug/>能夠觀察到,這兩個對象其實就是map數據類型的。

獲取map數據的方法

 

 

 

九、Struts上傳文件

jsp部分:

 

 

struts.xml部分:

 

 

action部分:

 

 

 

注意:

文件對象名就是表單文件控件的name

文件類型的命名=文件對象名+FileContentType

文件名稱的命名=文件對象名+FileName

 

十、struts下載文件

jsp部分:

 

 

struts.xml部分:

 

 

action部分:

 

 

 

十一、兩級聯動

演示:

 

 

 

 

 

 

 

原理:

將數據庫中的數據封裝成對象,而後將對象轉化爲json數據,在客戶端用異步獲取後臺的json數據便可。

客戶端jsp頁面:

 

 

 

 

 

 

 

後臺:

 

 

 

 

注意:在js中若是某個元素還未被加載,那麼只能夠得到該元素的引用,不能對該元素進行綁定事件。

 

1三、struts框架中使用json

客戶端:

 

 

 

Struts.xml:

 

 

UserAction:

 

 

注意struts類庫裏面沒有提供ezmorph-1.0.6.jar文件,因此要手動添加。

 

1四、hibernate中的cascade屬性

Cascade屬性是存在於set標籤中,用來作級聯刪除和保存。

它的值有如下幾種:

默認值是none,不作級聯動做;

save-update:級聯保存

delete:級聯刪除

all:級聯保存和刪除

 

注意:屬性名稱和屬性值都嚴格需分大小寫

 

1五、hibernate中的inverse屬性

修改街道對應的區道信息:

 

 

修改後會發現程序執行了兩次修改操做:

 

 

緣由:

區道與街道是一對多的關係;

因爲Hibernate是雙向維護外鍵,因此當修改區道中的街道時,會修改一次外鍵;在修改街道中的區道時,又會修改一次外鍵。

這樣就會產生效率慢的問題,由於若是執行兩次修改,那麼第二次是無用的操做。利用inverse屬性能夠解決這一問題。

 

在區道表的映射文件裏面的set標籤中設置inverse屬性爲true;

inverse的屬性值以下:

默認值爲false,表示我方不放棄維護外鍵的權利

true,表示我方放棄維護外鍵的權利

 

 

 

一個國家有一個主席,國家有不少人,主席不可能認識國家的全部人,可是國家全部人能夠認識主席。

 

1六、延遲加載

延遲加載分爲類級別延遲和關聯級別延遲。

類級別延遲:

使用load(),例如:

 

 

只有當使用這個對象時纔會進行查詢,如輸出str和str.getName()時就會執行查詢語句,可是str.getId()並不會進行查詢。

關聯級別延遲:

使用set標籤中的lazy屬性,lazy的屬性值有true(默認值)、false、extra(極其懶惰,要什麼才查什麼);

懶加載的意思就是當你使用到對象中的關聯對象時,才執行查詢操做。

如當lazy=」true」時,當你使用set時才執行查詢操做。

如當lazy=」false」時,當你獲取District對象時,同時會查出全部的Street。

如當lazy=」extra」時,用什麼查什麼。

如我要查詢set.size(),系統會執行一下的查詢語句:

 

 

 

1七、fetch屬性

fetch的屬性值有select(默認值)、join、subselect

fetch=」select」時,程序會先查詢返回要查詢的主體對象,而後根據lazy屬性看是否懶加載。

fetch=」join」時,程序會將主體對象和關聯對象用一句鏈接查詢的sql同時查詢出來,這樣以來,懶加載就無用武之地了。

subselect和select同樣,不會一開始就將關聯對象查出來。

subselect與select的區別:

 

 

設置不執行懶加載;

select是根據關聯外鍵的id,每個對象發一個select查詢,獲取關聯的對象。

執行的sql以下所示:

 

 

 

subselect是發送兩條sql語句,一條是查詢主體對象,而另外一條是抓取在前面查詢到的全部實體對象的關聯集合。

執行的sql以下所示:

 

 

 

1八、批量抓取

批量抓取的使用場景是查詢出來一個集合,而後又查詢每一個集合對象中的集合。使用set標籤中的batch-size屬性實現。

 

數據庫中只有5個區道信息;

設置batch-size=」5」,執行的查詢語句以下:

 

 

 

 

 

 

 

 

而設置batch-size=」7xxx」,執行的查詢語句以下:

 

 

因爲發送sql數據的次數多少,因此batch-size的數值越大,效率就越高。

batch-size爲4時,首先會有4個?號,接着一個查詢語句會有1個?號。

 

1九、QBC查詢

格式:

 

 

 

qbc的統計查詢得使用projection實現,有兩種方式:

(1)

 

 

(2)

 

 

 

查看文檔發現ProjectionList和Projection的關係以下所示:

 

 

 

 

 

可使用groupProperty投影對結果集進行分組(使用SQL的GROUP BY子句),當你經過某個屬性分組時,程序就會查詢出該屬性所對應的列名。

可使用Property.forName()來表示投影,就是查詢指定的字段。

建立別名有三種方式:

 

 

 

20、離線查詢:

 

 

離線查詢使用DetachedCriteria對象設置限制條件,而後再經過session獲取Criteria對象。

離線查詢的使用場景:例如Biz類和Dao類,在Dao類中利用session操做CRUD,若是你想在Biz中設置限定條件,若是不使用離線查詢,那麼勢必得獲取Criteria對象,如此一來又得獲取session,有點麻煩。

可是使用離線查詢的話,能夠直接獲取DetachedCriteria對象設置限定條件,而後再將這個對象傳遞到Dao中便可。

 

 

 

概念:

投影就是指部分字段,例如我只查詢學生表中的姓名,這就叫投影。

CRUD是指在作計算處理時的增長(Create)、讀取查詢(Retrieve)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫。

相關文章
相關標籤/搜索