1. 程式人生 > >淺談Hibernate中對映集合屬性以及主鍵和外來鍵

淺談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對映集合屬性以及外來

首先說明一下什麼叫主鍵以及外來鍵。 主鍵和外來鍵是對於資料庫來說的,資料庫的表才有主鍵外來鍵的說法。 主鍵:主鍵是指標識某個表中唯一且非空的一條記錄行的列,這個列中的值不允許有重複的值,用於確定一個表中的一條記錄,實     際上主鍵就是告訴別人:這個資料列是唯一的。 外來

CSSmargin的屬性及使用方法

想修改一下子自己的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的!=、== 、!==、===的用法區別 JSNull與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

JavaEEHibernate的四種關係對映(三)

      今天我們一起來探討一下有關Hibernate四種關係對映,大家可能會有疑惑,關係對映不就是隻有三種(一對一,一對多,多對多)嗎?這裡我們再多說一個繼承對映關係,雖然它使用頻繁度沒有前三個那麼多,但是它在一些特定情況下,還是非常有用的,至於有什麼用下面馬上就要講。

springAOP以及springAOP的註解方式

早就 好的 面向 XML ram ati alt 返回 增強   AOP(Aspect Oriented Programming):AOP的專業術語是"面向切面編程" 什麽是面向切面編程,我的理解就是:在不修改源代碼的情況下增強功能.好了,下面在講述aop註解方式的情況下順

CSS3display屬性的Flex布局

center mil 界面 content ear contain star ever 之前 最近在學習微信小程序,在設計首頁布局的時候,新認識了一種布局方式display:flex 1 .container { 2 display: flex; 3 flex-

angularJSsrc與ng-src屬性的區別

圖片初始化報錯404的異常 瀏覽器解析html的順序: 1) 瀏覽器載入靜態HTML檔案並解析為DOM; 2) 瀏覽器載入angular.js檔案; 3) angular監聽 DOMContentLoaded 事件,監聽到時開始啟動; 4) angular尋找ng-app指令,確定作用範圍;

vuestyle的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,子查

HTTPGET、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]