Tải bản đầy đủ - 0 (trang)
3 Phân tích câu truy vấn đầy đủ

3 Phân tích câu truy vấn đầy đủ

Tải bản đầy đủ - 0trang

thể).

Bảng 2.4: Phụ thuộc tương ứng với từng kiểu truy vấn

Tên phụ thuộc



Ý nghĩa phụ thuộc theo kiểu truy vấn



SQLDeleteDependency

SQLInsertDependency

SQLInsertOrUpdateDependency

SQLSelectDependency

SQLUpdateDependency



Phương thức DAO truy vấn xóa bản ghi

Phương thức DAO truy vấn thêm bản ghi

Phương thức DAO truy vấn thêm hoặc cập nhật bản ghi

Phương thức DAO truy vấn lấy thông tin bản ghi

Phương thức DAO truy vấn cập nhật bản ghi



Hibernate được xây dựng trên nền của JDBC để quản lí và cải tiến các thao tác đến

CSDL. Hibernate sử dụng hai phương pháp ánh xạ là dùng tệp XML hoặc dùng Java

Annotation để định nghĩa thông tin bảng trong lớp Java. Cấu trúc của Hibernate và vị

trí của nó trong ứng dụng Java được thể hiện như trong Hình 2.12.



Hình 2.12. Cấu trúc của Hibernate Framework

Ứng dụng sử dụng Hibernate phải sử dụng một tệp cấu hình. Tệp cấu hình có thể

là một tệp XML (tên là hibernate.cfg.xml) hoặc là một tệp properties

(hibernate.properties) dưới dạng key-value. Tệp hibernate.properties chỉ có thể chứa

các tham số cấu hình việc kết nối như đường dẫn đến CSDL, tài khoản/mật khẩu kết

nối CSDL, driver thực hiện kết nối và nhiều thông tin khác. Còn đối với tệp

hibernate.cfg.xml, ngồi chứa các tham số kể trên, nó còn có thể chứa thơng tin của

những tệp mơ tả việc ánh xạ. Một ví dụ của tệp hibernate.cfg.xml được mô tả như Mã

nguồn 2.7. Trong trường hợp ứng dụng định nghĩa cả hai loại cấu hình XML và

Properties, Hibernate sẽ ưu tiên sử dụng tệp cấu hình XML.



32



Mã nguồn 2.7. Mã nguồn tệp cấu hình hibernate.cfg.xml

?xml version='1.0'encoding='utf-8'?>


PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"

“http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">







com.mysql.jdbc.Driver





jdbc:mysql://localhost:3306/Sample



root

pass

true









Q trình phân tích sâu mã nguồn của Hibernate được mơ tả như Hình 2.13, tệp

hibernate.cfg.xml được chuyển từ kiểu nút XmlFileNode thành kiểu nút

HibernateConfigNode. Sau đó, nội dung của tệp này được xử lý, các thẻ XML được

phân tích. Các thẻ khai báo thông tin ánh xạ được chuyển từ kiểu nút XmlTagNode

thành kiểu nút HibernateCfgMappingNode. Nút này có lưu một thuộc tính là

typeMapping thể hiện kiểu khai báo. Với kiểu ánh xạ bằng XML, thẻ khai báo ánh xạ

(thẻ ) có thuộc tính resource với giá trị là đường dẫn tệp ánh xạ XML,

khi đó giá trị của typeMapping được lưu thành “xml”. Còn kiểu ánh xạ bằng Java

Annotation, thẻ khai báo ánh xạ có thuộc tính class với nội dung là tên lớp Java với

đầy đủ package, giá trị của typeMapping được lưu là “annotation”. Tùy vào từng kiểu

khai báo ánh xạ, ta sẽ tìm được tệp ánh xạ tương ứng, hoặc XML hoặc Java. Tệp ánh

xạ này tiếp tục được đưa vào phân tích để tạo thành nút DatabaseTableNode chứa

thông tin về tên bảng, các cột, v.v. đại diện cho các bảng trong CSDL. Cuối cùng, các

nút DatabaseTableNode sẽ được chứa trong nút DatabaseSchemaNode8 và thêm như là

con của nút gốc trong JDG.



8 Nếu nút DatabaseTableNode có định nghĩa thơng tin schema thì sẽ thuộc nút DatabaseSchemaNode với tên

schema tương ứng. Nếu không định nghĩa, nút DatabaseTableNode sẽ thuộc nút DatabaseSchemaNode được tạo

ra mặc định bởi bộ phân tích.



33



Hình 2.13. Q trình phân tích sâu Hibernate

2.4.1.



Phân tích sự ánh xạ qua tệp cấu hình XML



