hibernate關聯對象的增刪改查------增,hibernate------

來源:互聯網
上載者:User

hibernate關聯對象的增刪改查------增,hibernate------
本文可作為,北京尚學堂馬士兵hibernate課程的學習筆記。
這一節,我們看看hibernate關聯關係的增刪改查
就關聯關係而已,咱們在上一節已經提了很多了,一對多,多對一,單向,雙向...

其實咱們可以簡單的說就是A與B,有關係。


至於他們到底是一對多,多對一,暫且不論。

咱們要討論的是,如果我儲存A,那麼資料庫裡是否會有B;如果我刪除A,那麼與之相關的B是否也會刪除;如果我更新了A,那麼B是否會被更新;如果我查詢出A,那麼B是否也會被查詢出來。
首先,咱們看一對多,多對一雙向的例子。
還是我們上一節的例子,dream與person。
一個person有多個dream,而每一個dream只能屬於一個person。
我們在配置xml時,讓hibernate自動產生建表語句,並且每次都新生資料庫。
<property name="hbm2ddl.auto">create</property>
實體類情況
@Entitypublic class Person {    private int id;    private String name;    private Set<Dream> dreams=new HashSet<>();        @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(name ="myname")    public String getName() {        return name;    }        @OneToMany(mappedBy="person")    public Set<Dream> getDreams() {        return dreams;    }//省略部分代碼}@Entitypublic class Dream {    private int id;    private String description;        private Person person;        @Id    @GeneratedValue    public int getId() {        return id;    }    @ManyToOne    @JoinColumn(name="personId")    public Person getPerson() {        return person;    }  //省略部分代碼}




OK,兩個類的關係已經很清楚了,雙向多對一/一對多。
如果我們的測試代碼如下:
//代碼片1
public static void main(String[] args) {        Person p=new Person();        p.setName("dlf");                Dream d=new Dream();        d.setDescription("marry glt");        d.setPerson(p);        SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();        Session session = sessionFactory.getCurrentSession();        session.beginTransaction();                session.save(p);        session.save(d);        session.getTransaction().commit();            }


上面的代碼是沒有問題的,而且即使先save dream也OK。
那麼現在問題來了
d.setPerson(p);
這句代碼,已經說明了dream裡有一個引用指向了person。
那麼我可以在代碼層次不save person麼?
即只有一個
session.save(d);
答案是否定的,報下面的錯誤。
object references an unsaved transient instance - save the transient instance before flushing: com.bjsxt.hibernate.Person
因為在資料庫儲存dream的時候,person還沒有儲存,所以出錯了。
上面的例子告訴我們,預設情況下:hibernate不會替我們儲存"一"的那一方。
當我寫到這塊的時候,我忽然腦子一抽,又寫下了下面的測試代碼:
//代碼片2public static void main(String[] args) {        Dream d=new Dream();        d.setDescription("marry glt");                Person p=new Person();        p.setName("dlf");        p.getDreams().add(d);        SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();        Session session = sessionFactory.getCurrentSession();        session.beginTransaction();                session.save(p);        session.getTransaction().commit();            }
如果,我以"一"的那一方為主,上面的代碼會是個什麼情況?
答案是,不報錯,代碼能正常執行,但是資料庫裡只有p的資訊而沒有d的資訊。
上面的代碼確實有點奇葩了,在上一節的時候,我們就已經達成了共識,在處理關聯關係時,資料庫層面總是在多的那一方維護關係。
所以上面的代碼,並不能儲存dream。

上面也說了,是在預設情況下,那特殊情況呢?

我們看api文檔




上面是manytoone這個元標籤可以帶的屬性,cascade翻譯成中文就是級聯。他是caschdetype型的
而Caschdetype是enum型的。可以取六個值
我們最經常用的就是,all,persist與remove。
all的意思是,對這個對象的增刪改四中操作都會影響到與之關聯的那個對象。(關於查詢的級聯,由另一個屬性管理)
persist的意思是,對這個對象的增加(save操作)會連帶把與之關聯的那個對象也sava了。
remove的意思就是,如果刪除這個對象也會刪除與之關聯的那個對象。
OK看下面的改動
    @ManyToOne(cascade={CascadeType.ALL})    @JoinColumn(name="personId")    public Person getPerson() {        return person;    }
此時,我們下面的代碼,就能正常運行了,而且資料庫裡,兩個對象都儲存了,且外部索引鍵關聯也是OK的。
        //代碼片3        Person p=new Person();        p.setName("dlf");                Dream d=new Dream();        d.setDescription("marry glt");        d.setPerson(p);            session.save(d);


寫到這,我的腦子又抽了,如果我給onetomany的那一方加上cascade會如何?
    @OneToMany(mappedBy="person",cascade={CascadeType.ALL})    public Set<Dream> getDreams() {        return dreams;    }    測試代碼:        Dream d=new Dream();        d.setDescription("marry glt");                Person p=new Person();        p.setName("dlf");        p.getDreams().add(d);                session.save(p);

cascade確實有用,此時資料庫裡已經有了dream,但是dream的外鍵是null。
為什麼?因為dream裡並沒有關聯person。
其實,cascade這個東西也不是絕對的,如果關聯關係比較麻煩,我們探索資料庫裡總是少存了一個對象,那就按照代碼1的辦法,直接存兩次對象不就OK了。

談點規律:
1 我們發現如果儲存物件的時候,我們從多的一方操作是比較簡單的。所以以後,盡量在多的一方操作。
2 為了符合邏輯,同時也不出錯,一點兩個對象之間的關係是雙向的,那麼在代碼層次,就把兩個的引用都設好,這樣就不會出問題了。
3 之前說的,如果是雙向的,設定mappedby。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.