Hibernate(二)——持久化

1.OID和主鍵生成策略


1.1.主鍵(Primary key):

在數(shù)據(jù)庫(kù)表中能夠唯一識(shí)別每一行記錄的一個(gè)字段或者多個(gè)字段的組合.

主鍵特點(diǎn):
非空且唯一,簡(jiǎn)單.一般的使用一個(gè)列來(lái)表示主鍵.

主鍵分類:

名稱 區(qū)別
自然主鍵 主鍵具有業(yè)務(wù)含義,比如身份證號(hào)碼,必須要收到輸入.
代理主鍵 主鍵沒(méi)有業(yè)務(wù)含義,僅僅起唯一標(biāo)識(shí),一般由數(shù)據(jù)庫(kù)服務(wù)器自動(dòng)生成.
單字段主鍵 在一張表中使用某一列作為主鍵.
復(fù)合主鍵 在一張表中使用多列一起,聯(lián)合作為主鍵.

1.2.OID

  • 1.在hibernate中,一個(gè)對(duì)象必須要有一個(gè)id,這個(gè)id對(duì)應(yīng)數(shù)據(jù)庫(kù)的主鍵;

  • 2.在hibernate當(dāng)中,把對(duì)象中對(duì)應(yīng)數(shù)據(jù)表主鍵的屬性,對(duì)象標(biāo)識(shí)符(OID).

  • 3.OID可以是單個(gè)屬性,也可以使多個(gè)屬性(復(fù)合主鍵的映射)

  • 4.OID的重要作用:

    1.OID在Hibernate中唯一標(biāo)識(shí)了一個(gè)對(duì)象(在數(shù)據(jù)庫(kù)表中主鍵唯一的表示了一行數(shù)據(jù));
    2.在一級(jí)緩存中,Type+ID唯一標(biāo)識(shí)了一級(jí)緩存中相同的數(shù)據(jù) .
    3.一般情況,在domain當(dāng)中,需要用OID屬性來(lái)重寫equals和hashcode法方法

  • 5.單個(gè)OID都使用<id>元素來(lái)映射,name代表OID屬性的名稱,column表示對(duì)應(yīng)表中主鍵的列名.

  • 6.id元素都有一個(gè)generator子元素,規(guī)定了主鍵的生成策略.

自然主鍵:assigned,在保存之前必須手動(dòng)設(shè)置值,assigned只針對(duì)于自然主鍵


image.png

保存改對(duì)象的時(shí)候,必須手動(dòng)輸入該值.

1.3.代理主鍵的生成方式(讓數(shù)據(jù)庫(kù)生成或讓hibernate生成):

  • 1:uuid:使用uuid作為主鍵值 ,使用uuid這一種生成策略,此時(shí)主鍵必須是String類型.
  • 2:increment:增長(zhǎng)方式.

    1,hibernate生成主鍵
    2,先查詢當(dāng)前表id最大值,自增1后作為當(dāng)前對(duì)象的id
    3,主鍵類型可以遞增;不能在集群(多個(gè)hibernate應(yīng)用使用同一個(gè)數(shù)據(jù)庫(kù))的情況下使用;

  • 3:identity:

    1,使用數(shù)據(jù)庫(kù)本身的id生成策略:MySQL:auto_increment;
    2,數(shù)據(jù)庫(kù)本身必須支持id自動(dòng)增長(zhǎng)策略,Oracle不能使用.

  • 4:sequence:序列

    1,使用序列生成id,如果只配置sequence,會(huì)創(chuàng)建一個(gè)默認(rèn)的序列hibernate_sequence;
    2,數(shù)據(jù)庫(kù)本身必須支持序列

//可以通過(guò)sequence參數(shù)來(lái)指定表對(duì)應(yīng)的序列生成器的名字
<generator class="sequence">
   <param name="sequence">IDDOMAIN_SEQ</param>