Hibernate cũng như tất cả các công nghệ Java ORM khác, đều cần thiết phải có

định dạng về siêu dữ liệu (metadata) để mô tả cách thức ánh xạ giữa lớp với bảng,

thuộc giữa thuộc tính và các cột, sự liên hệ giữa các lớp và khóa ngoại hay các kiểu dữ

liệu tương ứng giữa Java và CSDL,… Hiện tại, định dạng thông dụng nhất cho siêu dữ

liệu về xây dựng dữ liệu đối tượng/quan hệ chính là XML. XML có cấu trúc rất gọn

gàng, dễ hiểu, dễ sử dụng và có khả năng tùy biến rất cao.

Mã nguồn 2.8. Mã nguồn tệp ánh xạ tên category.hbm.xml






1 Định nghĩa DTD



PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"

Thẻ khai báo định nghĩa

thông tin ánh xạ

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">




2

Ánh xạ lớp Category

của Java với bảng

CATEGORY



mapping> 3



Ánh xạ Khóa chính

CATEGORY_ID với trường id

của lớp Category

name="sample.model.Category"

table="CATEGORY"> 4


name="id"

column="CATEGORY_ID"

type="long">



34




class="native"/>





5



Ánh xạ cột NAME với trường

name của lớp Category




name="name" column="NAME" type="string"/>







Mã nguồn 2.8 là một phần tệp cấu hình trong ánh xạ giữa bảng CATEGORY

trong CSDL với thực thể Category của Java. Bước đầu tiên, bộ phân tích sẽ tìm tất cả

các thẻ - thẻ chứa thông tin ánh xạ giữa bảng của CSDL với

một thực thể. Thẻ định nghĩa các thông tin ánh xạ giữa tên bảng (thuộc tính

table) với thơng tin của thực thể Java (thuộc tính name). Tên của thực thể Java là tên

chứa đầy đủ đường dẫn của package (gói). Thẻ thể hiện việc ánh xạ giữa khóa

chính của bảng với một trường của thực thể. Tương tự như các thẻ khác, thuộc tính

table chứa tên khóa chính ánh xạ, name dành cho tên trường của thực thể và type kiểu

dữ liệu của trường được ánh xạ. Cách đánh chỉ số của khóa chính trong CSDL được

định nghĩa bởi thẻ . Mỗi cột trong CSDL, đều được ánh xạ bằng thẻ

. Thẻ có các thuộc tính giống với thẻ nhưng không

chứa thẻ con . Mối quan hệ many-to-one, one-to-many và many-to-many

giữa các bảng trong CSDL được định nghĩa bởi ba thẻ tương ứng ,

. . Hai thẻ

đều định nghĩa tên bảng ánh xạ bằng thuộc tính name, cột có mối quan hệ là thuộc tính

column và các thực thể tham gia qua thuộc tính class. Còn thẻ định

nghĩa tên thực thể tham gia qua thuộc tính entity-name.

2.4.2.



Phân tích sự ánh xạ qua Java Annotation



Chú thích (Java Annotation) là một kiểu siêu dữ liệu được xây dựng và sử dụng trên

mã nguồn Java, dùng để đặc tả cho một đối tượng hoặc giá trị nào đó. Người phát triển

có thể tự định nghĩa các chú thích để phục vụ mục đích của bản thân. Đối với

Hibernate, chú thích được sử dụng với mục đích tương tự như cấu hình XML, dùng để

ánh xạ các thuộc tính của bảng như tên bảng, tên cột, kiểu dữ liệu của côt, sự quan hệ,

v.v. sang kiểu của Java. Mã nguồn 2.9 là ví dụ khi sử dụng Java Annotation để mô tả

cách thức ánh xạ.

Mỗi một chú thích khi sử dụng phải được kí hiệu bắt đầu bằng ký tự “@”.



35



Hibernate sử dụng các chú thích theo chuẩn JPA 2.1 9. Chú thích đầu tiên được sử dụng

trong Mã nguồn 2.9 là @Entity, khai báo rằng lớp User hiện tại là một POJO (Plain

Old Java Object). POJO là một lớp không thừa kế lớp khác (ngoại trừ lớp

Serializable), chỉ chứa thuộc tính và các phương thức getter, setter (có thể thêm

toString() và equal()). Hibernate yêu cầu bắt buộc lớp được ánh xạ phải là một POJO

và sử dụng chú thích @Entity. Để định nghĩa việc ánh xạ bảng, Hibernate sử dụng chú

thích @Table cho tên lớp với các thuộc tính như name (tên bảng trong CSDL), catalog

