成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

hibernate多對(duì)多,單個(gè)修改很傷神

zzzmh / 2623人閱讀

摘要:因?yàn)榈臎]有依賴模塊,因而,數(shù)據(jù)字典無法調(diào)用模塊中的項(xiàng)目類,如圖所示因而,如果我們采用這種方式創(chuàng)建多對(duì)多的關(guān)系,會(huì)破壞結(jié)構(gòu)或者框架結(jié)構(gòu)。如圖所示項(xiàng)目和圖片的關(guān)系,一個(gè)項(xiàng)目有很多張圖片,但是一張圖片也可以被多個(gè)項(xiàng)目使用。。。。。

導(dǎo)讀

客戶單擊項(xiàng)目詳細(xì)時(shí),會(huì)跳轉(zhuǎn)到項(xiàng)目詳細(xì)頁面。用戶單擊紅框中的加號(hào),頁面彈出選擇標(biāo)簽頁面。用戶單擊待選標(biāo)簽中的標(biāo)簽,當(dāng)前標(biāo)簽會(huì)被保存到數(shù)據(jù)庫中。

當(dāng)然,項(xiàng)目標(biāo)簽與項(xiàng)目之間是多對(duì)多的關(guān)系,也就是說,一個(gè)項(xiàng)目可以有多個(gè)標(biāo)簽,一個(gè)標(biāo)簽對(duì)應(yīng)多個(gè)項(xiàng)目,總體來說,它們之間是多對(duì)多的關(guān)系。

多對(duì)多的關(guān)系

多也是相對(duì)的多,就像導(dǎo)讀中的項(xiàng)目和項(xiàng)目標(biāo)簽一樣。這是從宏觀上來說的多對(duì)多,但從微觀上來看,其內(nèi)部還是一對(duì)多的關(guān)系。一個(gè)項(xiàng)目可以有多個(gè)項(xiàng)目標(biāo)簽,一個(gè)項(xiàng)目標(biāo)簽可以對(duì)應(yīng)多個(gè)項(xiàng)目。既然對(duì)各自來說,都是一對(duì)多的關(guān)系,為什么不這樣寫呢:

// 項(xiàng)目表
@Entity
@Table(name = "zq_project")
public class Project extends BaseObj {
 /**
 * 項(xiàng)目標(biāo)簽
 */
    @ManyToOne
    @JoinColumn(name = "attach_id")
    private List tagss;
}

//項(xiàng)目標(biāo)簽表
@Entity
@Table(name = "core_data_dict", uniqueConstraints = {@UniqueConstraint(columnNames = {"tenant_id", "code"}, name = "uk_dd_tid_code")})
public class DataDict extends ToString{

  /**
   * 項(xiàng)目
  */
    @ManyToOne
    @JoinColumn(name = "attach_id")
    private List projectList;
    
}

