編輯:關於Android編程
喜歡把所有的代碼都寫在一個類裡的程序員肯定是個新手。沒錯,任何一個像樣的程序都不可能僅僅只有一個類的,同樣地,任何一個像樣的數據庫也不可能僅僅只有一張表。我們都知道,在面向對象的編程語言中,多個類之間可以相互關聯引用,共同完成某項功能。那麼在數據庫當中,多個表之間可以相互關聯嗎?當然可以!只不過表與表之間的關聯關系要比對象之間的關聯關系復雜一些,也更加難懂,但是作為數據庫的基本功,還是應該了解清楚的,那麼我們就先來學習一下數據庫表關聯的基礎知識。
表與表之間的關聯關系一共有三種類型,一對一、多對一、和多對多,下面我們分別對這三種類型展開進行討論。
表示兩個表中的數據必須是一一對應的關系。這種場景其實並不是很常見,我們還是通過例子來直觀地體會一下,例子仍然是在之前文章的基礎上展開的。
現在我們已經創建好了news這張表,裡面主要記錄了新聞的標題和內容,那麼除了標題和內容之外,有些新聞還可能帶有一些導語和摘要,我們把這兩個字段放在一張introduction表中,作為新聞的簡介。那麼很顯然,news表和introduction表就是一對一的關系了,因為一條新聞只能對應一個簡介,一個簡介也只能屬於一條新聞。它們之間的對應關系大概如下圖描述的一樣:
可以看到,News1對應了Introduction2,News2對應了Introduction3,News3對應了Introduction1,但不管怎麼樣,它們都是一對一的關系。
那麼這種一對一的關系,在編程語言中該怎麼體現出來呢?相信熟悉面向對象設計的你,一定很輕松就能想出來吧,只需要在News類中持有一個Introduction類的引用,然後在Introduction類中也持有一個News類的引用,這樣它們之間自然就是一對一的關系了。
沒錯,對象之間的一對一關系非常簡單易懂,那麼難點就在於,如何在數據庫表中建立這樣的一對一關系了。由於數據庫並不像面向對象的語言一樣支持相互引用,如果想讓兩張表之間建立一對一的關系,一般就只能通過外鍵的方式來實現了。因此,一對一關系的表結構就可以這樣設計:
請注意,introduction表中有一個news_id列,這是一個外鍵列,裡面應該存放一個具體的新聞id,這樣一條introduction就能對應一條news,也就實現一對一的關系了,如下圖所示:
由此我們就能夠看出,id為1的introduction對應著id為2的news,id為2的introduction對應著id為3的news,id為3的introduction對應著id為1的news。需要注意的是,一對一的關系並沒有強制要求外鍵必須加在哪一張表上,你可以在introduction表中加一個news_id作為外鍵,也可以在news表中加一個introduction_id作為外鍵,不管使用哪一種,都可以表示出它們是一對一的關聯關系。
表示一張表中的數據可以對應另一張表中的多條數據。這種場景比起一對一關系就要常見太多了,在我們平時的開發工作中多對一關系真的是比比皆是。比如說現在我們的數據庫中有一個news表,還有一個comment表,它們兩個之間就是典型的多對一關系,一條新聞可以有很多條評論,但是一條評論只能是屬於一條新聞的。它們的關系如下圖所示:
而這種多對一的關系在編程語言中是非常容易體現出來的,比如Java中就有專門集合類,如List、Set等,使用它們的話就能輕松簡單地在對象之間建立多對一的關系,我們稍後就會看到。那麼,這裡的難點仍然是在數據庫表中如何建立這樣的多對一關系。現在說難點其實已經不難了,因為前面我們已經學會了一對一關系的建立方法,而多對一也是類似的。沒錯,數據庫表中多對一的關系仍然是通過外鍵來建立的,只不過一對一的時候外鍵加在哪一張表上都可以,但多對一的時候關鍵必須要加在多方的表中。因此,多對一關系的表結構就可以這樣設計:
在comment表中有一個news_id列,這是一個外鍵列,裡面應該存放一個具體的新聞id,並且允許多條comment都存放同一個新聞id,這樣一條評論就只能對應一條新聞,但一條新聞卻可以有多條評論,也就實現多對一的關系了,如下圖所示:
由此我們就可以看出,id為1、2、3的三條評論是屬於第一條新聞的,而id為4、5的兩條評論是屬於第二條新聞的。
表示兩張關聯表中的數據都可以對應另一張表中的多條數據。這種場景也不算是很常見,但比一對一關系要稍微更加常用一些。舉個例子,我們都知道新聞網站是會將新聞進行種類劃分的,這樣用戶就可以選擇自己喜歡的那一類新聞進行浏覽,比如說網易新聞中就會有頭條、科技、娛樂、手機等等種類。每個種類下面當然都會有許多條新聞,而一條新聞也可能是屬於多個種類的,比如iPhone6發布的新聞既可以屬於手機種類,也可以屬於科技種類,甚至還可以上頭條。因此,新聞和種類之間就是一種多對多的關系,如下圖所示:
可以看到,News1是屬於Category1的,而News2和News3都是既屬於Category1也屬於Category2,如此復雜的關聯關系該如何表示呢?在面向對象的編程語言中一切都是那麼的簡單,只需要在News類中使用集合類聲明擁有多個Category,然後在Category類中也使用集合類聲明擁有多個News就可以了,我們稍後就會看到。而難點仍然是留在了數據庫上,兩張表之間如何建立多對多的關聯關系呢,還是用外鍵嗎?肯定不行了,多對多的情況只能是借助中間表來完成了。也就是說,我們需要多建立一張表,這張表沒什麼其它作用,就是為了存放news表和category表之間的關聯關系的,如下圖所示:
注意這裡我們建立一張名為category_news的中間表,中間表的命名並沒有什麼強制性的約束,但一個良好的命名規范可以讓你一眼就明白這張表是用來做什麼的。中間表裡面只有兩列,而且也只需要有兩列,分別是news表的外鍵和category表的外鍵,在這裡存放新聞和種類相應的id,就可以讓它們之間建立關聯關系了,如下圖所示:
由此我們就可以看出,第一條新聞是屬於第一個種類的,而第二和第三條新聞,則既屬於第一個種類,也屬於第二個種類。反過來也可以這樣看,第一個種類下面有第一、第二、第三這三條新聞,而第二個種類下面只有第二、第三這兩條新聞。不管怎麼看,多對多的關系都是成立的。
好了,三種關聯關系都講完了,那我們來簡單總結一下吧。雖說上面介紹了花了很大的篇幅講解數據庫的表關聯知識,但其實最後的結論是非常簡單的,大家可以當成口訣一樣背下來。即一對一關聯的實現方式是用外鍵,多對一關聯的實現方式也是用外鍵,多對多關聯的實現方式是用中間表。記下了這個口訣,在很多數據庫設計的時候,你都可以發揮得更加游刃有余。
雖說口訣就是這個樣子,但牽扯到表關聯的時候畢竟增加了建表的難度,建表語句會更加復雜,你也需要格外地小心以防止出現什麼錯誤。因此,使用LitePal來自動建立表關聯又是一個非常不錯的選擇,我們不需要關心什麼外鍵、中間表等實現的細節,只需要在對象中聲明好它們相互之間的引用關系,LitePal就會自動在數據庫表之間建立好相應的關聯關系了,下面我們就來嘗試一下吧。
首先確定一下一共涉及到了哪些實體類,News和Comment,這兩個類我們在前兩篇文章中就已經建好了,然後還需要有Introduction和Category這兩個類,新建Introduction類,代碼如下所示:
public class Introduction { private int id; private String guide; private String digest; // 自動生成get、set方法 }接著新建Category類,代碼如下所示:
public class Category { private int id; private String name; // 自動生成get、set方法 }現在四個類都已經建好了,但目前它們都還是各自獨立的,互相之間沒有任何聯系,那麼我們現在就開始用極為簡單易懂的方式來給它們建立關聯吧。首先,News和Introduction是一對一的關系,那就可以在News類中添加如下引用:
public class News { ... private Introduction introduction; // 自動生成get、set方法 }就是這麼簡單,在News類中可以得到一個對應的Introduction的實例,那麼它們之間就是一對一關系了。
接著Comment和News是多對一的關系,因此News中應該包含多個Comment,而Comment中應該只有一個News,所以就可以這樣寫:
public class News { ... private Introduction introduction; private List先使用一個泛型為Comment的List集合來表示News中包含多個Comment,然後修改Comment類的代碼,如下所示:commentList = new ArrayList (); // 自動生成get、set方法 }
public class Comment { ... private News news; // 自動生成get、set方法 }在Comment類中聲明了一個News的實例,這樣就清楚地表示出了News中可以包含多個Comment,而Comment中只能有一個News,也就是多對一的關系了。
最後News和Category是多對多的關系,相信聰明的你一定已經知道該怎麼寫了。News中可以包含多個Category,所以仍然應該使用List集合來表示:
public class News { ... private Introduction introduction; private List而Category中也可以包含多個News,因此Category類也應該使用相同的寫法,如下所示:commentList = new ArrayList (); private List categoryList = new ArrayList (); // 自動生成get、set方法 }
public class Category { ... private List這樣就清楚地表達出它們之間是多對多的關聯了。newsList = new ArrayList (); // 自動生成get、set方法 }
基本上到這裡就可以輕松地說結束了,現在只需要任意操作一下數據庫,表之間的關聯關系就將會自動建立,比如說調用一下Connector.getDatabase()方法。
下面我們來驗證一下吧,輸入.table命令查看一下當前數據庫中的表,如下所示:
OK,news、comment、category、introduction這幾張表全都有了,除此之外還有一張category_news中間表。那我們要來一一檢查一下了,先查看一下introduction表的結構吧,如下所示:
可以看到,多了一個news_id列,說明introduction表和news表之間的一對一關系已經建立好了。
然後再檢查一下comment表的結構,如下所示:
OK,comment表中也有一個news_id的列,那麼comment表和news表之間的多對一關系也已經建立好了。
最後檢查一下category_news這張中間表的結構,如下所示:
一共只有兩列,一列是news_id,一列是category_id,分別對應著兩張表的外鍵,這樣news表和category表的多對多關系也建立好了。
借助LitePal的幫助,即使你並不熟悉數據庫的表關聯設計,只要你會面向對象編程,都可以輕松地將表與表之間的關聯建立起來。創建表、升級表、表關聯,這就是LitePal在數據庫表管理方面給我們帶來的巨大便利,相信大家都能體會到它的魅力所在了。那麼到這裡為止,我們就把使用LitePal進行表管理的知識全部學完了,從下一篇文章開始,我將會講解如何使用LitePal進行CRUD的操作。
最近項目上需要實現藍牙傳輸apk的一個功能,能夠搜索周圍的藍牙手機並分享文件。從需求上講android手機自帶的藍牙傳輸模塊就可以滿足需要了,實現也很簡單。不過讓人頭疼的
在插上電源充電之後,充上幾個小時發現手機的電量沒有任何增進,反而掉的見底了!小編在充電的時候,充了一整夜都只到75%。這是怎麼回事,是電池問題嗎?還是其他什
概述 悠悠綠水傍林侵日落觀山四望回 幽林古寺孤明月冷井寒泉碧映台 鷗飛滿浦漁舟泛鶴伴閒亭仙客來 游徑踏花煙上走流溪遠棹一篷開 概述 一個不小心都寫了三篇了,也不知道大家
一:Android 4.0WebView分析(1)WebView API三:Android 4.4 WebView的結構在Android 4.4系統上 Google已經將