(tên catalog trong CSDL), uniqueConstraints (các ràng đồng nhất có trong bảng),

indexes (danh sách khóa chính trong bảng). Còn với ánh xạ các cột, Hibernate sử dụng

chú thích @Column với các thuộc tính như name (tên cột), length (độ dài của cột),

nullable (cột có thể có giá trị null hay khơng), unique (cột có đinh nghĩa đơn nhất hay

khơng),… Chú thích @Column có thể được sử dụng để khai báo cho một trường của

lớp Java, hoặc cho hàm getter của trường nào đó. Ngồi ra, để định nghĩa một trường

ánh xạ với khóa chính trong bảng, Hibernate sử dụng chú thích @Id. Đồng thời, chú

thích @Generator được sử dụng để thơng báo cách thức sinh khóa chính tự động.

Mã nguồn 2.9. Mã nguồn tệp User.java chứa thông tin ánh xạ bằng annotation

@Entity

@Table(name = "BOOK", catalog = "sample", uniqueConstraints = {

@UniqueConstraint(columnNames = "NAME")})

public class Book implements java.io.Serializable {

private Integer id;

private String name;

private String author;

public User() {}

public User(String name, String author) {

this.name = name;

this.author = author;

}

@Id

@GeneratedValue(strategy = IDENTITY)

@Column(name = "ID", unique = true, nullable = false)

public Integer getId() {return this.id;}

public void setId(Integer id) {this.id = id;}

@Column(name = "NAME",unique = true,nullable = false,length = 10)

public String getName () {return this.name;}

public void setName(String name) {this.name = name;}

@Column(name = "AUTHOR",unique = true,nullable = false,length = 20)

public String getAuthor() {return this.author;}

public void setAuthor(String author) {this.author = author;}

9 http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf



36



}



Để ánh xạ được mối quan hệ giữa các bảng với nhau, Hibernate sử dụng các chú

thích @OneToMany, @ManyToOne, @ManyToMany:

• @OneToMany: Được sử dụng để định nghĩa cho phía “một” của quan hệ mộtnhiều. Sử dụng thuộc tính mappedBy khai báo tên trường của thực thể tham

chiếu đến thực thể hiện tại.

• @ManyToOne: Được sử dụng để định nghĩa cho phía “nhiều” của quan hệ mộtnhiều. Chú thích này phải được sử dụng đồng thời với @JoinColumn. Chú thích

@JoinColumn sử dụng thuộc tính name để khai báo tên cột bị tham chiếu.

• @ManyToMany: Được sử dụng để định nghĩa ở cả hai phía của quan hệ nhiềunhiều. Một trong hai thực thể của quan hệ này phải sử dụng chú thích

@JoinTable. Thực thể nào sử dụng @JoinTable được gọi là thực thể thuận,

bảng ánh xạ với thực thể thuận gọi là bảng thuận. Thực thể còn lại gọi là thực

thể nghịch, và bảng ánh xạ gọi là bảng nghịch. Chú thích @JoinTable sẽ khai

báo bảng trung gian của hai bảng trong quan hệ. Trong @JoinTable có ba thuộc

tính: name (tên của bảng trung gian), joinColumn (tên cột trong bảng trung gian

tham chiếu tới bảng thuận), inverseJoinColumns (tên cột trong bảng trung gian

tham chiếu tới bảng nghịch). Đồng thời, trong thực thể nghịch, trong chú thích

@ManyToMany, phải khai báo thuộc tính mappedBy là tên trường mà thực thể

thuận sử dụng để ánh xạ.

Do cấu trúc sự ánh xạ của Hibernate bằng Java Annotation rất tường minh, nên việc

phân tích phụ thuộc trong mã nguồn khá đơn giản. Từ bước tiền xử lý mã nguồn Java,

ta có thể lấy được danh sách các chú thích của lớp, sâu hơn nữa là của các trường, các

phương thức. Cứ với mỗi lớp Java trong JDG có kiểu JavaClassNode mà sử dụng

đồng thời hai chú thích là @Entity và @Table, bộ phân tích sẽ tạo một nút kiểu

DatabaseTableNode đại diện cho một bảng trong CSDL. Nút DatabaseTableNode

chứa tên bảng và tên schema ánh xạ (có thể để trống) tương ứng với giá trị của thuộc

tính name và catalog trong chú thích @Table. Tương tự như vậy, với mỗi một chú

thích

@Column có trong lớp Java, bộ phân tích tạo một nút kiểu

DatabaseColumnNode là nút con của DatabaseTableNode tương ứng đại diện cho một

cột. Ngoài thơng tin tên cơt được lấy từ thuộc tính name, nút DatabaseColumnNode

