国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

Kodo EJB:實現(xiàn)類和類之間的關(guān)聯(lián)關(guān)系

2024-07-21 02:14:46
字體:
供稿:網(wǎng)友

  對象和對象之間除了繼承關(guān)系之外,還存在著關(guān)聯(lián)關(guān)系:包括分作一對一、一對多、多對一和多對多,由于這幾種關(guān)系在kodo ejb中的實現(xiàn)原理基本類似,因此本文中主要就一對一類關(guān)聯(lián)關(guān)系進行深入的講述,同時通過簡單例子的分析和實踐詳細的說明如何使用kodo ejb中提供的注釋來定義類和類之間的關(guān)聯(lián)關(guān)系,剩下的一對多、多對一和多對多三種關(guān)系將只在文章最后進行說明,請讀者參考一對一關(guān)系的實現(xiàn)過程。

  面向?qū)ο蟮氖澜缋铮恆和類b之間的一對一關(guān)系必須滿足如下條件:

  1. 對象a1引用了對象b1

  2. 類a其他對象an不可能應(yīng)用同樣的對象b1

  在關(guān)系數(shù)據(jù)庫中,我們通常使用唯一外鍵的方式來實現(xiàn)一對一關(guān)系,下面這個圖說明了這種的情況。



  下面開始介紹一下kodo ejb中和一對一關(guān)系實現(xiàn)相關(guān)的知識,為了說明的需要,我們首先定義一個虛擬的場景。

  模擬場景

  我們假定要完成一個圖書館管理系統(tǒng),該系統(tǒng)中需要管理很多書,我們需要記錄書的基本信息如編號、書名、出版日期等基本信息,還需要記錄書的前言,序等信息。

  假設(shè)我們根據(jù)上面的需求,將書設(shè)計成一個類(book),包括了書的編號和名稱兩個屬性,同時將書的前言信息設(shè)計成另外一個類(bookextend),它包括了書的編號和前言信息兩個屬性。由于一本書有前言而且也不可能有其他的書前言部分會和他一樣,所以類book和bookextend之間很自然的形成了一對一的關(guān)系。這兩個類的屬性以及類之間的關(guān)系如下圖所示。



  [注]

  1、為了說明的簡單,例子設(shè)計時每個對象僅僅選擇了必要的屬性。

  2、上面的設(shè)計僅僅為了演示的要求而特意采用,不代表設(shè)計合理。

  kodo ejb中和一對一關(guān)系實現(xiàn)相關(guān)的內(nèi)容

  在kodo ejb中,我們可以使用簡單的onetoone注釋來聲明類和類之間的一對一關(guān)系,另外可選的,我們可以使用joincolumn注釋來聲明兩個類對應(yīng)的表之間使用什么字段來進行關(guān)聯(lián)。

  onetoone

  onetoone注釋提供了5個屬性供開發(fā)者定義類和類之間一對一關(guān)系的細節(jié)內(nèi)容。

  1. targetentity

    class類型的屬性。

    定義關(guān)系類的類型,默認是該成員屬性對應(yīng)的類類型,所以通常不需要提供定義。

  2. mappedby

    string類型的屬性。

    定義類之間的雙向關(guān)系。如果類之間是單向關(guān)系,不需要提供定義,如果類和類之間形成雙向關(guān)系,我們就需要使用這個屬性進行定義,否則可能引起數(shù)據(jù)一致性的問題。比如上面的演示場景中,我們只是定義book類有bookextend屬性,而bookextend并沒有book屬性,那么他們是單向關(guān)系,如何bookextend中也定義了book屬性,那么book和bookextend之間就構(gòu)成了雙向關(guān)系。

  3. cascade

    cascadetype[]類型。

    該屬性定義類和類之間的級聯(lián)關(guān)系。定義的級聯(lián)關(guān)系將被容器視為對當(dāng)前類對象及其關(guān)聯(lián)類對象采取相同的操作,而且這種關(guān)系是遞歸調(diào)用的。舉個例子:book和bookextend有級聯(lián)關(guān)系,那么刪除book時將同時刪除它所對應(yīng)的bookextend對象。而如果bookextend還和其他的對象之間有級聯(lián)關(guān)系,那么這樣的操作會一直遞歸執(zhí)行下去。

    cascade的值只能從cascadetype.persist(級聯(lián)新建)、cascadetype.remove(級聯(lián)刪除)、cascadetype.refresh(級聯(lián)刷新)、cascadetype.merge(級聯(lián)更新)中選擇一個或多個。還有一個選擇是使用cascadetype.all,表示選擇全部四項。

  4. fatch

    fetchtype類型的屬性。

    可選擇項包括:fetchtype.eager和fetchtype.lazy。前者表示關(guān)系類在主類加載的時候同時加載,后者表示關(guān)系類在被訪問時才加載。默認值是fetchtype.eager。

  5. optional

    boolean類型的屬性。

    定義該關(guān)聯(lián)類對是否必須存在。如果設(shè)置為false,那么該屬性就不能設(shè)置為null。默認值是true。

  onetoone用法舉例