</generator>
  • 5:native:

    1,使用數(shù)據(jù)庫(kù)本地的主鍵生成策略
    對(duì)于mysql:auto_increment;
    對(duì)于oracle:使用默認(rèn)的sequence;

  • 6:org.hibernate.id.enhanced.TableGenerator

    1,相當(dāng)于序列生成器,hibernate使用一張hibernate_seqences這樣的表來(lái)模擬序列生成器
    2,如果只配置org.hibernate.id.enhanced.TableGenerator,相當(dāng)于所有的表都使用default這一個(gè)序列生成器
    3,會(huì)造成很多額外的SQL

<generator class="org.hibernate.id.enhanced.TableGenerator">
     <param name="segment_value">IDDOMAIN_SEQ</param>
</generator>

1.4.選擇:

1,自然主鍵還是代理主鍵;
2,使用數(shù)據(jù)庫(kù)來(lái)生成主鍵還是使用hibernate來(lái)生成主鍵(應(yīng)用是否需要移植數(shù)據(jù)庫(kù))
是否在集群環(huán)境中使用
3,性能問(wèn)題
4,一般來(lái)說(shuō),使用native就可以了.

image.png

2.Session中的方法


常用方法(已學(xué)):

Transaction beginTransaction():開(kāi)啟一個(gè)事務(wù)
Transaction getTransaction():獲取一個(gè)事務(wù)
Serializable save(Object o):保存一個(gè)對(duì)象
void update(Object o):修改一個(gè)對(duì)象
void delete(Object o):刪除一個(gè)對(duì)象
Object get(Class type,Serializable id):根據(jù)主鍵查詢指定類型的對(duì)象
Query createQuery(String hql):根據(jù)hql創(chuàng)建一個(gè)查詢對(duì)象
void close():關(guān)閉Session
void clear():清除一級(jí)緩存所有對(duì)象
void evict(Object o):清除一級(jí)緩存中制定的對(duì)象

按照方法的功能,把session的方法分為:

2.1.事務(wù)相關(guān):

Transactionsession.beginTransaction():標(biāo)記打開(kāi)當(dāng)前session綁定的事務(wù)對(duì)象墨礁。
Transactionsession.getTransaction():得到和當(dāng)前session綁定的事務(wù)對(duì)象。

2.2.一級(jí)緩存相關(guān):

session.clear():清除一級(jí)緩存中所有的對(duì)象。
boolean contains(Object entity):判斷一級(jí)緩存中是否有給定的對(duì)象。
session.evict(Object entity):從一級(jí)緩存中清除指定的對(duì)象搁痛。
session.flush():把一級(jí)緩存中的臟數(shù)據(jù)同步到數(shù)據(jù)庫(kù)中渠概。
session.refresh(Objectentity):強(qiáng)制重新查詢對(duì)象,相當(dāng)于把數(shù)據(jù)庫(kù)中的數(shù)據(jù)同步到一級(jí)緩存中择示。

2.3.持久化操作相關(guān):

session.delete(Objectentity):從數(shù)據(jù)庫(kù)中刪除一個(gè)對(duì)象
session.update(Objectentity):更新一個(gè)對(duì)象
session.get(ClassentityType,Serializableid):根據(jù)主鍵查詢一個(gè)對(duì)象
session.load(ClassentityType,Serializableid):根據(jù)主鍵加載一個(gè)對(duì)象

1.load方法是一個(gè)延遲加載(lazy-load)的方法;把對(duì)象的獲壬孤谩(SQL)延遲到了真正使用這個(gè)對(duì)象的時(shí)候才發(fā)送对妄;
2.真正使用?當(dāng)使用一個(gè)非主鍵屬性的時(shí)候敢朱;
3.load實(shí)現(xiàn)原理剪菱?使用動(dòng)態(tài)代理,為load的domain動(dòng)態(tài)創(chuàng)建了一個(gè)子類拴签,在這個(gè)子類中孝常,復(fù)寫所有非主鍵調(diào)用方法,在這些方法中蚓哩,去發(fā)送.

