Các đối tƣợng có cấu trúc

Một phần của tài liệu Nghiên cứu cơ sở dữ liệu hướng đối tượng và áp dụng vào bài toán cụ thể với hệ quản trị DB40 (Trang 61 - 66)

Mở rộng miền làm việc với lớp khác và xem làm thế nào db4o lƣu giữ đƣợc mối quan hệ giữa các đối tƣợng.

namespace Db4odoc.Tutorial.F1.Chapter2 { public class Car {

string _model; Pilot _pilot;

public Car(string model) { _model = model;

_pilot = null; }

public Pilot Pilot { get {

return _pilot; }

set {

} }

public string Model { get {

return _model; }

}

override public string ToString() {

return string.Format("{0}[{1}]", _model, _pilot); }

} }

2.2.5.1. Lưu trữ các đối tượng có cấu trúc

Cách 1: Để lƣu trữ một xe với pilot của nó, ta gọi STORE() trên đối tƣợng . Car car1 = new Car("Ferrari");

Pilot pilot1 = new Pilot("Michael Schumacher", 100); car1.Pilot = pilot1;

db.Store(car1);

Cách 2: Lƣu trữ pilot trƣớc khi đƣa vào car, kết quả không khác nhau. Pilot pilot2 = new Pilot("Rubens Barrichello", 99);

db.Store(pilot2);

Car car2 = new Car("BMW"); car2.Pilot = pilot2;

db.Store(car2);

2.2.5.2. Tìm kiếm các đối tượng có cấu trúc a QBE

Để tìm kiếm tất cả xe, ta cung cấp một nguyên mẫu “trống” Car proto = new Car(null);

IObjectSet result = db.QueryByExample(proto); ListResult(result);

Ta cũng có thể truy vấn tất cả pilot Pilot proto = new Pilot(null, 0);

IObjectSet result = db.QueryByExample(proto); ListResult(result);

Khởi tạo nguyên mẫu để tìm kiếm tất cả các xe đƣợc lái bởi Rubens Barrichello. Pilot pilotproto = new Pilot("Rubens Barrichello", 0);

Car carproto = new Car(null); carproto.Pilot = pilotproto;

IObjectSet result = db.QueryByExample(carproto); ListResult(result);

Nếu ta đã biết thông tin về xe thì dễ dàng biết thông tin ngƣời lái bằng việc truy cập vào trƣờng pilot.

b Native Queries

Sử dụng Native Queries với các ràng buộc trên cấu trúc các đối tƣợng là dễ thực hiện, có thể thực hiện điều đó giống nhƣ với các ngôn ngữ khác. Ràng buộc truy vấn chỉ gồm các xe đƣợc điều khiển bởi Pilot có tên xác định:

public class RetrieveCarsByPilotNamePredicate : Predicate { readonly string _pilotName;

public RetrieveCarsByPilotNamePredicate(string pilotName) { _pilotName = pilotName;

}

public bool Match(Car candidate) {

return candidate.Pilot.Name == _pilotName; }

}

string pilotName = "Rubens Barrichello"; IObjectSet results = db.Query(new

RetrieveCarsByPilotNamePredicate(pilotName)); ListResult(results);

c SODA Query API

Sử dụng SODA để truy vấn xe với tên ngƣời lái, ta phải giảm xuống hai mức trong truy vấn .

IQuery query = db.Query(); query.Constrain(typeof(Car));

query.Descend("_pilot").Descend("_name").Constrain("Rubens Barrichello"); IObjectSet result = query.Execute();

ListResult(result);

Ta có thể ràng buộc các trƣờng pilot với một nguyên mẫu để đạt đƣợc kết quả tƣơng tự.

IQuery query = db.Query(); query.Constrain(typeof(Car));

Pilot proto = new Pilot("Rubens Barrichello", 0); query.Descend("_pilot").Constrain(proto);

IObjectSet result = query.Execute(); ListResult(result);

Ta thấy rằng giảm dần một truy vấn cung cấp cho chúng một truy vấn khác. Bắt đầu từ truy vấn gốc, ta giảm xuống theo nhiều hƣớng. Trong thực tế điều này giống nhƣ là tăng dần từ một con nào đó tới cha và giảm dần xuống con khác. Chúng ta có thể kết luận rằng các truy vấn theo một hƣớng tham chiếu trong các đối tƣợng của ta

vào mối quan hệ đúng. Đây là một ví dụ truy vấn "Tìm tài xế xe có nhãn hiệu 'Ferrari'":

IQuery carQuery = db.Query(); carQuery.Constrain(typeof(Car));

carQuery.Descend("_model").Constrain("Ferrari"); IQuery pilotQuery = carQuery.Descend("_pilot"); IObjectSet result = pilotQuery.Execute();

ListResult(result);

Hình 2.11 Minh họa truy vấn SODA

2.2.5.3. Cập nhật các đối tượng có cấu trúc

Để cập nhật các đối tƣợng có cấu trúc trong db4o, gọi lại STORE() trên chúng. IObjectSet result = db.QueryByExample(new Car("Ferrari"));

Car found = (Car)result.Next();

found.Pilot = new Pilot("Somebody else", 0); db.Store(found);

result = db.QueryByExample(new Car("Ferrari")); ListResult(result);

Thay đổi thông tin tài xế.

IObjectSet result = db.QueryByExample(new Car("Ferrari")); Car found = (Car)result.Next();

found.Pilot.AddPoints(1); db.Store(found);

result = db.QueryByExample(new Car("Ferrari")); ListResult(result);