public class book{ // 其他內(nèi)容… @onetoone(optional=true,cascade=cascadetype.all) public bookextend bookextend; } 

  joincolumn

  joincolumn注釋用于定義主類在數(shù)據(jù)庫中對應(yīng)的表通過什么字段和關(guān)系類的主鍵進行關(guān)聯(lián),這個注釋是可選的,如果不提供該注釋,kodo在使用”對象名_id”和關(guān)聯(lián)表進行關(guān)聯(lián)(簡單情況下),比如演示場景中類book的bookextend沒有使用joincolumn注釋進行聲明,我們使用kodo ejb提供的mapping tool工具生成表格的時候,book類對應(yīng)的表book中將自動加入列bookextend_id,它的類型將和bookextend對應(yīng)表的主鍵字段id類型保持一致。

  joincolumn注釋中有兩個屬性:name和referencedcolumnname屬性。

  1. name

    string類型。

    它用于指定主類對應(yīng)的表中和關(guān)系類的主鍵進行關(guān)聯(lián)的字段的名稱,比如上例中,我們不希望使用默認的bookextend_id字段名進行關(guān)聯(lián),我們可以在book類中使用joincolumn注釋bookextend屬性,設(shè)置joincolumn注釋為自己想要的名字比如extendid或者其他。

  2. referencedcolumnname

    string類型。

    指定關(guān)聯(lián)表中與主表形成關(guān)聯(lián)關(guān)系的字段名。主要用于設(shè)置區(qū)別于主鍵字段的情況。比如bookextend表中默認使用id進行關(guān)聯(lián),但現(xiàn)在需要使用其他字段進行關(guān)聯(lián),我們就可以提供該屬性。

  joincolumn用法舉例

public class book{ // 其他內(nèi)容… @onetoone(optional=true,cascade=cascadetype.all) @joincolumn(name="extendid",referencedcolumnname="id") public bookextend bookextend; } 

  編寫符合要求的持久化類

  現(xiàn)在我們開始根據(jù)上面章節(jié)中介紹的內(nèi)容編寫符合模擬場景中要求的book類和bookextend類,下面是作者編寫的兩個類的全部代碼,代碼中加入了比較多的注釋方便大家理解。

  book類

package org.vivianj.kodo.examples.beans; import javax.persistence.basic; import javax.persistence.cascadetype; import javax.persistence.column; import javax.persistence.entity; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.inheritance; import javax.persistence.inheritancetype; import javax.persistence.joincolumn; import javax.persistence.onetoone; /**  * book 用于表征系統(tǒng)中的書籍對象,他有三個屬性
* id - 書籍編號,書籍編號將由mysql數(shù)據(jù)庫自動生成
* name - 書名
* bookextend – 書的擴展信息,和bookextend是一對一(onetoone)關(guān)系 */ /* entity注釋表示該類是持久化類,的name屬性是該實體在查詢中對應(yīng)的唯一名稱,默認是類名 */ @entity(name = "book") /* table注釋的name屬性指定該持久化類對應(yīng)的數(shù)據(jù)表的名稱,默認數(shù)據(jù)表名和類名保持一致,為了
* 增強代碼的可移植性,建議大家在name屬性中使用大寫英文字母 */ /* inheritance注釋的strategy確定了持久化對象和數(shù)據(jù)表之間的關(guān)系,可選擇項包括single_table、joined和table_per_class,我們這里采用joined */ /* table_per_class : strategy 設(shè)置為該選項表示每個類使用一個表,也就是上面所說的第一種情況*/ /* single_table : strategy 設(shè)置為該選項表示所有類及其子類共用一個表,也就是上面所說的第二種情況*/ /* joined : strategy 設(shè)置為該選項表示每個類使用子表保存子類比父類多出的屬性,也就是上面所說的第三種情況*/ @inheritance(strategy = inheritancetype.joined) public class book { /* id注釋表示該字段是標(biāo)識字段 */ @id /* generatedvalue注釋定義了該標(biāo)識字段的產(chǎn)生方式,我們的演示系統(tǒng)中id由mysql數(shù)據(jù)庫字段自動生成,因此選擇generationtype.identity */ @generatedvalue(strategy = generationtype.identity) /* column注釋的name屬性定義了該類屬性對應(yīng)的數(shù)據(jù)字段的名稱,為了最大限度保持系統(tǒng)和數(shù)據(jù)庫之前的獨立性,建議使用大寫字符 */ @column(name = "id") public int id; /* basic注釋表示該屬性是基本屬性 */ @basic /* column注釋的name屬性定義了該類屬性對應(yīng)的數(shù)據(jù)字段的名稱,為了最大限度保持系統(tǒng)和數(shù)據(jù)庫之前的獨立性,建議使用大寫字符 */ @column(name = "name") public string name = null; /* 使用onetoone注釋表示該屬性和book類形成一對一關(guān)系,onetoone注釋的option屬性設(shè)為true表示該對象可以不存在,cascade屬性設(shè)置為cascadetype.all,表示book和bookextend對象級聯(lián)新建、更新、刪除、刷新 */ @onetoone(optional=true,cascade=cascadetype.all) /* 使用joincolumn注釋設(shè)置兩個對象對應(yīng)數(shù)據(jù)庫表之間的關(guān)聯(lián)字段 */ @joincolumn(name="extendid",referencedcolumnname="id") public bookextend bookextend; }