cũng lấy các thơng tin từ các thuộc tính length, nullable, unique, v.v.

2.4.3.



Phân tích phương thức tương tác cơ sở dữ liệu



Hibernate hiện có hai cách thức tương tác với CSDL là dùng phương thức được

37



xây dựng sẵn có sử dụng thực thể hoặc sử dụng câu truy vấn. Do đó bộ phân tích

Hibernate sẽ chia ra làm hai phần nhỏ là phân tích hàm tương tác thực thể và phân tích

câu truy vấn. Hibernate đã xây dựng sẵn các phương thức tương tác với CSDL bằng

thực thể, danh sách các phương thức cho trong Bảng 2.5. Tham số truyền vào các hàm

này có thể là tên của thực thể Java dưới dạng “package.name” ví dụ như

“sample.entity.Book”. Đi kèm với tên thực thể là đối tượng Java chứa các giá trị cần

gửi cho CSDL, hoặc chỉ cần gửi đối tượng Java là đủ. Các phương thức này có các đặc

điểm khá riêng biệt nên chúng dễ được tìm thấy bằng các qt qua từng câu lệnh. Sau

đó phân tích các tham số truyền vào phương thức này và xác định thực kiểu thực thể

được sử dụng.

Ngoài câu truy vấn SQL thơng thường, Hibernate còn hỗ trợ dùng ngơn ngữ truy

vấn HQL - ngôn ngữ truy vấn làm việc trên các thực thể khác với SQL làm việc trên

các bảng - ví dụ như “from sample.entity.Book” hay chỉ đơn giản “from Book”. Do đó,

bộ phân tích JDBC API sẽ được sử dụng cho phân tích truy vấn của Hibernate, nhưng

khơng chỉ tìm bảng được gọi mà còn xác định những thực thể có tham gia trong câu

truy vấn.

Bảng 2.5. Danh sách các phương thức truy xuất CSDL có sẵn của Hibernate

Phương thức



Mơ tả



delete(Object data)

delete(String entityName, Object data)



Xóa một bản ghi



get(Class clazz, Serializable id)

get(String entityName, Serializable id)



Lấy thông tin bản ghi



load(Class clazz, Serializable id)

load(Object data, Serializable id)



Lấy thông tin bản ghi



merge(Object data)

merge(String entityName, Object data)



Cập nhật bản ghi



persist(Object data)

persist(String entityName, Object data)



Lưu bản ghi



save(Object data)

save(String entityName, Object data)



Lưu bản ghi



update(Object data)

update(String entityName, Object data)



38



Cập nhật bản ghi



Chương 3.



Phương pháp phân tích và xây dựng luồng dữ liệu



Đồ thị luồng dữ liệu là một khía cạnh của phân tích cấu trúc. Đồ thị luồng dữ liệu

biểu diễn một thứ tự đầy đủ các nút từ nút mở đầu luồng dữ liệu đến nút cuối cùng mà

dữ liệu được sử dụng. Với ứng dụng J2EE, nút mở đầu thường là các phần tử thuộc

phần View, như là tệp JSP, HTML, v.v. Sau đó, thông tin được gửi tới các lớp nghiệp

vụ để xử lí. Sau khi lớp nghiệp vụ tương tác với CSDL, kết quả được trả về và hiển thị.

Do đó, để mơ tả được rõ q trình dữ liệu được xử lý, đồ thị dòng dữ liệu nên thể hiện

một hướng đi rõ ràng.

Cách thức xây dựng dòng dữ liệu được mơ tả như Hình 3.14. Để xây dựng đồ thị

dòng dữ liệu, đầu tiên, từ nút gốc được truyền vào, phương pháp này phân tích các phụ

thuộc và tạo một luồng dữ liệu ở dạng thô, tập trung vào phần dữ liệu của luồng. Sau

đó đồ thị được chuẩn hóa và giữ lại thông tin cần thiết cho việc hiển thị.



Hình 3.14. Q trình phân tích và xây dựng luồng dữ liệu

3.1.Phân tích cây cấu trúc và xây dựng luồng dữ liệu thô



Định nghĩa: (Đồ thị luồng dữ liệu) Đồ thị kí hiệu G = , V là tập các đỉnh

của đồ thị. E = V R V là tập các cạnh với nhãn R = {DBTOVIEW, VIEWTODB},

gọi là cạnh dữ liệu. Cạnh có nhãn DBTOVIEW thể hiện cho dữ liệu được truyền từ

CSDL đến phần hiển thị của ứng dụng, gọi là cạnh dữ liệu ra, hai đỉnh của cạnh này