session.save(Objectentity):保存一個(gè)對(duì)象

1.同步JPA的接口方法构灸;
2.和save的區(qū)別:在沒(méi)有事務(wù)環(huán)境下,save方法會(huì)發(fā)送INSERT SQL岸梨,persist不會(huì)喜颁;)

session.saveOrUpdate(Objectentity):如果對(duì)象沒(méi)有保存到數(shù)據(jù)庫(kù),則保存曹阔,如果已經(jīng)保存過(guò)半开,則更新。
session.merge(Objectentity):等同于saveOrUpdate方法赃份。

1.同步JPA的接口方法寂拆;
2.和saveOrUpdate的區(qū)別:在沒(méi)有事務(wù)環(huán)境下奢米,saveOrUpdate方法會(huì)發(fā)送INSERT SQL,merge不會(huì)纠永;

2.4.其他:

session.close():關(guān)閉session鬓长,相當(dāng)于關(guān)閉了和session關(guān)聯(lián)的connection對(duì)象。關(guān)閉session之后尝江,就不能再使用這個(gè)session完成持久化相關(guān)的操作涉波。
session.doWork(Workwork):Hibernate提供給程序員直接使用JDBC的一個(gè)途徑。
session.doReturningWork(ReturningWork):Hibernate提供給程序員直接使用JDBC的一種途徑炭序。
Serializablesession.getIdentifier(Objectentity):得到一個(gè)對(duì)象的主鍵值

session 上面所有的方法都在促使對(duì)象的狀態(tài)發(fā)生改變.

2.5.Hibernate中對(duì)象保存的方法:

persist和方法save方法都表示保存一個(gè)對(duì)象,但是persist方法必須運(yùn)行在事務(wù)空間內(nèi).

save(e);   //沒(méi)有事務(wù)環(huán)境,也會(huì)發(fā)送INSERT INTO語(yǔ)句
persist(e);//沒(méi)有事務(wù)環(huán)境,不會(huì)發(fā)送INSERT INTO語(yǔ)句.

Hibernate實(shí)現(xiàn)了JPA的規(guī)范,就得提供JPA中的方法,而在JPA中持久化操作的方法就叫做:persist.
建議使用persist方法.

2.6.保存或更新操作方法:

session.saveOrUpdate(Objectentity):如果對(duì)象沒(méi)有保存到數(shù)據(jù)庫(kù)怠蹂,則保存,如果已經(jīng)保存過(guò)少态,則更新。

  • 如果對(duì)象存在OID,則update
  • 如果對(duì)象不存在OID,則save.

merge方法相當(dāng)于saveOrUpdate方法.必須運(yùn)行在事務(wù)空間內(nèi),是JPA規(guī)范的方法.

2.7.加載或查詢指定類型和IOD的一個(gè)對(duì)象:

Object obj = session.load(Classs type,Serializable id)
Object obj = session.get(Classs type,Serializable id)
  • get方法返回的總是持久化狀態(tài)的對(duì)象;get方法立刻發(fā)送一條SELECT語(yǔ)句,結(jié)果可以用if-null來(lái)判斷.
  • load方法并不會(huì)立刻發(fā)送一條SELECT語(yǔ)句去查詢對(duì)象,而要到真正在使用(使用一個(gè)非主鍵屬性)這個(gè)對(duì)象的時(shí)候,才會(huì)去發(fā)送SELECT語(yǔ)句,我們把這種方式叫做延遲加載(lazy-load/懶加載).

如果對(duì)象沒(méi)有被加載過(guò),則發(fā)送一條SELECT語(yǔ)句,去加載對(duì)象,再返回屬性值.
load方法返回的對(duì)象永遠(yuǎn)不可能為空,所以不能使用ifnull來(lái)判斷,如果load了一個(gè)不存在的id的對(duì)象,在使用的時(shí)候報(bào)錯(cuò);
load方法返回的對(duì)象是持久化對(duì)象;
load方法也會(huì)從一級(jí)緩存中獲取數(shù)據(jù)

