淺談Hibernate中對映集合屬性以及主鍵和外來鍵
首先說明一下什麼叫主鍵以及外來鍵。
主鍵和外來鍵是對於資料庫來說的,資料庫的表才有主鍵外來鍵的說法。
主鍵:主鍵是指標識某個表中唯一且非空的一條記錄行的列,這個列中的值不允許有重複的值,用於確定一個表中的一條記錄,實
際上主鍵就是告訴別人:這個資料列是唯一的。
外來鍵:引用另外一個表中的主鍵,在當前表中不一定為唯一的,但是在被引用表中一般唯一。對於關係型資料庫來說(比如MySQL)
外來鍵是聯絡資料表之間的唯一方式,主要目的是控制儲存在外來鍵表中的資料。
建立外來鍵的前提:本表的列必須與外來鍵型別相同(外來鍵必須是外表主鍵)。
例如:
表1:使用者編號(主鍵) 使用者名稱稱 部門編號(外來鍵)
表2:部門編號(主鍵) 部門名稱
這裡來講:對於表1來說,使用者編號是主鍵,對於表2來講部門編號是主鍵,然後表1引用表2的主鍵作為外來鍵,表2為主表,表1為從表,這樣就將兩個資料表關聯起來了,表一中每個部門編號表二都會有個部門名稱相對應。
下面開始對映集合屬性:
因為關於Hibernate中對映List、Array、Set、以及Map的方式相差不大,此處僅拿對映List展開,其他稍作介紹。
Hibernate對映List集合
1:PersonList.java
Person類中除了普通屬性外,還有一個List集合屬性:schools,該屬性對應多個學校。
package com.mao;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.*;
@Entity
@Table(name="personList_inf")
public class PersonList {
//分別指定主鍵、主鍵列名、主鍵為自增
@Id
@Column(name="person_id",nullable=false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column (name="person_name",length=50)
private String name;
@Lob
@Basic(fetch=FetchType.LAZY)
private byte[]pic;
//通過@Temporal註解 可以完成持久化屬性對映到資料庫的時間格式
@Temporal(TemporalType.DATE)
private Date birth;
//如果集合通過泛型指定了型別 則可以不通過targetClass指定型別
@ElementCollection(targetClass=String.class)
//指定儲存集合的資料表 並指定外來鍵列
@CollectionTable(name="schools_inf", [email protected] (name="person_id",nullable=false))
//指定儲存集合元素的列為:school_name
@Column (name="school_name")
//對映集合元素的索引的列
@OrderColumn(name="list_order")
private List<String> school=new ArrayList<>();
//省略相應的set、get方法
}
2:主程式 PersonManagerList.java
package com.mao; import java.io.File; import java.io.FileInputStream; import java.util.Date; import org.hibernate.*; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; public class PersonManagerList { public static void main(String[]args) throws Exception{ Configuration cof=new Configuration().configure(); ServiceRegistryBuilder serviceRegistryBuilder=new ServiceRegistryBuilder().applySettings(cof.getProperties()); ServiceRegistry registry=serviceRegistryBuilder.buildServiceRegistry(); SessionFactory sf=cof.buildSessionFactory(registry); Session sess=sf.openSession(); Transaction tx=sess.beginTransaction(); PersonList person=new PersonList(); person.setName("VipMao"); //建立檔案 上傳圖片到資料庫 File file=new File("image/2.jpg"); byte[]content=new byte[(int) file.length()]; //建立讀取資料流來讀取圖片物件file並存入位元組陣列content new FileInputStream(file).read(content); person.setPic(content); person.setBirth(new Date()); person.getSchool().add("菜鳥學院"); //儲存資訊並將物件持久化 sess.save(person); //提交事務 tx.commit(); sess.close(); sf.close(); } }
3:配置檔案 hibernate.cfg.xml(後面配置檔案不在列出)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.characterEncoding">utf-8</property>
<!-- 指定連線池最大連線數 -->
<property name="hibernate.c3p0.max_size">20</property>
<!-- 指定連線池最小連線數 -->
<property name="hibernate.c3p0.min_size">1</property>
<!-- 指定連線池裡連線超時時長 -->
<property name="hibernate.c3p0.timeout">5000</property>
<!-- 指定連線池裡做大快取多少個Statement物件 -->
<property name="hibernate.c3p0.max_statements">50</property>
<!-- 是否根據需要自動建表 -->
<property name="hbm2ddl.auto">update</property>
<!-- 是否顯示sql語句 -->
<property name="show_sql">true</property>
<!-- 將SQL指令碼進行格式化後再輸出 -->
<property name="hibernate.format_sql">true</property>
<!-- 設定連線資料庫所使用的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 羅列所有持久化類名 -->
<!--
<mapping class="com.mao.Person"/>
<mapping class="com.mao.PersonMap"/>
<mapping class="com.mao.PersonArray"/>
<mapping class="com.mao.PersonSet"/>
-->
<mapping class="com.mao.PersonList"/>
</session-factory>
</hibernate-configuration><span style="font-size:14px;">
</span>
4:執行結果
從控制檯輸出的SQL語句可以看出,先在personList_inf表中插入了普通屬性,然後通過外來鍵列在schools_inf表中插入集合資訊,下面資料庫結果:
這樣person_id是表一的主鍵 ,然後表二把表一的主鍵作為外來鍵,這樣兩個表就通過person_id聯絡起來了。
5:對映集合常用的註解
@ElementCollection:用於對映集合屬性
@CollectionTable:用於對映集合屬性表,name屬性指定儲存集合屬性表的表名,joinColumns屬性對映外來鍵列
@Column:用於對映儲存集合元素的資料列
@OrderColumn:用於對映集合的索引列,像Set這種無序集合可以不用此註解
Hibernate對映Array集合
1:PersonArray.java(只給出集合部分變動)
@ElementCollection(targetClass=String.class)
@CollectionTable(name="arraySchool_inf" ,[email protected](name="id",nullable=false))
//指定儲存集合元素的列為school_name
@Column(name="school_name")
//對映集合元素的索引
@OrderColumn(name="array_order")
private String[]school;
2:PersonManagerArray.java
PersonArray person=new PersonArray();
person.setName("VipMao");
File file=new File("image/2.jpg");
byte[]content=new byte[(int) file.length()];
//建立讀取資料流來讀取圖片物件file並存入位元組陣列content
new FileInputStream(file).read(content);
person.setPic(content);
person.setBirth(new Date());
System.out.println("日期為:"+new Date());
String[]school=new String[3];
school[0]="菜鳥學院";
school[1]="小牛學院";
school[2]="大牛學院";
person.setSchool(school);
sess.save(person);
3:執行結果
Hibernate對映Set集合
1:PersonSet.java
@ElementCollection
@CollectionTable(name="schoolSet_inf" , [email protected](name="person_id",nullable=false))
@Column(name="school_name",nullable=false)
private Set<String>schools=new HashSet<>();
2:PersonManagerSet.java
PersonSet person=new PersonSet();
person.setName("VipMao");
person.setAge("24");
person.getSchools().add("菜鳥學院");
person.getSchools().add("小牛學院");
person.getSchools().add("大牛學院");
sess.save(person);
3:執行結果
可以看出,因為Set集合的無序性,我們並沒有通過@OrderColumn對映集合的索引列。
Hibernate對映Map集合
1:PersonMap.java
@ElementCollection(targetClass=Float.class)
@CollectionTable(name="score_inf",[email protected](name="person_id",nullable=false))
//對映儲存Map key的資料列
@MapKeyColumn(name="subject_name")
//指定Map key的型別為String型別
@MapKeyClass(String.class)
//對映儲存 Map value的資料列
@Column(name="mark")
private Map<String,Float>scores=new HashMap<>();
2:PersonManagerMap.java
PersonMap person = new PersonMap();
person.setAge("24");
person.setName("VipMao");
// 向person的Map集合屬性中新增key-value對
person.getScores().put("語文" , 90f);
person.getScores().put("英文" , 99f);
session.save(person);
3:執行結果
最後說一下各集合的聯合主鍵問題:
List聯合主鍵:持久化外來鍵列+集合元素索引列
Set聯合主鍵:持久化外來鍵列+Set元素列(元素列不能為空)
Map聯合主鍵:持久化外來鍵列+集合Key列
相關推薦
淺談Hibernate中對映集合屬性以及主鍵和外來鍵
首先說明一下什麼叫主鍵以及外來鍵。 主鍵和外來鍵是對於資料庫來說的,資料庫的表才有主鍵外來鍵的說法。 主鍵:主鍵是指標識某個表中唯一且非空的一條記錄行的列,這個列中的值不允許有重複的值,用於確定一個表中的一條記錄,實 際上主鍵就是告訴別人:這個資料列是唯一的。 外來
淺談CSS中margin的屬性及使用方法
想修改一下子自己的CSS,因為部落格標題正好把網頁圖片上的文字正好檔了一部分,看起來很不爽。最後確實是由“margin命令”來控制的,於是上網學習了一下子這個的用法。margin在中文中我們翻譯成外邊距或者外補白(本文中引用外邊距)。他是元素盒模型(box model)的基礎
淺談CSS3中的部分屬性——flex佈局
display:Flex 簡介: flex是Flexible Box的縮寫,即“彈性佈局” 設定display:flex;屬性後,子元素的float,clear和vertical-align屬性將不再起作用 此屬性既適用於塊級元素也適用於行內元素 概念
淺談Python中的 property屬性
1.什麼是property屬性 一種用起來像是使用的例項屬性一樣的特殊屬性,可以對應於某個方法 class Foo: def func(self): pass # 定義property屬性 @property
淺談JS中的!=、== 、!==、===的用法和區別 JS中Null與Undefined的區別 讀取XML文件 獲取路徑的方式 C#中Cookie,Session,Application的用法與區別? c#反射 抽象工廠
main 收集 data- 時間設置 oba ase pdo 簡單工廠模式 1.0 var num = 1; var str = ‘1‘; var test = 1; test == num //true 相同類型 相同值 te
MySQL資料庫中主鍵和外來鍵的操作
在MySQL資料庫中,一般會涉及到主鍵和外來鍵,在上一個表中添加了主鍵之後,通常在下一個表中要新增外來鍵,但是添加了外來鍵之後,在實體類和資料庫中在加上上一個表的主鍵會比較好,這樣兩個表關聯之後,在上一個表查詢完成之後,將查詢是出來的欄位拿著去下一個庫裡查詢,會比較好。 select * fro
SQL SERVER 主鍵和外來鍵中的 級聯刪除(ON DELETE CASCADE)和級聯更新(ON UPDATE CASCADE)
建立學生表 create table gh_student( stuno varchar(3) primary key, stuname varchar(4), stuclass varchar(3) ) 插入資料 insert into gh_student values
淺談JavaEE中的Hibernate中的四種關係對映(三)
今天我們一起來探討一下有關Hibernate四種關係對映,大家可能會有疑惑,關係對映不就是隻有三種(一對一,一對多,多對多)嗎?這裡我們再多說一個繼承對映關係,雖然它使用頻繁度沒有前三個那麼多,但是它在一些特定情況下,還是非常有用的,至於有什麼用下面馬上就要講。
淺談spring中AOP以及spring中AOP的註解方式
早就 好的 面向 XML ram ati alt 返回 增強 AOP(Aspect Oriented Programming):AOP的專業術語是"面向切面編程" 什麽是面向切面編程,我的理解就是:在不修改源代碼的情況下增強功能.好了,下面在講述aop註解方式的情況下順
淺談CSS3中display屬性的Flex布局
center mil 界面 content ear contain star ever 之前 最近在學習微信小程序,在設計首頁布局的時候,新認識了一種布局方式display:flex 1 .container { 2 display: flex; 3 flex-
淺談angularJS中src與ng-src屬性的區別
圖片初始化報錯404的異常 瀏覽器解析html的順序: 1) 瀏覽器載入靜態HTML檔案並解析為DOM; 2) 瀏覽器載入angular.js檔案; 3) angular監聽 DOMContentLoaded 事件,監聽到時開始啟動; 4) angular尋找ng-app指令,確定作用範圍;
淺談vue中style的scoped屬性(修改特定Element元件樣式的方法)
在單頁.vue檔案中,為了保證各元件間的css樣式不衝突,很可能會使用到區域性css,也就是給<style>標籤加上一個scoped屬性(當然也可以用各種命名規則來規避這個問題)。 一開始用的時候感覺很神奇,於是看程式碼查資料瞭解了一下原理。 所謂的區域性css,就是通過vue-lo
淺談sql中的in與not in,exists與not exists的區別以及效能分析
1、in和exists in是把外表和內表作hash連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢,一直以來認為exists比in效率高的說法是不準確的。如果查詢的兩個表大小相當,那麼用in和exists差別不大;如果兩個表中一個較小一個較大,則子查詢表大的用exists,子查
淺談HTTP中GET、POST用法以及它們的區別
HTTP定義了與伺服器互動的不同方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE。URL全稱是資源描述符。我們可以這樣認為: 一個URL地址,它用於描述一個網路上的資源,而HTTP中的GET,POST,PUT,DELETE就對應著對這個資源
淺談Android中的 Fragment、生命週期回撥方法 以及使用
4onActivityCreated() 當Activity中的onCreate方法執行完後呼叫。 注意了:從這句官方的話可以看出:當執行onActivityCreated()的時候 activity的onCreate才剛完成。所以在onActivityCrea
淺談iOS 中 nil、Nil、null以及NSNull的區別
以下程式碼是直接在工程中驗證的,所以可以直接貼上到工程中檢視執行結果。 關於null的用法還不是太明確,歡迎交流。 //******************nil Nil null NSNull************** NSDictionary
Hibernate框架基礎——對映集合屬性
集合對映 集合屬性大致有兩種: 單純的集合屬性,如像List、Set或陣列等集合屬性。 Map結構的集合屬性,每個屬性值都有對應的Key對映。 集合對映的元素大致有如下幾種: list:用於對映List集合屬性。 set:用於對映Set集合屬性。
淺談Java中的hashCode方法
implement state ask get() 存在 rsa key 沖突 如何 哈希表這個數據結構想必大多數人都不陌生,而且在很多地方都會利用到hash表來提高查找效率。在Java的Object類中有一個方法: public native int hashCode(
【SSH 基礎】淺談Hibernate關系映射(3)
區別 ack 增加 ans 存儲結構 mil pro 映射 方向 繼上篇博客 一對多關聯映射(單向) 上面我們介紹了多對一,我們反過來看一對多不就是多對一嗎?那還用再進行不同的映射嗎?有什麽區別嗎?一對多和多對一映射原理是一致的,存儲是同樣的。也就是生成的數據庫
A1—淺談JavaScript中的原型(二)
js原型是什麽?想要了解這個問題,我們就必須要知道對象。對象根據w3cschool上的介紹:對象只是帶有屬性和方法的特殊數據類型。我們知道,數組是用來描述數據的。其實呢,對象也是用來描述數據的。只不過有一點點的區別,那就是數組的下標只能是數字。所以,數組最好只用來裝同樣意義的內容。比如說[1,2,3,4,5]