  bookextend類

package org.vivianj.kodo.examples.beans; import javax.persistence.basic; import javax.persistence.column; import javax.persistence.entity; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.inheritance; import javax.persistence.inheritancetype; import javax.persistence.joincolumn; /**  * bookextend 用于表征系統(tǒng)中書的擴展信息,他有兩個屬性:
* id - 擴展信息編號,擴展信息編號將由mysql數(shù)據(jù)庫自動生成
* name - 書的前言信息
*/ /* entity注釋表示該類是持久化類,的name屬性是該實體在查詢中對應(yīng)的唯一名稱,默認是類名 */ @entity /* table注釋的name屬性指定該持久化類對應(yīng)的數(shù)據(jù)表的名稱,默認數(shù)據(jù)表名和類名保持一致,為了
* 增強代碼的可移植性,建議大家在name屬性中使用大寫英文字母 */ /* inheritance注釋的strategy確定了持久化對象和數(shù)據(jù)表之間的關(guān)系,可選擇項包括
* single_table、joined和table_per_class,我們這里采用joined */ /* table_per_class : strategy 設(shè)置為該選項表示每個類使用一個表,也就是上面所說的第一種情況*/ /* single_table : strategy 設(shè)置為該選項表示所有類及其子類共用一個表,也就是上面所說的第二種情況*/ /* joined : strategy 設(shè)置為該選項表示每個類使用子表保存子類比父類多出的屬性,也就是上面所說的第三種情況*/ @inheritance(strategy = inheritancetype.joined) public class bookextend { /* id注釋表示該字段是標(biāo)識字段 */ @id /* generatedvalue注釋定義了該標(biāo)識字段的產(chǎn)生方式,我們的演示系統(tǒng)中id由mysql數(shù)據(jù)庫字段自動生成,因此選擇generationtype.identity */ @generatedvalue(strategy = generationtype.identity) /* column注釋的name屬性定義了該類屬性對應(yīng)的數(shù)據(jù)字段的名稱,為了最大限度保持系統(tǒng)和數(shù)據(jù)庫之前的獨立性,建議使用大寫字符 */ @column(name = "id") public int id; /* basic注釋表示該屬性是基本屬性 */ @basic /* column注釋的name屬性定義了該類屬性對應(yīng)的數(shù)據(jù)字段的名稱,為了最大限度保持系統(tǒng)和數(shù)據(jù)庫之前的獨立性,建議使用大寫字符 */ @column(name = "name") public string name = null; }
  調(diào)用代碼

  上面的代碼中,我們已經(jīng)準(zhǔn)備好了符合要求的持久化類,下面我們看看kodo ejb中如何調(diào)用這兩個類完成book類和bookextend類的創(chuàng)建、修改、刪除工作。

  由于篇幅的關(guān)系,這些沒有講述如何編譯、加強這些類并且準(zhǔn)備相應(yīng)的配置文件來完成整個項目開發(fā)環(huán)境的建立,這部分的內(nèi)容請參考我的另外一篇文章《kodo ejb:符合ejb3規(guī)范的持久層框架

  級聯(lián)新建對象

  下面的這段代碼演示了只需要調(diào)用book類的persist方法就同時持久化book類對象和bookextend類對象的情況。請注意其中用粗體標(biāo)識出的部分。
/* 獲得ejb的實體管理器 */ entitymanagerfactory emf = persistence.createentitymanagerfactory(null); entitymanager em = emf     .createentitymanager(persistencecontexttype.extended); /* 開始事務(wù) */ em.gettransaction().begin();    /* 創(chuàng)建新的book對象 */ book book = new book(); /* 設(shè)置book對象的name屬性 */ book.name = "kodo入門"; /* 創(chuàng)建新的bookextend對象 */ bookextend bookextend = new bookextend(); /* 設(shè)置對象屬性 */ bookextend.name = "spring is a very good book that ..."; /* 建立對象之間的關(guān)系 */ book.bookextend = bookextend; /* 持久化對象,只需要持久化book對象,不需要單獨持久化bookextend對象 */ em.persist(book); /* 結(jié)束事務(wù) */ em.gettransaction().commit(); em.close(); emf.close(); 
  級聯(lián)更新對象狀態(tài)