load原理:

  • 1).Hibernate框架的中的javassist組件創(chuàng)建了代理類以及對(duì)象.
  • 2).該對(duì)象提供了非主鍵屬性的getter方法和toString方法.
  • 3):該對(duì)象存在是否加載完畢的狀態(tài),訪問(wèn)屬性是先判斷對(duì)象是否加載完畢,如是直接返回該屬性之,否則發(fā)送SQL查詢?cè)搶?duì)象.

如果在session關(guān)閉之前沒(méi)有去實(shí)例化延遲加載對(duì)象,報(bào)錯(cuò):
LazyInitializationException: could not initialize proxy - no Session.

LoadEventListener$LoadType類
一般的,load方法是Hibernate內(nèi)部使用的,我們就使用get方法即可.

image.png

3.持久化對(duì)象的狀態(tài)


3.1.通過(guò)三個(gè)問(wèn)題,引出對(duì)象狀態(tài).

  • 問(wèn)題1: 主鍵生成策略不同,save操作時(shí)發(fā)生INSERT語(yǔ)句的時(shí)機(jī)不同.

    native: 在執(zhí)行save方法的時(shí)候發(fā)送INSERT SQL.
    increment: 在提交事務(wù)的時(shí)候,才發(fā)送INSERT SQL.

  • 問(wèn)題2: 刪除對(duì)象的時(shí)候,沒(méi)有立刻發(fā)生DELETE語(yǔ)句,而是在提交事務(wù)的時(shí)候發(fā)送的.

  • 問(wèn)題3: 為什么在事務(wù)環(huán)境下,通過(guò)get方法得到的對(duì)象,只要修改了屬性值,會(huì)發(fā)生UPDATE語(yǔ)句.

結(jié)論:
通過(guò)上述三個(gè)測(cè)試,我們發(fā)現(xiàn)Session中的方法和SQL的執(zhí)行沒(méi)有任何關(guān)系.
問(wèn)題:那到底SQL的執(zhí)行和什么有關(guān)系呢?有什么關(guān)系呢? ---->和對(duì)象的狀態(tài)有關(guān)系.

3.2.持久化對(duì)象的狀態(tài)有哪一些,怎么劃分的?

劃分的規(guī)則:
1):當(dāng)前對(duì)象是否有OID(該對(duì)象在表中對(duì)應(yīng)有一個(gè)id值.)
2):對(duì)象是否被Session所管理(對(duì)象是否在一級(jí)緩存中).

狀態(tài) - 特點(diǎn)
臨時(shí)狀態(tài)/瞬時(shí)態(tài)(transient) 剛剛用new語(yǔ)句創(chuàng)建易遣,沒(méi)有被持久化彼妻,不處于session中。 沒(méi)有oid,不在session當(dāng)中.
持久化狀態(tài)(persistent) 已經(jīng)被持久化豆茫,加入到session的緩存中侨歉。 有oid,在session當(dāng)中
脫管態(tài)/游離狀態(tài)(detached) 已經(jīng)被持久化,但不處于session中揩魂。 有oid,不在session當(dāng)中
刪除狀態(tài)(removed) 對(duì)象有關(guān)聯(lián)的ID幽邓,并且在Session管理下,但是已經(jīng)計(jì)劃被刪除火脉。 有oid,在session當(dāng)中,最終的效果是被刪除.

判斷規(guī)則:
對(duì)象是否有OID牵舵,判斷對(duì)象是否與Session關(guān)聯(lián)(被Hibernate管理)

