ORM物件關係對映之GreenDAO建立多表關聯
利用GreenDAO可以非常方便的建立多張表之間的關聯
一對一關聯
通常我們在操作資料庫的時候,我們往往不是單獨的對一張表進行操作,而是對這張表的操作會聯動的影響另外一張表或者多張表,比如:現在有兩張表,一張是使用者User表(有name、age、sex三個欄位),一張是頭像Picture表(有pictureId、pictureName、width、height四個欄位)。假如使用者表和頭像表是一對一關係,一個使用者只有一個頭像,一個頭像只能有一個使用者,所以要建立這兩張表之間的聯絡,這兩張表肯定是需要關聯的,這樣就可以通過使用者的資訊得到它的頭像資訊。我們知道在資料庫中,關聯兩張表(暫且不說多對多關係的)一般都是把一張表的主鍵作為另外一張表的外來鍵來做的,所以在Android中也同樣,如果我們要關聯User表和Picture表,那麼只需要把Picture表的主鍵(假如是pictureId)作為User表的外來鍵即可,另外一個亦是如此,如:
假設還是以上面的場景為例,則利用GreenDAO建立User表和Picture表一對一的關聯可以這樣建立:
//把User表的主鍵name作為Picture表的外來鍵,把Picture的主鍵pictureId作為User表的外來鍵,這樣得到任何一個實體的資訊都可以得到關聯的另外一個實體的資訊
Property property = user.addLongProperty("pictureId").getProperty();
user.addToOne(picture,property);
Property propertyName = picture.addStringProperty ("name").getProperty();
picture.addToOne(user,propertyName);
在為Schema新增實體的時候,我們在相應的實體中新增另外一個表的主鍵即可:
Schema schema = new Schema(1,"com.sunzxyong.greendao2");
//User
Entity user = schema.addEntity("User");
user.addStringProperty("name").notNull().primaryKey();
user.addStringProperty ("sex");
//Picture
Entity picture = schema.addEntity("Picture");
picture.addLongProperty("pictureId").primaryKey();
picture.addStringProperty("pictureName").notNull();
picture.addIntProperty("width");
picture.addIntProperty("height");
//建立一對一關聯
Property property = user.addLongProperty("pictureId").getProperty();
user.addToOne(picture,property);
Property propertyName = picture.addStringProperty("name").getProperty();
picture.addToOne(user,propertyName);
new DaoGenerator().generateAll(schema, "../GreenDAODemo/app/src/main/java-gen");
【注意】:目前多表關聯只能支援關聯的表只能有一個主鍵,所以我們不能加入user.addIdProperty();或者在表中設定了兩個主鍵,因為user.addIdProperty();預設會把id作為主鍵。所以當你的某張表存在與其它表關聯時,你需要檢查所關聯的那張表是否只設置了一個主鍵,否則將會報錯。
當右鍵執行生成相應的實體後,我們可以開啟User類:
發現多了一個pictureId
屬性,這正是User表的外來鍵,Picture的主鍵,然後構造方法也需要我們傳入pictureId
的值:
User類中還提供了一個getPicture()方法,供我們直接得到當前User的Picture物件而得到相應資訊,實際上它內部已經幫我們封裝好了相應的查詢方法,我們只需直接呼叫即可:
同樣Picture類中也是這樣。
一對多關聯
大家都知道在超市購物時候,一位顧客可以有很多訂單,而一個訂單隻能屬於一位顧客,所以這就成了一對多的關係,假設顧客Customer表有customerId(primaryKey)、name兩個屬性,訂單Order表有orderId(primaryKey)、money兩個屬性。
所以建立顧客和訂單之間的一對多關聯為:
Schema schema = new Schema(1,"com.sunzxyong.greendao3");
//顧客
Entity customer = schema.addEntity("Customer");
customer.addLongProperty("customerId").primaryKey();
customer.addStringProperty("name").notNull();
//訂單
Entity order = schema.addEntity("Order");
order.addLongProperty("orderId").primaryKey();
order.addDoubleProperty("money").notNull();
//建立一對多關聯(顧客對訂單為一對多)
Property property = order.addLongProperty("customerId").getProperty();
order.addToOne(customer,property);
customer.addToMany(order,property).setName("orders");
new DaoGenerator().generateAll(schema, "../GreenDAODemo/app/src/main/java-gen");
當設定了顧客對訂單一對多關聯後,Order實體(和表)中會多一個屬性為customerId
,所以通過訂單我們可以得到該顧客資訊,而Customer實體(和表)中會多一個List集合變數:List<Order> orders
,表示該顧客的所有訂單,其中orders
其實是我們自定義的名字,在剛剛setName("orders")
就是給這個變數設定了“orders“名稱,而Customer實體中還提供了一個方法getOrders()
表示得到該顧客所有訂單:
List<Order> orders = customer.getOrders();
事實上它也是封裝好了查詢Order中顧客id為customerId的所有訂單。
多對多關聯
通常來說,在建立多對多關聯上,我們都會採用新建一張中間表,利用中間表把多對多這種複雜關係簡單化,在通常的選課系統上,一個學生可以選擇多門課,一門課可以被多個學生選,這就是多對多關係了,假設Student有studentId、name兩個屬性,Course有courseId、courseName兩個屬性,則建立多對多關係為:
Schema schema = new Schema(1,"com.sunzxyong.greendao4");
//學生
Entity student = schema.addEntity("Student");
student.addLongProperty("studentId").primaryKey();
student.addStringProperty("name").notNull();
//課程
Entity course = schema.addEntity("Course");
course.addLongProperty("courseId").primaryKey();
course.addStringProperty("courseName").notNull();
//建立多對多關聯
Entity studentCourse = schema.addEntity("StudentCourse");
Property studentId = studentCourse.addLongProperty("studentId").getProperty();
Property courseId = studentCourse.addLongProperty("courseId").getProperty();
studentCourse.addToOne(student,studentId);
studentCourse.addToOne(course,courseId);
student.addToMany(studentCourse, studentId);
course.addToMany(studentCourse,courseId);
new DaoGenerator().generateAll(schema, "../GreenDAODemo/app/src/main/java-gen");
這樣就建立學生和課程表多對多的關聯,學生實體和課程實體中都有這麼一個方法:
public List<StudentCourse> getStudentCourseList(){
//...
}
意思就是得到一個StudentCourse的集合,而StudentCourse實體中又有這麼兩個方法:
public Student getStudent(){//...}
public Course getCourse(){//...}
所以當我們得到了StudentCourse的List集合,我們可以通過StudentCourse中的這兩個方法來得到對應的學生或者課程資訊。