而是這樣書寫方式呢?

 /**
     * 添加項(xiàng)目標(biāo)簽,如果是標(biāo)簽來源于數(shù)據(jù)字典,則可以直接讀取數(shù)據(jù)字典
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @Fetch(FetchMode.SELECT)
    @JoinTable(
            name = "zq_project_tags",
            joinColumns = {@JoinColumn(name = "project_id")},
            inverseJoinColumns = @JoinColumn(name = "tag_code")
    )
    @JSONField(serialize = false)
    private List tagList;

因?yàn)檫@樣書寫,hibernate會(huì)根據(jù)項(xiàng)目和數(shù)據(jù)字典(項(xiàng)目標(biāo)簽放在數(shù)據(jù)字典表中)生成一個(gè)中間表,如圖所示:

為什么不采用第一種方式呢?
1、第一種方式擴(kuò)展性不好,破壞框架結(jié)構(gòu),為什么這么說?

項(xiàng)目標(biāo)簽放置在數(shù)據(jù)字典中,換句話,數(shù)據(jù)字典所存儲(chǔ)的數(shù)據(jù)集不會(huì)經(jīng)常改變。就像我們的新華字典,不會(huì)時(shí)常做版本更新。因而,類似于項(xiàng)目標(biāo)簽,數(shù)值型的單位呀、系統(tǒng)標(biāo)量等,這些數(shù)據(jù)都不會(huì)時(shí)常改變。

而且,現(xiàn)在的項(xiàng)目都采用maven構(gòu)建,什么是maven項(xiàng)目呢?很多博客都有詳細(xì)介紹,我只做簡單地介紹。maven是項(xiàng)目對(duì)象模型(POM),舉一個(gè)簡單的例子,我們在不使用maven創(chuàng)建項(xiàng)目時(shí),往往需要拷貝jar包到項(xiàng)目中。然而,我們使用maven創(chuàng)建項(xiàng)目時(shí),就會(huì)創(chuàng)建一個(gè)pom文件。我們在pomp文件中做配置,如果需要新的jar包,我們直接使用...

  
    com.alibaba
    fastjson
    ${fastjson.version}
  

當(dāng)然,引用jar包是一回事,還有模塊化構(gòu)建項(xiàng)目。我們經(jīng)常分模塊構(gòu)建項(xiàng)目,比如信息發(fā)布一個(gè)模塊,核心層一個(gè)模塊,自定義業(yè)務(wù)層一個(gè)模塊。各個(gè)模塊之間就像是Java一樣,具有繼承和關(guān)聯(lián)關(guān)系。子pom文件可以使用父pom的所有jar包。如圖所示:

層級(jí)非常嚴(yán)格,即便在同一個(gè)項(xiàng)目不同的模塊中,我們?nèi)绻胍{(diào)用另外一個(gè)模塊的類時(shí),也需要用dependency來引用其模塊。比如,我們想要在platform-custom層調(diào)用platform-core層的類,我們需要在platform-custom的pom文件中寫入依賴:

  
    com.zfounder.platform
    platform-core
   

但是,項(xiàng)目表是自定義業(yè)務(wù)范疇的,是在platform-custom模塊中的,而數(shù)據(jù)字典是屬于platform-core模塊的。因?yàn)閜latform-core的pom沒有依賴platform-custom模塊,因而,數(shù)據(jù)字典無法調(diào)用platform-custom模塊中的項(xiàng)目類,如圖所示:

因而,如果我們采用這種方式創(chuàng)建多對(duì)多的關(guān)系,會(huì)破壞maven結(jié)構(gòu)或者框架結(jié)構(gòu)。

2、對(duì)于數(shù)據(jù)庫的維護(hù)性不好。
對(duì)于項(xiàng)目來說,相同項(xiàng)目標(biāo)簽的可能有數(shù)條項(xiàng)目的記錄,但是,每個(gè)項(xiàng)目都是唯一的,一個(gè)項(xiàng)目應(yīng)該有多個(gè)標(biāo)簽,但現(xiàn)在的問題是,同一個(gè)項(xiàng)目的編號(hào)不同了,因?yàn)椴煌捻?xiàng)目標(biāo)簽,這就破壞了數(shù)據(jù)庫的唯一性。

針對(duì)以上兩種情況,我們應(yīng)該使用中間表,來創(chuàng)建多對(duì)多的關(guān)系。如圖所示:

這樣簡潔明快,也便于日后的維護(hù)工作。

哪些是多對(duì)多的關(guān)系

1、用戶和角色之間的關(guān)系,一個(gè)用戶可以有多重角色,一個(gè)角色可以對(duì)應(yīng)多個(gè)用戶。
2、既然說到了角色,自然說到角色所能管理的權(quán)限,比如當(dāng)用戶登錄,根據(jù)用戶的角色,需要展示哪些頁面,可以操作該頁面的哪些按鈕,等等。這些都放在資源表中。如圖所示:


3、項(xiàng)目和圖片的關(guān)系,一個(gè)項(xiàng)目有很多張圖片,但是一張圖片也可以被多個(gè)項(xiàng)目使用。
4、。。。。

中間表一般都涉及兩個(gè)字段,字段分別引用兩張表的主鍵。

多對(duì)多的實(shí)例,以選擇項(xiàng)目標(biāo)簽為例

我們在點(diǎn)擊保存項(xiàng)目標(biāo)簽時(shí),心想我們點(diǎn)擊一次,保存一次,而項(xiàng)目類中項(xiàng)目標(biāo)簽對(duì)象是一個(gè)集合對(duì)象,我們應(yīng)該創(chuàng)建這個(gè)集合,然后拿到前端傳

過來的項(xiàng)目標(biāo)簽的code值(數(shù)據(jù)字典對(duì)應(yīng)的是code值),通過數(shù)據(jù)字典的事務(wù)方法獲取這個(gè)數(shù)據(jù)字典對(duì)象,再判斷該對(duì)象的父類是不是項(xiàng)目標(biāo)簽。因?yàn)閿?shù)據(jù)字典存儲(chǔ)很多類字典,比如項(xiàng)目標(biāo)簽字典、單位字典、系統(tǒng)變量字典等等。然后保存這個(gè)數(shù)據(jù)字典,但結(jié)果事與愿違,它會(huì)覆蓋數(shù)據(jù)庫中原來的數(shù)據(jù),這是更新數(shù)據(jù),而不是保存數(shù)據(jù),如圖所示:

為什么會(huì)這樣,因?yàn)椋涞讓邮褂玫氖莔erge方法,如代碼所示:

 /**
 * @see com.zfounder.platform.core.dao.GenericDao#save(T)
 */
@SuppressWarnings("unchecked")
@Override
public T save(T object) {
    Session session = getSession();
    return (T) session.merge(object);
}

merger如果發(fā)現(xiàn)數(shù)據(jù)庫存在該編號(hào)的對(duì)象,則執(zhí)行update操作;如果不存在,則執(zhí)行insert操作。因而,中間表,即項(xiàng)目標(biāo)簽表,已經(jīng)存在該項(xiàng)目編號(hào)的id,所以,執(zhí)行更新操作。