3.3.狀態(tài)的之間的轉(zhuǎn)換:

  • Transient(臨時(shí)狀態(tài)/瞬時(shí)狀態(tài)):
    特點(diǎn),沒(méi)有OID,不被Session所管理.

    情況1):new語(yǔ)句剛創(chuàng)建了一個(gè)對(duì)象.
    情況2):刪除狀態(tài)的對(duì)象,在事務(wù)提交之后,對(duì)象處于臨時(shí)狀態(tài).

臨時(shí)狀態(tài)是沒(méi)有ID的,測(cè)試可以打印該對(duì)象的ID,發(fā)現(xiàn)存在ID.
--->設(shè)置hibernate.cfg.xml的屬性:hibernate.use_identifier_rollback=true

  • Removed(刪除狀態(tài)):
    特點(diǎn):此時(shí)有OID,被Session所管理中,但是最終會(huì)被刪除.

    情況1:delete方法讓持久化狀態(tài)和游離狀態(tài)變成刪除狀態(tài).
    但是刪除狀態(tài)的對(duì)象必須等到session刷新(flush),事務(wù)提交時(shí)才真正從數(shù)據(jù)庫(kù)中刪除.

  • Persistent(持久化狀態(tài)):
    特點(diǎn):有OID,被Session所管理.

    情況1):save方法把臨時(shí)狀態(tài)轉(zhuǎn)換為持久化狀態(tài).
    情況2):save方法把游離對(duì)象變成另一個(gè)持久化狀態(tài).
    保存一個(gè)對(duì)象之后,提交事務(wù)/關(guān)閉Session,此時(shí)對(duì)象處于游離狀態(tài),再創(chuàng)建新的Session來(lái)保存該對(duì)象.
    情況3):get和load方法返回的是持久化對(duì)象.
    情況4):Query.list方法返回的是持久化對(duì)象,在處理大數(shù)據(jù)量的時(shí)候,需要及時(shí)清理一級(jí)緩存(分頁(yè)查詢).
    情況5):update方法把游離對(duì)象變成持久化對(duì)象.

  • Detached(游離狀態(tài)/托管狀態(tài)):
    特點(diǎn):有OID,但是不被Session所管理(不在一級(jí)緩存中).

    情況1):session.close()方法把所有的持久化對(duì)象變成游離對(duì)象.
    情況2):session.clear()方法把所有持久化對(duì)象變成游離對(duì)象.
    情況3):session.evivt(Object)方法把制定的持久化對(duì)象變成游離對(duì)象.
    情況4):使用new創(chuàng)建對(duì)象,并設(shè)置OID(數(shù)據(jù)庫(kù)存在該ID);

image.png

3.4.總結(jié):

Session中的方法僅僅只是改變對(duì)象的狀態(tài),不負(fù)責(zé)發(fā)送SQL/默認(rèn)情況下事務(wù)提交的時(shí)候發(fā)送SQL.

  • 問(wèn)題1: 主鍵生成策略不同,save操作時(shí)發(fā)生INSERT語(yǔ)句的時(shí)機(jī)不同.

    native: 在執(zhí)行save方法的時(shí)候發(fā)送INSERT SQL.
    increment: 在提交事務(wù)的時(shí)候,才發(fā)送INSERT SQL.
    原因是:save方法僅僅是把臨時(shí)狀態(tài)的對(duì)象轉(zhuǎn)換為持久化狀態(tài),本身不負(fù)責(zé)發(fā)送SQL.
    臨時(shí)狀態(tài)的對(duì)象沒(méi)有IOD,調(diào)用save方法之后,變成持久化狀態(tài),就必須有OID.
    此時(shí):從臨時(shí)狀態(tài)轉(zhuǎn)換為持久化狀態(tài),只需要獲取OID即可.
    native:表示數(shù)據(jù)庫(kù)主鍵的自增長(zhǎng),只有發(fā)送SQL,才能獲取主鍵,----->OID.
    increment:先發(fā)送SELECT語(yǔ)句查詢id,(擁有了OID),不需要發(fā)送INSERET來(lái)獲取ID.

  • 問(wèn)題2: 刪除對(duì)象的時(shí)候,沒(méi)有立刻發(fā)生DELETE語(yǔ)句,而是在提交事務(wù)的時(shí)候發(fā)送的.

    原因是:delete方法僅僅是改變對(duì)象的狀態(tài),本身不負(fù)責(zé)發(fā)送SQL.

  • 問(wèn)題3: 為什么在事務(wù)環(huán)境下,通過(guò)get方法得到的對(duì)象,只要修改了屬性值,會(huì)發(fā)生UPDATE語(yǔ)句.

    原因是:通過(guò)get查詢操作得到的對(duì)象處于持久化狀態(tài)(有OID,存在于一級(jí)緩存中).
    此時(shí),修改了非IOD的屬性值,發(fā)現(xiàn)一級(jí)緩存中的數(shù)據(jù)和快照區(qū)域的數(shù)據(jù)不同(臟數(shù)據(jù)),
    Hibernate就會(huì)做比較(一級(jí)緩存和快照區(qū)),發(fā)送不同,就發(fā)送UPDATE語(yǔ)句,做數(shù)據(jù)同步.
    session的flush方法,負(fù)責(zé)把一級(jí)緩存中的臟數(shù)據(jù)同步到數(shù)據(jù)庫(kù)中去.