gọi là có quan hệ dữ liệu thuận. Ngược lại, cạnh dữ liệu tới là cạnh có nhãn

VIEWTODB thể hiện dữ liệu được truyền từ lớp hiển thị đến CSDL, giữa hai đỉnh của

cạnh có quan hệ dữ liệu nghịch.

Trong đồ thị luồng dữ liệu, định nghĩa ba kiểu đỉnh là đinh tương tác, đỉnh

thường và đỉnh xử lý.

• Đỉnh tương tác: Thể hiện việc người dùng có thể tương tác, đại diện cho phần

View (JSP, HTML). Nếu có trong đồ thị, đỉnh này phải là vừa đỉnh bắt đầu, vừa



39



là đỉnh kết thúc trong luồng dữ liệu.

• Đỉnh thường: Thể hiện cho một phần tử trong luồng dữ liệu.

• Đỉnh xử lý: Thể hiện cho tầng thấp nhất của luồng dữ liệu, đại diện cho phần

Model (trong ứng dụng J2EE là CSDL), là nơi dữ liệu được xử lý. Đồng thời,

đỉnh này cũng là nơi cuối cùng nhận dữ liệu được gửi từ phần giao diện, và là

đỉnh đầu tiên trả về dữ liệu để hiển thị.

Đồ thị luồng dữ liệu được xây dựng từ JDG. Do đó, mỗi một phụ thuộc sẽ được

ánh xạ với mơt tập các cạnh dữ liệu bởi một hàm ánh xạ �: D → 2E gọi là hàm chuyển.

Do các phụ thuộc cấu trúc không thể hiện việc sử dụng dữ liệu của các thành phần

trong mã nguồn. Do đó, tất cả các phụ thuộc cấu trúc sẽ không tham gia vào q trình

xây dựng luồng dữ liệu thơ, nghĩa là �(DPt =STRUCTURE) = ∅.

Phương pháp xây dựng luồng dữ liệu thô từ đỉnh bắt đầu r như sau: Bắt đầu từ

nút gốc nr ứng với đỉnh r, ta lấy danh sách các phụ thuộc dữ liệu của nút đó. Mỗi phụ

thuộc dữ liệu sẽ được ánh xạ sang tập các cạnh dữ liệu. Đồng thời, phụ thuộc đang

được ánh xạ được kiểm tra xem có nhãn converted hay khơng. Nếu phụ thuộc có nhãn

converted, nghĩa là đã được chuyển đổi sang tập cạnh dữ liệu trước đó rồi, thì phụ

thuộc đó sẽ bị bỏ qua. Còn nếu chưa có nhãn converted, tập cạnh dữ liệu sinh ra sẽ

được thêm vào đồ thị, phụ thuộc đó sẽ được gán nhãn converted và nút cuối của phụ

thuộc sẽ tiếp tục được xử lý như trên.

Ví dụ về đồ thị luồng dữ liệu thơ được thể hiện như Hình 3.15. Đồ thị này có thể hiểu

theo thực tế như sau: Đỉnh 1 là một đỉnh JSP bắt đầu luồng dữ liệu. Thành phần tương

tác dữ liệu trong JSP thường là một thẻ
. Thông tin tương tác sẽ được ánh xạ

với một thẻ (đỉnh 2). Cạnh từ Đỉnh 1 tới Đỉnh 2 được sinh ra bởi hàm

chuyển của phụ thuộc JspToStrutsConfigurationDependency. Thẻ được ánh

xạ với một lớp Java qua phụ thuộc StrutsActionToJavaClass. Theo như kiến trúc của

Struts10, mỗi Interceptor được chạy trước khi lớp Java của StrutsAction thực hiện và

sau khi lớp Java của StrutsAction kết thúc xử lý. Do đó, hàm chuyển của phụ thuộc từ

tới lớp Java phải có sự tham gia của các Interceptor. Điều này khiến cho

trong đồ thị của Hình 3.15, giữa Đỉnh 2 và Đỉnh 5 có sự tham gia của Đỉnh 3 và 4.

Trong lớp Java của Struts Action sẽ sử dụng các lớp nghiệp vụ và tương tác đến

CSDL. Dữ liệu sau khi được lấy từ CSDL sẽ được trả về cho lớp Java của Struts

Action. Các Interceptor được hoạt động sau khi lớp Java của Struts Action kết thúc xử

lý. Thẻ định nghĩa các Struts Result (đỉnh 8) khai báo việc hiển thị dữ liệu.

10 https://struts.apache.org/core-developers/interceptors.html



40



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

3 Phân tích câu truy vấn đầy đủ

Tải bản đầy đủ ngay(0 tr)

×