  下面的這段代碼演示了只需要調(diào)用book類的merge方法就同時更新book類對象和bookextend類對象狀態(tài)的情況。請注意其中用粗體標(biāo)識出的部分。
/* 獲得ejb的實體管理器 */ entitymanagerfactory emf = persistence.createentitymanagerfactory(null); entitymanager em = emf     .createentitymanager(persistencecontexttype.extended); /* 開始事務(wù) */ em.gettransaction().begin();    /* 創(chuàng)建新的book對象 */ book book = new book(); /* 設(shè)置book對象的id屬性 */ book.id= 1; book.name = “kodo 入門”; /* 創(chuàng)建新的bookextend對象 */ bookextend bookextend = new bookextend(); /* 設(shè)置對象屬性 */ bookextend.id=1; bookextend.name = "kodo 分為kodo ejb和kodo jdo ..."; /* 建立對象之間的關(guān)系 */ book.bookextend = bookextend; /* 持久化對象,只需要調(diào)用book對象的merge方法,不需要單獨處理bookextend對象 */ em.merge(book); /* 結(jié)束事務(wù) */ em.gettransaction().commit(); em.close();  emf.close(); 
  級聯(lián)刪除對象
/* 獲得ejb的實體管理器 */ entitymanagerfactory emf = persistence.createentitymanagerfactory(null); entitymanager em = emf     .createentitymanager(persistencecontexttype.extended); /* 開始事務(wù) */ em.gettransaction().begin(); /* 使用查詢刪除對象,可以不必將對象加入到內(nèi)存中,提高效率 */ query q = entitymanager     .createquery("delete from book c where c.id=:id"); int id = book.id; /* 設(shè)置被刪除book對象的主鍵值 */ q.setparameter("id", id); /* 當(dāng)方法被調(diào)用時,book對象對應(yīng)的bookextend對象會同時被刪除 */ q.executeupdate(); /* 結(jié)束事務(wù) */ em.gettransaction().commit(); em.close();  emf.close(); 
  其他幾種關(guān)聯(lián)關(guān)系

  一對多

  我們可以使用onetomany注釋來描述類和類之間的一對多關(guān)系,onetomany注釋有四個屬性:targetentity、mappedby、cascade和fetch,這四個屬性的具體含義和onetoone注釋注釋的同名屬性一一對應(yīng),請大家參考前面章節(jié)中的內(nèi)容。

  多對一

  我們可以使用manytoone注釋來描述類和類之間的多對一關(guān)系,manytoone注釋有四個屬性:targetentity、cascade、fetch和optional,這四個屬性的具體含義和onetoone注釋注釋的同名屬性一一對應(yīng),請大家參考前面章節(jié)中的內(nèi)容。

  多對多

  我們可以使用manytomany注釋來描述類和類之間的多對多關(guān)系,manytomany注釋有四個屬性:targetentity、mappedby、cascade和fetch,這四個屬性的具體含義和onetoone注釋注釋的同名屬性一一對應(yīng),請大家參考前面章節(jié)中的內(nèi)容。

  總結(jié)

  對象和對象之間除了繼承關(guān)系之外,還存在著關(guān)聯(lián)關(guān)系,包括一對一、一對多、多對一和多對多的關(guān)系,本文中,作者以一對一關(guān)系為例,結(jié)合簡單的例子,詳細地描述了如何在kodo ejb框架下通過注釋簡單的描述類和類之間的關(guān)系,并且實現(xiàn)類操作的級聯(lián)特性。文章的最后簡單的說明了kodo ejb中實現(xiàn)一對多、多對一和多對多時需要用到的注釋,具體的實現(xiàn)請大家參考文檔中的內(nèi)容自行完成。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 盱眙县| 连南| 湘潭市| 昔阳县| 德安县| 屯昌县| 丹东市| 南部县| 高青县| 将乐县| 阳江市| 秀山| 新邵县| 凤山县| 固镇县| 翼城县| 卢龙县| 达日县| 玉树县| 启东市| 留坝县| 上虞市| 曲靖市| 汽车| 莆田市| 宁城县| 绍兴市| 襄垣县| 宝坻区| 阿拉善左旗| 大庆市| 奉节县| 齐河县| 山西省| 琼海市| 镇坪县| 丹阳市| 古交市| 河北区| 民丰县| 彰武县|