User u = new User();  //臨時(shí)狀態(tài)
u.setName("XX");

session.save(u);---->SELECT max(id) //持久化狀態(tài)

//持久化狀態(tài)可以被刪除.
 User  u = session.get(User.class,1L);
 session.delete(u);

 User u = new User();
 u.setId(1L);//游離狀態(tài)
-----------------------------------

image.png

4.集合映射


之前對(duì)象中的屬性:都是簡(jiǎn)單數(shù)據(jù)類型(一個(gè)類型對(duì)應(yīng)一個(gè)值.String,Integer,Date)
屬性是集合類型:

案例:根據(jù)一個(gè)用戶有一個(gè)郵箱地址,分析表結(jié)構(gòu)的設(shè)計(jì).
因?yàn)榇藭r(shí):一個(gè)用戶最多只有一個(gè)郵件地址,可以直接郵件作為用戶表的一列.
如何一個(gè)用戶有多個(gè)郵箱地址,分析表結(jié)構(gòu)的設(shè)計(jì).

image.png

image.png

存儲(chǔ)多個(gè)數(shù)據(jù),此時(shí)只能使用集合.
Set/List/Map.
Set:不記錄添加順序,元素不能重復(fù).
List:記錄添加的順序,元素運(yùn)行重復(fù).
Map:存儲(chǔ)鍵值對(duì),每次存儲(chǔ)都要存儲(chǔ)key和value.
在開(kāi)發(fā)中靈活選用,根據(jù)各自的特點(diǎn)和具體的需求.

Set set = new HashSet();
List list = new ArrayList();
Map map  = new HashMap();

集合屬性只能以接口聲明(當(dāng)持久化某個(gè)實(shí)例時(shí), Hibernate 會(huì)自動(dòng)把程序中的集合實(shí)現(xiàn)類替換成 Hibernate 自己的集合實(shí)現(xiàn)類),

image.png

集合屬性只能以接口聲明(當(dāng)持久化某個(gè)實(shí)例時(shí), Hibernate 會(huì)自動(dòng)把程序中的集合實(shí)現(xiàn)類替換成 Hibernate 自己的集合實(shí)現(xiàn)類
---->PersistentSet
---->PersistentList


image.png

選擇:
如果集合類型使用Set,則使用<set>元素.
如果集合類型使用List,則使用<bag>元素.

Hibernate對(duì)集合賬號(hào)的原生支持兩種排序方式(了解):

  • 1:內(nèi)存中排序,Hibernate把數(shù)據(jù)加載到內(nèi)存中的Java集合中,根據(jù)集合自身的功能來(lái)排序(自然排序/定制排序).
  • 2:數(shù)據(jù)庫(kù)排序,Hibernate通過(guò)SELECT語(yǔ)句從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)的時(shí)候,使用ORDER BY字句進(jìn)行排序.
