hibernate主鍵生成策略
使用mySql生成聯合主鍵需要注意的地方:
生成聯合主鍵的各個列不可以為空,首先要設定好,也不可以有一個為主鍵,
因為主鍵只有一個,如果聯合主鍵其中的一個為主鍵的話,那麼就沒有必要再去
生成聯合主鍵了.
使用聯合主鍵的時候要注意:聯合主鍵需要實現serializable介面,實現了這個介面後還最好要重寫
equals和toString()方法,這兩個方法如果不寫的話,剛開始是看不到錯誤的,但是等你開始真正的執行的時候就會報錯了.
應該是任何的資料庫的主鍵生成策略都是一樣的.
在改造系統自動生成的聯合主鍵的過程中注意修改好:
比如系統自動生成的是:
<composite-id name="id" class="com.dada.foreign.TwoId">
<key-property name="id" type="java.lang.Integer">
<column name="id" />
</key-property>
<key-property name="name" type="java.lang.String">
<column name="name" length="20" />
</key-property>
</composite-id>
如果想自己改造一下這個實體,讓它只是需要一個類就可以,這種情況下
要這樣來修改:
<composite-id>
<key-property name="id" type="java.lang.Integer">
<column name="id" />
</key-property>
<key-property name="name" type="java.lang.String">
<column name="name" length="20" />
</key-property>
</composite-id>
就是隻是需要把composite標籤裡面的屬性給刪除掉就好了,然後再修改
系統自動生成的實體類,這個時候需要把包含在那個生成聯合逐漸的實體
類中的屬性都放入到生成實體的主體類當中,而且需要提供每個屬性的
get和set方法,之後再新增一個只是包含了聯合主鍵的構造方法就可以了.
然後再把沒有用的屬性都給刪除掉,在對實體進行操作的時候,記住要首先
使用構造方法生成主鍵,然後再執行其他的操作.
聯合主鍵是需要生成這個主鍵的hashCode和equals方法的
public class TwoId implements java.io.Serializable {
// Fields
private Integer id;
private String name;
getter and setters
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof TwoId))
return false;
TwoId castOther = (TwoId) other;
return ((this.getId() == castOther.getId()) || (this.getId() != null
&& castOther.getId() != null && this.getId().equals(
castOther.getId())))
&& ((this.getName() == castOther.getName()) || (this.getName() != null
&& castOther.getName() != null && this.getName()
.equals(castOther.getName())));
}
public int hashCode() {
int result = 17;
result = 37 * result + (getId() == null ? 0 : this.getId().hashCode());
result = 37 * result
+ (getName() == null ? 0 : this.getName().hashCode());
return result;
}
}
--------------------------------------------------------------------------------------------------
使用annotation生成聯合主鍵
1.把提供主鍵的類設定為@Embeddable表明這個類可以作為一個嵌入的類,然後在需要此類的地方進行引用時為這個
元件的引用加上@Id註解就可以了.
2.將元件的屬性設定為Embeddable,就是說這個元件類本身是不帶有註解的,但是對它進行引用的實體就需要在使用
它的時候對他加上Embedded這個註解
3.將實體類設定為IdClass,然後把實體中所有屬於主鍵的屬性給標註為@Id就行了.
三種方式的使用情況,第一種的使用情況是非常少的,因為第二種就可以直接的比它少了一步,第二種方式是最常用的,
第三種也有用的,但是用的少,為什麼呢?
這個是因為如果使用了聯合主鍵之後,自己總還是需要從資料庫中去讀取東西的,這個時候呢就有必要把它給讀出來,
怎麼讀呢?使用物件導向的方法就需要提供主鍵的物件,這個時候就需要使用到它了.
--------------------------------------------------------------------------------------------------
一對一單相外來鍵關聯
這種情況就會導致的是在此表中會多生成一個欄位那就是wife_id是作為這個表的一個外來鍵.
如果要指定生成的外來鍵欄位就需要這樣設定:
@OneToOne
@JoinColumn(name="wifeId")
private Wife1 wife;
@Entity
public class Husband1 {
@Id
@GeneratedValue
private Integer id;
private String name;
@OneToOne
private Wife1 wife;
public Wife1 getWife() {
return wife;
}
}
當然雙向關聯就容易了,只需要在wife實體中也持有一個對Husband的引用就可以了.
但是又這樣的一個需求,就是,需要設定雙向的關聯,但是實際上只需要在自己或者對方
設定一個引用就可以了,就是說,兩個表雖然是雙向的關聯,但是並不需要設定兩個外來鍵
這樣設定是多餘的,這種情況下應該怎麼弄呢?
這個時候應該在不需要設定外來鍵的一方中設定好mappedBy就好了,如下
@OneToOne(mappedBy="wife")
private Husband1 husband1;
其中mappedBy的意思是這個外來鍵關係是由對方來主導的,使用的是對方的wife屬性來主導的.
這樣設定之後就可以達到使用一個外來鍵而得到雙向關聯的目的了.
在xml中這種雙向關聯,只生成一個外來鍵的設定方式是:
<one-to-one name="wife" property-ref="student">
同樣的,這裡的student也是對方實體裡面的一個引用.
只要有雙向關聯必然需要設定mapped
如果是設定為一對一的主鍵關聯的話,就把
@JoinColumn(name="wifeId")
修改為
@PrimaryKeyJoinColumn
--------------------------------------------------------------------------------------------------
多對多單向關聯
單向關聯只需要在一方設定好關聯關係就好了,另外的一方不要設定的.
@Entity
public class Student {
@Id
private int id;
private String name;
@ManyToMany
private Set<Teacher> teachers = new HashSet<Teacher>();
}
注意在這個地方設定@ManyToMany的mappedBy屬性是沒有用的,因為
它根本不需要生成外來鍵,而是生成一箇中間表,這個時候如果想要指定
生成的中間表的名稱和中間表中的欄位的名字的話,就需要設定:
@JoinTable(
name="t_s",//指明中間表的名字
joinColumns={@JoinColumn(name="stu_id")},//指明本實體
//的主鍵在中間表中的外來鍵的名字
inverseJoinColumns={@JoinColumn(name="tea_id")}
//指明另外一方實體在中間表中的外來鍵的名字.
)
在xml配置中中間表的名稱是在類的hbm的<set>標籤中配置的.
---------------------------------------------------------------------------------------------------------------------------------------------------
Hibernate更新指定的欄位
1需求,有一個表裡面記錄的是學生的姓名,學號和他的愛好論文這個時候如果這個表需要更新,
那麼在hibernate中預設的更新是把所有的欄位全部都更新一遍,因此就會出現在更新一個人的
愛好的時候卻需要把論文也更新的情況,這種情況很顯然很耗資源也沒有必要,這個時候可以這樣
配置
在對應的論文欄位上加上註解@Colum(updatable=false);
或者在對應的xml的配置檔案中配置一下<property>標籤的update屬性也是可以的.
但是上面的這兩種方式都太不靈活了,因此需要使用第三種方式就是在xml中配置
<hibernate-mapping>
<class catalog="shopping" name="com.dada.entities.Notebook" table="notebook" dynamic-update="true">
這個時候呢就是dynamic-update="true"這句話起作用了,它可以動態的去修改.
不過這種動態的改變有個限制就是隻能夠在xml檔案中去配置,而不可以在annotation中去配置,所以
如果需要使用動態的改變的話,就使用xml去配置這個檔案就好了.
當然如果不想使用這種動態的配置的話,也可以使用類似於sql的hql語句來實現對特定的一個欄位進行修改.
但是即便是動態的修改它還是有條件的,條件就是動態修改的條件,如何才能知道哪些屬性改變了呢?
肯定是拿現在的屬性跟資料庫的屬性進行了比較了,那怎麼跟資料庫裡面的資料進行比較呢?
那肯定是把資料庫裡面的東西給load進入記憶體裡面了,這樣才能對修改後的內容跟修改之前的內容進行比較
所以就是執行動態代理的條件就是,被執行動態代理的物件是持久化的也就是被load或者get進入記憶體的.
但是有的時候會出現這種需求就是跨session去修改資料庫,這個時候應該使用的是merge()它的意思是合併
這個在hibernate中實現的細節是:先從資料庫中去load這個物件,之後再把要合併的東西跟資料庫裡面的進行
對比,然後再去修改到資料庫裡面.
clear()清空快取內容;
flush:強制快取內容與資料庫同步;
比如
p.setName("a");
p.setName("aa");
session.save(p);
這個時候hibernate中會生成一條語句這個時候只是執行最後一次的更新.
如果使用的是
p.setName("a");
session.flush();
p.setName("aa");
session.save(p);
session.flush();
這句話會產生這樣的效果:
1.hibernate會向資料庫傳送兩條語句,一條是執行第一個更改
2.執行第二次更改
如果把session.flush();換成為session.clear();
那麼結果就是記憶體被清空,然後呢持久化的物件都沒有了這個時候,當然就談不上是更改了.
當然在執行commit();方法的時候,系統就會預設的實現flush();這個方法的.
相關文章
- Hibernate 主鍵的生成策略
- Hibernate框架的主鍵生成策略框架
- Java Hibernate 主鍵生成10大策略Java
- Hibernate主鍵策略
- 轉JPA實體註解與hibernate主鍵生成策略
- 資料庫主鍵 ID 生成策略資料庫
- Hibernate 自定義主鍵
- java主鍵生成Java
- 分散式主鍵生成分散式
- Kudu主鍵選擇策略
- Mybatis-Plus3.0預設主鍵策略導致自動生成19位長度主鍵id的坑MyBatisS3
- Hibernate自定義產生主鍵方式
- 操作hibernate多主鍵的問題?
- 操作hibernate多主鍵的問題?(2)
- hibernate複合主鍵查詢問題
- 請教Hibernate的多主鍵操作如何實現?
- HIBERNATE的自定義型別主鍵的對映??型別
- Laravel 中使用 Redis 生成自增主鍵LaravelRedis
- cqrs架構下的主鍵如何生成架構
- hibernate 關係對映之 主鍵關聯一對一
- 【mybatis-plus】主鍵id生成、欄位自動填充MyBatis
- Mysql分庫分表的主鍵生成演算法MySql演算法
- Hibernate的查詢方式與策略
- Hibernate之自動生成工具
- 生成按時間增長的全域性唯一主鍵
- MySQL 資料庫自增主鍵生成的優缺點MySql資料庫
- 主鍵與主鍵索引的關係索引
- [求助]Hibernate自增長主鍵的設定問題和事務問題
- 關於資料庫表記錄主鍵生成的問題?資料庫
- ID生成策略——SnowFlake
- Oracle主鍵Oracle
- 主鍵命名
- Oracle主鍵與複合主鍵的效能分析Oracle
- Hibernate效能優化策略 (網上找的)優化
- 主鍵、自增主鍵、主鍵索引、唯一索引概念區別與效能區別索引
- hibernate的hbm檔案生成問題
- eclipse 配置hibernate自動生成工具Eclipse
- Hibernate識別符號生成器符號