1.1. Khái niệm Hibernate
1.1.1. ORM Framework
• Framework là một khái niệm trong phát triển phần mềm dùng để chỉ những “cấu trúc hỗ trợ được định nghĩa” mà trong đó những dự án phần mềm khác có thể được sắp xếp vào đó và phát triển.
• ORM (Object Relational Mapping) framework là một cơ chế cho phép người lập trình thao tác với database một cách hoàn toàn tự nhiên thông qua các đối tượng. Lập trình viên hoàn toàn không quan tâm đến loại database sử dụng, SQL, …
1.1.2. Persistence Layer
• “Tier” và “Layer”: tier thường được gắn với phần cứng về mặt vật lý (physical) còn layer thì dính đến vấn đề cách thức tổ chức bên trong của ứng dụng. Việc phân chia tier là “trong suốt” (transparent) đối với ứng dụng về mặt luận lý (logical). Điều này có nghĩa là khi ta phát triển một ứng dụng, chúng ta không bận tâm đến các thành phần (component) sẽ triển khai (deploy) ra sao mà chỉ chú ý là chúng ta sẽ tổ chức ứng dụng thành những layer như thế nào.
• Peristence layer: một ứng dụng có thể được chia làm 3 phần như sau: giao diện người dùng (presentation layer), phần xử lý nghiệp vụ (business layer) và phần chứa dữ liệu (data layer). Cụ thể ra, business layer có thể được chia nhỏ thành 2 layer con là business logic layer (các tính toán nhằm thỏa mãn yêu cầu người dùng) và persistence layer. Persistence layer chịu trách nhiệm giao tiếp với data layer (thường là một hệ quản trị cơ sở dữ liệu quan hệ - Relational DBMS). Persistence sẽ đảm nhiệm các nhiệm vụ mở kết nối, truy xuất và lưu trữ dữ liệu vào các Relational DBMS.
1.1.3. Hibernate Framework
• Hibernate là một trong những ORM Framework
• Hibernate framework là một framework cho persistence layer. Như vậy, nhờ có Hibernate framework mà giờ đây khi bạn phát triển ứng dụng bạn chỉ còn chú tâm vào những layer khác mà không phải bận tâm nhiều về persistence layer nữa.
• Hibernate: là một dịch vụ lưu trữ và truy vấn dữ liệu quan hệ mạnh mẽ và nhanh.
Hibernate giúp bạn phát triển các class dùng để lưu trữ dữ liệu theo cách thức hướng đối tượng: association, inheritance, polymorphism, composition và collections
Hibernate cho phép bạn thực hiện các câu truy vấn dữ liệu bằng cách sử dụng ngôn ngữ SQL mở rộng của Hibernate (HQL) hoặc là ngôn ngữ SQL nguyên thủy cũng như là sử dụng các API.
Hibernate được license theo LGPL (Lesser GNU Public License). Theo đó, bạn có thể thoải mái sử dụng Hibernate trong các dự án open source hoặc các dự án thương mại (commercial).
1.2. Cài đặt và sử dụng
1.2.1. Cài đặt
• Việc cài đặt Hibernate rất đơn giản. Hibernate được build thành 1 tập tin JAR. Bạn chỉ cần download tập tin này và lưu nó vào thư mục LIB của project mà bạn đang phát triển.
• Download JDBC Driver cho database (cũng được build thành 1 tập tin JAR).
• Thêm các thành phần liên quan của Hibernate vào classpath.
1.2.2. Sử dụng
• Việc sử dụng Hibernate cũng rất đơn giản. Bạn cần gì ở một persistence layer? Đó là chúng sẽ truy xuất cũng như lưu trữ dữ liệu của bạn xuống database. Về mặt vật lý, theo mô hình dữ liệu quan hệ, dữ liệu của bạn sẽ bao gồm các thực thể (entity) có quan hệ với nhau. Và khi hiện thực cụ thể hơn mức database, chúng sẽ được đại diện bởi các table, bởi các ràng buộc khóa ngoại, khóa chính, … Hibernate cũng như vậy.
• Mỗi table trong database là một object trong Hibernate. Do đó, bạn cần có một java bean cho mỗi table trong database. Các java bean này sẽ có các getters / setters và một số ngoại lệ theo quy ước của Hibernate.
• Tiếp theo để Hibernate biết một object được “ánh xạ” (mapping) như thế nào với table trong database, Hibernate yêu cầu bạn cung cấp tập tin đặc tả gọi là mapping file. Theo quy ước của Hibernate, các mapping file này có đuôi là .hbm.xml và phải hợp lệ với DTD (Document Type Definition) mà Hibernate đã đưa ra. Trong các mapping file này, bạn sẽ đặc tả các mối quan hệ giữa property của object với field của table. Tức là bạn giúp cho Hibernate hiểu “mối quan hệ giữa các object” tương ứng như thế nào với “mối quan hệ giữa các field”.
• Tiếp theo nữa, bạn cần có 1 tập tin để Hibernate bắt đầu: hibernate.cfg.xml. Có thể nói tập tin này được load lên đầu tiên khi bạn “khởi động” Hibernate. Trong tập tin này, bạn đặc tả các thông tin sau:
SQL Dialects.
JDBC connection property: connection (url, driver class name, user name, password, pool size).
Hoặc là datasource property: datasource JNDI name, user name, password.
Hibernate configuration: show sql, …
Hibernate cache configuration.
Hibernate transaction configuration.
Miscellaneous configuration.
1.3. Các tập tin config
1.3.1. hibernate.cfg.xml
• Tập tin này bắt đầu bằng thẻ
• Thẻ
• Để định nghĩa các properties của session-factory, ta sử dụng thẻ
name của thẻ property là property của session-factory. Những properties của session-factory có thể là:
o hibernate.connection.driver_class
o hibernate.connection.url
o hibernate.connection.username
o hibernate.connection.password
o hibernate.connection.pool_size
o show_sql
o dialect
o hibernate.hbm2ddl.auto
o …
class là các giá trị của các properties của session-factory.
Ví dụ:
com.mysql.jdbc.Driver
• Để định nghĩa resouces của session-factory, ta sử dụng
resource là đường dẫn url của hbm.xml file.
1.3.2. hibernate.properties
Khai báo các properties trong 1 file tên là: hibernate.properties, chỉ cần đặt file này trong classpath của ứng dụng. Nó sẽ tự kiểm tra và đọc khi Hibernate khởi chạy lần đầu tiên, là khi tao 1 Configuaration object. Tương tự như hibernate.cfg.xml, hibernate.properties cũng để khai báo các thông số, nhưng hibernate.properties thường được kết hợp với spring config.
1.4. Tập tin hbm.xml – tập tin ánh xạ:
1.4.1. Cấu trúc cơ bản
• Bắt đầu bằng
• Từng bảng trong CSDL được đinh nghĩa bằng thẻ
name: là tên của lớp đối tượng dữ liệu (data object class) (của bảng tương ứng trong CSDL).
table: là tên của bảng trong CSDL.
• Thẻ
Thẻ
o name: là tên property của đối tượng dữ liệu (data object).
o column: là tên của cột trong CSDL.
o type: là kiểu dữ liệu của cột. Chú ý: đây là một kiểu của Hibernate chứ không phải của kiểu dữ liệu của Java hay của CSDL.
Thẻ
o Thẻ
Thẻ
1.4.2. Mapping types
Mapping types là những kiểu dữ liệu mà khi khai báo ở tập tin hbm.xml sẽ dược ánh xạ tương ứng. Hibernate có một số kiểu dữ liệu sẵn có mà Hibernate đã định nghĩa, goi là Built-in mapping types. Ngoài ra, bạn cụng có thể tự định nghĩa một kiểu riêng của bạn.
1.5. org.hibernate.cfg.Configuration
1.5.1. Configure()
Sử dụng các phép ánh xạ (mappings) và các đặc tính được xác định (properties specified) trong một tài nguyên ứng dụng (application resource) được đặt tên là hibernate.cfg.xml. Nhiều người thích tập trung cấu hình Hibernate bằng cách này thay vì thêm tham số vào Configuration trong code của ứng dụng.
1.5.2. addResource(String path)
Đọc các mappings trong một application resource (sử dụng cái này khi không muốn sử dụng file .cfg.xml để config).
1.5.3. addClass(java.lang.Class class)
Đọc mapping files của class đầu vào (ví dụ, có lớp User and và có User.hbm.xml, khi sử dụng addClass(User.class) nghĩa là thêm User.hbm.xml resource file vào Configuration).
1.5.4. setProperties(java.util.Properties)
Ta có thể class, driver, user, password (,…) để truy cập vào database bằng cách sử dụng .cfg.xml file hoặc .properties file. Khi sử dụng .properties file, phải sử dụng phương thức này để config.
1.6. org.hibernate.Session
1.6.1. Cách sử dụng
//open a session
Session session = sessionFactory.openSession();
//begin a transaction
Transaction tx = session.beginTransaction();
//
//do sth with session here
//
//commit
tx.commit();
//close session
session.close();
1.6.2. Rút trích một persistence object bằng id
Ví dụ lấy ra một user bằng id:
User user = session.get(User.class, new Long(100));
Nếu chúng ta sử dung phương thức này để lấy User với cùng id trong cùng session, phương thức này sẽ trả về một instance của User (không phải 2 instance).
Ví dụ:
User user1 = session.get(User.class, new Long(100));
User user2 = sessoon.get(User.class, new Long(100));
=> user1= user2
Ta có thể rút trích bằng phương thức load(). Sự khác biệt giữa phương thức load() và get() là ta có thể không rút trinh một đối tượng được trả về bởi phương thức load() khi session đã bị đóng (close).
1.6.3. lock()
Sau khi lấy một đối tượng từ CSDL, ta đóng session lại. Cái việc này sẽ làm cho đối tượng trở thành intacnce bị tách biệt (detached instance). Nó có thể được kết hợp lại (reassociated) với Session mới bằng cách gọi lock(). Phương thhức này sẽ ném ra một ngoại lệ là HibernateException khi nó không thể tìm thấy id trong CSDL bằng với id của đối tượng. HibernateException cũng sẽ bị ném khi bạn thay đổi id của đối tượng sau khi kết hợp lại.
Ví dụ:
Session session = sessionFactory.openSession();
User user = (User) session.get(User.class, new Long(100));
Session.close(); //user becomes detached
Session session2 = sessionFactory.openSession(); //another session
session2.lock(user, LockMode.NONE); //reassociated
1.6.4. Updating persistence objects
Các đối tượng được rút trích bởi phương thức session.load() hay session.get() đã được kết hợp với CSDL. Chúng ta chỉ cần set những giá trị mới và commit cái transaction để update. Objects that are reassociated are also the same.
Ví dụ:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = (User) session.get(User.class, new Long(100));
user.setName(“ABC”);
tx.commit();
session.close();
Detached objects có thể thường được cập nhật bởi phương thức update(). Các đối tượng được cập nhật cũng được kết hợp lại với session mới.
Ví dụ:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = (User) session.get(User.class, new Long(100));
user.setName(“ABC”);
tx.commit();
session.close();
// pretend that user has 2 properties, first is
// name, second is password; and the values by
// roster are “AAA” and “BBB”.
user.setName(“ABC”);//new name value
Session session2 = sessionFactory.openSession();
tx = session2.beginTransaction();
session2.update(user); //update and reassociated
user.setPassword(“EFG”);
tx.commit();
session2.close();
//the new values of user in turn of name and password are “ABC” and “EFG”
Một StaleStateException sẽ được ném khi ta cập nhật một đối tượng không tồn tại.
1.6.5. Insert
Để insert một đối tượng vào CSDL, ta sử dụng phương thức save(). Sau khi gọi phương thức này, đối tượng sẽ được kết hợp lại với session.
Ví dụ:
User user = new User();
user.setId(120);
user.setName(“Name”);
user.setPassword(“Password”);
Session session = sessionFactory.openSession();
Transaction tx = Session.beginTransaction();
session.save(user);
user.setName(“NewName”);
tx.commit();
session.close();
/* after executing the code above, in database, there is a row containing values as follow: id = 120, name = “NewName”, password = “Password” */
1.6.6. Delete
Để delete một dòng trong CSDL, ta phải đưa ra một đối tượng tương ứng với bảng trong CSDL. Nhưng ta không cần phải đưa hết giá trị vào các thuộc tính của đối tượng, ta chỉ cần set cái id của đối tượng. Phương thức này sẽ ném ra một ngoại lệ (StaleStateException) khi ta muốn xóa một đối tượng có id mà id này ko tồn tại trong CSDL.
Ví dụ:
User user = new User();
User.setId(100);
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.delete(user);
tx.commit();
session.close();
1.6.7. Ngoại lệ ConstraintViolationException
Khi bạn có gắng để save, update, delete những đối tượng mà sẽ xâm phạm các ràng buộc CSDL (như duplicate identifier, not-null constraint, unique constraint), ngoại lệ ConstraintViolationException sẽ được ném ra.
1.7. org.hibernate.Transaction
1.7.1. Understanding database transactions
• Một database transaction nhóm các thao tác truy cập dữ liệu. Một transaction sẽ kết thúc bằng một trong 2 cách sau đây: committed hoặc rolled back.
• Nếu có nhiều thao tác dữ liệu được thực thi trong một transaction, bạn phải đánh dấu chắc chắn cho từng công việc. Bạn phải start transaction, và ở 1 vài thời điểm, phải commit những thay đổi. Nếu có lỗi xảy ra (trong quá trình thực thi các thao tác hay trong lúc đang commit những thay đổi), bạn phải roll back transaction để đưa dữ liệu trở về tình trạng thích hợp. Việc này còn được gọi là transaction demarcation.
• Minh họa: tình trạng trong quá trình của một transaction
1.7.2. JDBC và JTA transactions
• Trong môi trường non-managed, JDBC API thường đánh dấu các giao tác. Bạn bắt đầu một transaction bằng cách gọi setAutoCommit(false) trong JDBC connection và kết thúc nó bằng cách gọi commit(). Đôi khi, bạn muốn ép nó rollback ngay lập tức thì có thể làm bằng cách gọi rollback().
• Trong hệ thống lưu trữ dữ liệu trên nhiều cơ sở dữ liệu, một công việc có thể truy cập đến nhiều hơn 1 kho dữ liệu. Trong trường hợp này, bạn không thể chỉ sử dụng JDBC một mình. Bạn cần phải có một transaction manager mà hỗ trợ transaction phân bố. Bạn có thể liên lạc với transaction manager bằng cách sử dụng JTA.
• Trong môi trường managed, JTA không chỉ sử dụng cho transaction phân bố mà còn sử dụng cho container managed transactions (CMT). CMT cho phép bạn ngăn ngừa được những transaction gọi trong source code của ứng dụng.
• Hibernate tác động tới database thông qua JDBC Connection. Vì thế nó hỗ trợ cả APIs. Trong một ứng dụng đơn lẻ, chỉ cần JDBC transaction là đủ, còn trong một ứng dụng server thì Hibernate có thể sử dụng JTA transaction. Như vậy, code Hibernate giổng cả 2 môi trường managed và non-managed. Hibernate cung cấn nhựng lớp trừu tượng bên của nó, được dấu bên dưới transaction API. Hibernate cho phép người sử dụng mở rộng bằng cách đưa thêm vào CORBA transaction service.
1.7.3. Hibernate Transaction API
• Transaction interface cung cấp những phương thức cho một database transaction. Xem ví dụ cơ bản dưới đây:
Session session = session.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
concludeAuction();
tx.commit();
} catch (Exception e) {
if (tx != null) {
try {
tx.rollback();
} catch (HibernateException he) {
// log he and rethrow e
}
}
throw e;
} finally {
try {
session.close();
} catch (HibernateException he) {
throw he;
}
}
• Việc gọi session.beginTransaction() là đánh dấu điểm bắt đầu của một một database transaction. Trong trường hợp là môi trường non-managed thì JDBC transaction sẽ bắt đầu trên JDBC connection. Còn trong môi trường managed, nó sẽ bắt đầu một JTA transaction mới nếu chưa có tồn tại JTA transaction, hoặc là kết hợp với JTA transaction đã tồn tại. Tất cả việc này đều được quản lý bởi Hibernate, nên bạn không cần phải quan tâm đến vấn đền này.
• Việc gọi tx.commit() đồng thời thay đổi tình trạng Session đối với cơ sở dữ liệu. Hibernate sẽ commit transaction bên dưới khi và chỉ khi beginTransaction() bắt đầu một transaction mới. Nếu beginTransaction() không bắt đầu một transaction bên dưới mới, commit() chỉ thay đởi tình trạng Session đối với cơ sở dữ liệu.
• Nếu concludeAuction() ném ra một ngoại lệ, chúng ta phải ép buộc transaction rollback bằng cách gọi tx.rollback().
1.8. Mối kết hợp (Association)
Có 2 mối kết hợp thường được sử dụng. Đó là many-to-one và one-to-many. (còn lại rất hiếm được sử dụng, đó là one-to-one và many-to-many).
1.8.1.
Có những thuộc tính và thẻ con sau:
• Child “column”: chứa tên thuộc tính để chỉ ra cái trường trong CSDL mà chứa khóa ngoại.
• Attribute “name”: tên của bảng trong CSDL mà được tham chiếu đến.
• Attribute “class”: đối tượng tương ứng của bảng trong CSDL mà được tham chiếu đến.
• Attribute “lazy”: nếu được set là true, nạp những đối tượng có liên quan từ CSDL mỗi lần nạp đối tượng này.
1.8.2.
Để chỉ ra quan hệ one-to-many, ta không chỉ đưa ra thẻ one-to-many. Mà còn có những thức khác để làm:
• Đầu tiên, ta phải sử dụng thẻ
• Trong thẻ này, ta phải chỉ ra các thuộc tính và các thẻ con sau:
Attribute “name”: tên của bảng tham chiếu đến bảng này.
Attribute “lazy”: nếu được set là true, nạp đối tượng liên quan từ CSDL mỗi lần nạp đối tượng này.
Child “key”: có thẻ con là column mà thuộc tính name của nó chứa cái tên của trường chứa khóa ngoại của bảng mà giữ cái id của bảng này.
Child “one-to-many”: chứa thuộc tính class để chỉ ra lớp tương ứng của bảng ngoại.
1.9. Simple Queries
1.9.1. HQL (Hibernate Query Language)
1.9.1.1. Tạo thể hiện
Để tạo một thể hiện của HQL, sử dụng session.createQuery(String)
1.9.1.2. Simple query
Ví dụ 1:
//get all records in table User.
Query query = session.createQuery("from User")
Ví dụ 2:
Query query = session.createQuery("from User u where u.name = :name");
query.setString("name", "THUAN");
Chú ý rằng User không phải là tên của bảng trong cơ sở dữ liệu. “User” là tên của đối tượng tương ứng với bảng đó. Và tên của những đối tượng này có phân biệt chữ hoa và chữ thường.
1.9.1.3. Kết bảng trong HQL
Một User chứa 1 tập hợp billings (có thuộc tính billings với accessor của nó). Trong mỗi billing, ta có 1 amount (số lượng). Bây giờ, ta muốn lấy tất cả User mà có billing chứa amount lớn hơn 100. Ta sử dũng HQL sau đây:
Query query = session.createQuery("from User user left join fetch user.billings billing where billing.amount > 100");
Chú ý rằng “billings” là tên của một thuộc tính trong cách thuộc tính của “User”. Và nó cũng có một getter và một setter cho billings.
1.9.1.4. Sub-query trong HQL
Ta muốn liệt ke toàn bộ user mà có billing (một vài user có thể không có billings). Ta sử dụng HQL sau đây:
Query query = session.createQuery("from User user where user in (select b.user from Billing B)");
Hoặc:
Query query = session.createQuery("from User user where exists (select 1 from user.billings)");
Chú ý rằng, sub-query trả về nhiều dòng. HQL cũng định nghĩa một số từ khóa để thu hẹp kết quả như: “in”, “all”, “any”, “some”.
1.9.1.5. Gom nhóm
Ví dụ:
Query query = session.createQuery("select count(*) from User");
Query query = session.createQuery("select b.user, sum(b.amount) from Billing b group by b.user");
1.9.2. Điều kiện (Criteria)
1.9.2.1. Tạo thể hiện
Để tạo một thể hiện của Criteria, sử dụng: session.createCriteria(User.class)
1.9.2.2. Add(Criterion)
Tìm trong trong các điều kiện, sử dụng phương thức: add(Criterion)
Ví dụ 1:
Criteria crit = session.createCriteria(User.class);
crit.add(Restrictions.eq("name", "Thuan"); //tìm user có name = 'Thuan'
Những phương thức dưới đây dùng để giới hạn tìm kiếm:
eq(String colName, String value): equal
gt(String colName, String value): greater than
ge(String colName, String value): greater than or equal
và …
Ví dụ: 2: lấy tất cả billing mà có amount nhỏ hơn 100 hoặc lớn hơn 1000
Criteria crit = session.createCriteria(Billing.class);
Crit.add(Restrictions.or(
Restrictions.lt("amount", 100),
Restrictions.gt("amount", 1000));
Sử dụng điều kiện “and” bằng cách tương tự như trên.
1.9.2.3. Kết
Ví dụ dưới đây sẽ lấy tất cả Users (và Billings của họ) mà có amount (của billing) lớn hơn 100.
Criteria crit = session.createCriteria(User.class);
crit.createCriteria("billings", "bill");
crit.add(Restrictions.gt("bill.amount", new Integer(100));
1.9.3. SQL
1.9.3.1. Tạo thể hiện
Đề tạo một thể hiện của SQL Query, sử dụng:
session.createSQLQuery(String).addEntity(String)
Ví dụ:
Query query = session.createSQLQuery("select * from User").addEntity(User.class);
1.9.3.2. SQLGrammaException
Nếu ta chỉ chọn từ User nhưng ta addEntity khác (ví dụ như Billing), Ngoại lệ SQLGrammaException sẽ được ném ra.
Ví dụ:
//SQLGrammaExeption will be thrown in the following code
Query query = session.createSQLQuery("select * from User").addEntity(User.class).addEntity(Billing.class);
1.9.3.3. Chọn nhiều bảng, chỉ addEntity một bảng
Nếu ta chọn từ nhiều bảng nhưng ta chỉ addEntity một bảng. Kiểu dữ liệu trả về chỉ là Entity đó.
Ví dụ:
Query query = session.createSQLQuery("select * from Billing b left join User u on u.ID = b.userID").addEntity(User.class);
//this query will return a List of User class.
1.9.3.4. Chọn nhiều bản, addEntity nhiều hơn 1 bảng
Nếu ta chọn từ nhiều bảng và ta addEntity nhiều hơn 1 bảng. Kiểu dữ liệu trả về là một mảng đối tượng chứa class theo thứ tự được add.
Ví dụ:
Query query = session.createSQLQuery("select * from Billing b left join User u on u.ID = b.userID")
.addEntity(User.class)
.addEntity(Billing.class);
Iterator iterator = query.list().iterator();
Object[] array;
User user;
Billing billing;
While (iterator.hasNext()) {
array = (Object[]) iterator.next();
User user = (User) array[0];
Billing billing = (Billing) array[1];
System.out.println("UserID = " + user.getId() + "; BillingID = " + billing.getId());
}
1.9.3.5. Gom nhóm
Ví dụ:
Query query = session.createSQLQuery("select count(1) userCount from User")
.addScalar("userCount", Hibernate.Integer);
Query query = session.createSQLQuery("select u.*, sum(b.amount) sumAmount from Billing b left join User u on u.ID = b.userID group by u.id")
.addEntity(User.class)
.addScalar("sumAmount", Hibernate.Integer);
Kiểu dữ liệu trả về là danh sách Object[2]. Object[0] là giá trị của phương thức addScalar method, kế tiếp là giá trị của phương thức addEntity.
1.9.4. Giới hạn kết quả trả về
Để giới hạn kết quả trả về, ta sử dụng 2 phương thức: setMaxResults(int) và setFirstResult(int).
2 phương thức này đều được thi hành bởi Criteria và Query
2.1. Khái niệm bean trong Spring
2.1.1. Cách khai báo 1 bean
• Bắt đầu trong spring là bằng thẻ
Singleton cho biết bean này chỉ được khởi tạo lên 1 lần. Mặc định singleton="true" (vì phần lớn controller chỉ cần khởi tạo 1 lần).
2.1.2.
• Ta có thể dùng tag property để set giá trị cho attribute của lớp và dùng tag contructor-arg để chỉ định contructor mà mình muốn dùng.
• Ví dụ, ta có class MyBean như sau:
package mypring;
public class MyBean {
private int myInt;
private List myList;
public MyBean(int myInt) {
this.myInt = myInt;
}
public void setMyInt(int myInt) {
this.myInt = myInt;
}
public int getMyInt() {
return this.myInt;
}
public void setMyList(List myList) {
this.myList = myList;
}
public List getMyList() {
return this.myList;
}
}
• Ta sẽ khai báo bean như sau:
2.1.3.
• Một bean cũng có thể chứa bean khác bằng cách dùng tag ref:
Không có nhận xét nào:
Đăng nhận xét