排序?qū)傩?/th> <set> <bag> <list> <map>
sort屬性 支持 不支持 不支持 支持
order-by屬性 支持 支持 不支持 支持

需求:根據(jù)郵件的地址逆序排序.

<!-- 映射Collection/List集合 -->
<bag name="emailBag" table="user_emails_bag" order-by="address DESC">
    <key column="user_id" />
    <element column="address" type="string" />
</bag>

order-by="address DESC":
注意:address表示數(shù)據(jù)庫(kù)表的列名.

5.對(duì)象之間的關(guān)系(寫少量代碼):


5.1.依賴關(guān)系:

如果A對(duì)象離開(kāi)了B對(duì)象,A對(duì)象就不能正常編譯,則A對(duì)象依賴B對(duì)象.
在A類使用到了B(調(diào)用了B的方法,調(diào)用了B的字段).

//依賴關(guān)系:
class B1{}
class B2{}
class A{
   B2 b2;//A依賴B2
   void doWork(){
      B1 b1 = new B1();//A依賴于B1
   }
}

5.2.關(guān)聯(lián)關(guān)系:

A對(duì)象依賴B對(duì)象,并且把B對(duì)象作為A對(duì)象的一個(gè)字段,則A和B是關(guān)聯(lián)關(guān)系.

class B{}
class A{
   B b;//關(guān)聯(lián)關(guān)系
}
class Deparment{
  //一對(duì)多
  List<Employee> employees = new ...;
}
class Employee{
}

Deparment d = new ...();
Employee e1 = new ....();
Employee e2 = new ....();
Employee e3 = new ....();

d.getEmployess().add(e1);
d.getEmployess().add(e2);
d.getEmployess().add(e3);

class Deparment{}
class Employee{
   //多對(duì)一
   Department dept;
}
Deparment d = new ...();

Employee e1 = new ....();
Employee e2 = new ....();
Employee e3 = new ....();

e1.setDept(d);
e2.setDept(d);
e2.setDept(d);

按照多重性分:

關(guān)聯(lián)關(guān)系 解釋 例子
1).一對(duì)一 : 一個(gè)A對(duì)象屬于一個(gè)B對(duì)象;
一個(gè)B對(duì)象屬于一個(gè)A對(duì)象.
QQ號(hào)碼對(duì)應(yīng)一個(gè)QQ空間.
2).一對(duì)多: 一個(gè)A對(duì)象包含多個(gè)B對(duì)象. 一個(gè)部門包含多個(gè)員工對(duì)象,
此時(shí)我們使用集合來(lái)封裝B對(duì)象.
3).多對(duì)一: 多個(gè)A對(duì)象同屬于一個(gè)B對(duì)象,
并且每個(gè)A對(duì)象只能屬于一個(gè)B對(duì)象.
設(shè)計(jì)表的時(shí)候:外鍵在many這一方
在開(kāi)發(fā)設(shè)計(jì)中:添加一個(gè)many方對(duì)象的時(shí)候,
往往通過(guò)下拉列表去選擇one方.
多個(gè)員工對(duì)象屬于同一個(gè)部門.
4).多對(duì)多 一個(gè)A對(duì)象屬于多個(gè)B對(duì)象,一個(gè)B對(duì)象屬于多個(gè)A對(duì)象.
通過(guò)中間表來(lái)表示關(guān)系.
一個(gè)老師可以有多個(gè)學(xué)生,
一個(gè)學(xué)生可以有多個(gè)老師.

按照導(dǎo)航性分:
如果通過(guò)A對(duì)象中的某一個(gè)屬性可以訪問(wèn)該屬性對(duì)應(yīng)的B對(duì)象,則說(shuō)A可以導(dǎo)航到B.