我們換一種思路,首先看項(xiàng)目類的部分源碼:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "zq_project")
public class Project extends BaseObj {

    /**
     * 項(xiàng)目名稱
     */
    @Column(name = "name")
    private String name;
    
    /**
     * 錄入日期
     */
    @Column(name = "sign_date")
    private Date signDate;

    /**
     * 備注
     */
    @Lob
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "remark", columnDefinition = "mediumtext")
    private String remark;

    /**
     * 預(yù)算金額
     */
    @Column(name = "budgetary_amount", precision = 10, scale = 2)
    private BigDecimal budgetaryAmount;
 
    /**
     * 工程起始時(shí)間
     */
    @Column(name = "start_time")
    private Date startTime;

    /**
     * 工程結(jié)束時(shí)間
     */
    @Column(name = "end_time")
    private Date endTime;

    /**
     * 添加項(xiàng)目標(biāo)簽,如果是標(biāo)簽來源于數(shù)據(jù)字典,則可以直接讀取數(shù)據(jù)字典
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @Fetch(FetchMode.SELECT)
    @JoinTable(
            name = "zq_project_tags",
            joinColumns = {@JoinColumn(name = "project_id")},
            inverseJoinColumns = @JoinColumn(name = "tag_code")
    )
    @JSONField(serialize = false)
    private List tagList;
}

因?yàn)轫?xiàng)目標(biāo)簽時(shí)多對(duì)多的關(guān)系,當(dāng)我們接收到前端傳過來的項(xiàng)目編號(hào),并調(diào)用項(xiàng)目的事務(wù)的get方法,創(chuàng)建當(dāng)前項(xiàng)目瞬時(shí)態(tài)的對(duì)象時(shí)。hibernate根據(jù)項(xiàng)目標(biāo)簽表中的code值,創(chuàng)建項(xiàng)目標(biāo)簽(數(shù)據(jù)字典)的集合對(duì)象,并填充到tagList的集合中。我們只要在對(duì)集合對(duì)象上,添加從前端傳過的code值,并通過code值創(chuàng)建項(xiàng)目標(biāo)簽(數(shù)據(jù)字典)的對(duì)象即可。因而,代碼改成下面的方式:

這樣保存就沒問題了。

結(jié)尾

如果我們掌握了最基本知識(shí)是,就可以很容易掌握其他語言了。加油,致自己。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73636.html

相關(guān)文章

  • 相對(duì)的一對(duì)多多對(duì)一,hibernate傷神

    摘要:一對(duì)多和多對(duì)一一和多的概念通過以上的分析,我們知道一對(duì)多和多對(duì)一的關(guān)系。一對(duì)多和多對(duì)一的理論示例所以,一和多之間,并非絕對(duì)的關(guān)系,只是相對(duì)來說。項(xiàng)目和項(xiàng)目階段也是一對(duì)多和多對(duì)一的關(guān)系。評(píng)論表和用戶文章也是一對(duì)多和多對(duì)一的關(guān)系。 導(dǎo)讀 最近公司在做這樣的一個(gè)業(yè)務(wù),由我來設(shè)計(jì)數(shù)據(jù)庫,其中有有一個(gè)需求,根據(jù)原型圖設(shè)計(jì)數(shù)據(jù)庫,這也是我第一次獨(dú)立設(shè)計(jì)數(shù)據(jù)庫,因涉及公司的機(jī)密,只能展示部分原型圖:...

    tianlai 評(píng)論0 收藏0
  • 慕課網(wǎng)_《Hibernate初探之對(duì)多映射》學(xué)習(xí)總結(jié)

    時(shí)間:2017年07月11日星期二說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:無學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:應(yīng)用場景 1-1 多對(duì)多的應(yīng)用場景 案例分析:企業(yè)項(xiàng)目開發(fā)過程中 一個(gè)項(xiàng)目可由多個(gè)員工參與開發(fā) 一個(gè)員工可同時(shí)參與開發(fā)多個(gè)項(xiàng)目 示意圖 showImg(https://segmentfau...

    caozhijian 評(píng)論0 收藏0
  • Hibernate映射關(guān)系

    摘要:前言首先聲明,這是一篇轉(zhuǎn)發(fā)博客,不屬于原創(chuàng)。關(guān)系映射有下面幾種類型一對(duì)一外鍵關(guān)聯(lián)映射單向一對(duì)一外鍵關(guān)聯(lián),使用,并設(shè)置了級(jí)聯(lián)操作。設(shè)置了外鍵的名稱為數(shù)據(jù)庫字段名,如果不設(shè)置,則默認(rèn)為另一類的屬性名,外鍵的值是唯一的。 前言 首先聲明,這是一篇轉(zhuǎn)發(fā)博客,不屬于原創(chuàng)。但是感覺很有用,所以在本人的博客中記錄下來。 Hibernate Annotation關(guān)系映射有下面幾種類型: 一對(duì)一...

    gougoujiang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

zzzmh

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<