Cập nhật chiều sâu

Hình dung một đối tƣợng phức tạp có nhiều đối tƣợng con (kế thừa) mà mỗi con của nó lại có nhiều con. Khi cập nhật đối tƣợng này, db4o phải cập nhật tất cả các đối tƣợng con, cháu,… của nó. Điều này đƣa đến thực thi khó khăn và sẽ không cần thiết trong phần lớn các trƣờng hợp.

Trong ví dụ cập nhật trƣớc, ta đã thay đổi tài xế (pilot) con của một đối tƣợng xe. Khi lƣu lại sự thay đổi, ta nói rằng db4o đã lƣu lại đối tƣợng xe mà giả sử bộ rằng sự thay đổi pilot sẽ đƣợc cập nhật. Nhƣng ta đã thay đổi và lƣu lại nhƣ đã làm ở ví dụ cập nhật đầu tiên. Lần đầu tạo ra sự thay đổi, db4o thực sự không bao giờ phải truy vấn

thay đổi pilot, nó trả về cái gì đó in dấu trong bộ nhớ là ta đã thay đổi nhƣng không bao giờ cập nhật cơ sở dữ liệu. Chúng ta nhìn thấy giá trị đã thay đổi, trong thực tế đó là một sai sót (lỗi). Chạy lại ứng dụng sẽ thấy giá trị không thay đổi.

Để giải quyết vấn đề này, db4o giới thiệu khái niệm cập nhật chiều sâu để điểu khiển làm thế nào chiều sâu các đối tƣợng thành viên trên cây đƣợc cập nhật. Cập nhật ngầm định cho tất cả các đối tƣợng là 1, nghĩa là chỉ các thành viên nguyên thuỷ và chuỗi đƣợc cập nhật, nhƣng thay đổi trong các thành viên đối tƣợng sẽ không phản xạ.

Db4o cung cấp các phƣơng tiện để điều khiển cập nhật chiều sau rất tốt. Vấn đề hiện tại là cập nhật đồ thị đầy đủ cho các đối tƣợng xe bằng cách thiết lập cascadeOnUpdate() cho lớp này.

// updatePilotSeparateSessionsImprovedPart1

IConfiguration config = Db4oFactory.NewConfiguration(); config.ObjectClass(typeof(Car)).CascadeOnUpdate(true);

IObjectContainer db = Db4oFactory.OpenFile(config, YapFileName); IObjectSet result = db.QueryByExample(new Car("Ferrari"));

Car found = (Car)result.Next(); found.Pilot.AddPoints(1); db.Store(found);

db.Close();

// updatePilotSeparateSessionsImprovedPart2

IObjectSet result = db.QueryByExample(new Car("Ferrari")); ListResult(result);

2.2.5.4. Xoá các đối tượng có cấu trúc

Gọi phƣơng thức DELETE() trên đối tƣợng để xoá chúng .

IObjectSet result = db.QueryByExample(new Car("Ferrari")); Car found = (Car)result.Next();

db.Delete(found);

result = db.QueryByExample(new Car(null)); ListResult(result);

Xe đã bị xóa, còn ngƣời lái thì sao? Ta hãy hiển thị tất cả ngƣời lái. Pilot proto = new Pilot(null, 0);

IObjectSet result = db.QueryByExample(proto); ListResult(result);

Không có gì ngạc nhiên cả, chúng ta không mong muốn ngƣời lái sẽ bị loại bỏ khi xóa xe của anh ta. Nhƣng nếu điều gì xảy ra nếu ta muốn đối tƣợng con cũng bị xóa theo?

Xoá đệ quy

Xoá đệ quy cũng gần giống nhƣ cập nhật. Cấu hình db4o để tài xế xe cũng bị xoá khi xe bị xoá..

IConfiguration config = Db4oFactory.NewConfiguration(); config.ObjectClass(typeof(Car)).CascadeOnDelete(true);

IObjectContainer db = Db4oFactory.OpenFile(config, YapFileName); IObjectSet result = db.QueryByExample(new Car("BMW"));

Car found = (Car)result.Next(); db.Delete(found);

result = db.QueryByExample(new Car(null)); ListResult(result);

db.Close();

Vấn đề gì sẽ xảy ra nếu đối tƣợng con bị xoá vẫn đƣợc tham chiếu bởi đối tƣợng khác?

// deleteDeepRevisited

IConfiguration config = Db4oFactory.NewConfiguration(); config.ObjectClass(typeof(Car)).CascadeOnDelete(true);

IObjectContainer db = Db4oFactory.OpenFile(config, YapFileName); IObjectSet result = db.QueryByExample(new Pilot("Michael Schumacher", 0));

Pilot pilot = (Pilot)result.Next(); Car car1 = new Car("Ferrari"); Car car2 = new Car("BMW"); car1.Pilot = pilot;

car2.Pilot = pilot; db.Store(car1); db.Store(car2); db.Delete(car2);

result = db.QueryByExample(new Car(null)); ListResult(result);

db.Close();

Pilot proto = new Pilot(null, 0);

IObjectSet result = db.QueryByExample(proto); ListResult(result);

Hiện tại db4o không kiểm tra các đối tƣợng bị xoá có đƣợc tham chiếu hay không, vì vậy cẩn thận khi dùng tính năng này.

Một phần của tài liệu Nghiên cứu cơ sở dữ liệu hướng đối tượng và áp dụng vào bài toán cụ thể với hệ quản trị DB40 (Trang 61 - 66)

Tải bản đầy đủ (PDF)

(94 trang)