- -
1).單向: 只能從A通過(guò)屬性導(dǎo)航到B,B不能導(dǎo)航到A.
2).雙向: A可以通過(guò)屬性導(dǎo)航到B,B也可以通過(guò)屬性導(dǎo)航到A.

判斷方法:
1,判斷都是從對(duì)象的實(shí)例上面來(lái)看的;
2,判斷關(guān)系必須確定一對(duì)屬性;
3,判斷關(guān)系必須確定具體需求;

5.3.聚合關(guān)系:

表示整體和部分的關(guān)系,整體和部分之間可以相互獨(dú)立存在,一定是有兩個(gè)模塊來(lái)分別管理整體和部分.
整體和部分可以分開(kāi).

5.4.組合關(guān)系:

強(qiáng)聚合關(guān)系,但是整體和部分不能獨(dú)立存在,一定是在一個(gè)模塊中同時(shí)管理整體和部分,生命周期必須相同.
單據(jù)和單據(jù)明顯/購(gòu)物車

5.5.泛化關(guān)系

:其實(shí)就是繼承關(guān)系.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市倦挂,隨后出現(xiàn)的幾起案子畸颅,更是在濱河造成了極大的恐慌,老刑警劉巖方援,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件没炒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡犯戏,警方通過(guò)查閱死者的電腦和手機(jī)送火,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)先匪,“玉大人种吸,你說(shuō)我怎么就攤上這事⊙椒牵” “怎么了骨稿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我坦冠,道長(zhǎng)形耗,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任辙浑,我火速辦了婚禮激涤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘判呕。我一直安慰自己倦踢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布侠草。 她就那樣靜靜地躺著辱挥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪边涕。 梳的紋絲不亂的頭發(fā)上晤碘,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音功蜓,去河邊找鬼园爷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛式撼,可吹牛的內(nèi)容都是我干的童社。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼著隆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼扰楼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起美浦,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤灭抑,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后抵代,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體腾节,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年荤牍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了案腺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡康吵,死狀恐怖劈榨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晦嵌,我是刑警寧澤同辣,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布拷姿,位于F島的核電站,受9級(jí)特大地震影響旱函,放射性物質(zhì)發(fā)生泄漏响巢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一棒妨、第九天 我趴在偏房一處隱蔽的房頂上張望踪古。 院中可真熱鬧,春花似錦券腔、人聲如沸伏穆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)枕扫。三九已至,卻和暖如春辱魁,著一層夾襖步出監(jiān)牢的瞬間烟瞧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工商叹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人只泼。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓剖笙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親请唱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弥咪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Hibernate: 一個(gè)持久化框架 一個(gè)ORM框架 加載:根據(jù)特定的OID,把一個(gè)對(duì)象從數(shù)據(jù)庫(kù)加載到內(nèi)存中OID...
    JHMichael閱讀 1,963評(píng)論 0 27
  • 本文包括:1、Hibernate的持久化類2十绑、Hibernate 持久化對(duì)象的三個(gè)狀態(tài)(難點(diǎn))3聚至、Hibernat...
    廖少少閱讀 1,444評(píng)論 0 13
  • 1.主鍵生成策略 1.1 主鍵的兩種類型 自然主鍵:把數(shù)據(jù)表中的某一業(yè)務(wù)字段作為表的主鍵。如一張用戶表中本橙,把用戶的...
    Wizey閱讀 542評(píng)論 0 3
  • 昨夜你闖進(jìn)了我的夢(mèng)里 當(dāng)我回眸的一瞬間 正好看到了你的深情 多情的眼眸在觸碰的剎那 我知道遲了一個(gè)世紀(jì) 于是我無(wú)視...
    田萍閱讀 153評(píng)論 0 2
  • 爐扳躬。 炭火昏黃暖醍醐。 終陳曲甚亭, 枕籍抱殘壺贷币。
    蔚海山莊三六子閱讀 216評(píng)論 0 7