EJB - Mối quan hệ thực thể
EJB 3.0 cung cấp tùy chọn để xác định các mối quan hệ / ánh xạ thực thể cơ sở dữ liệu như một-một, một-nhiều, nhiều-một và nhiều-nhiều.
Sau đây là các chú thích có liên quan -
One-to-One- Các đối tượng có mối quan hệ 1-1. Ví dụ, một hành khách có thể sử dụng một vé duy nhất tại một thời điểm.
One-to-Many- Các đối tượng có mối quan hệ một - nhiều. Ví dụ, một người cha có thể có nhiều con.
Many-to-One- Các đối tượng có mối quan hệ nhiều-một. Ví dụ, nhiều trẻ em có một người mẹ đơn thân.
Many-to-Many- Các đối tượng có mối quan hệ nhiều-nhiều. Ví dụ, một cuốn sách có thể có nhiều tác giả và một tác giả có thể viết nhiều cuốn sách.
Chúng tôi sẽ trình bày việc sử dụng bản đồ ManyToMany tại đây. Để biểu diễn mối quan hệ ManyToMany, cần có ba bảng sau:
Book - Bàn sách, có hồ sơ sổ sách.
Author - Bảng tác giả, có ghi tác giả.
Book_Author - Bảng Tác giả Sách, có liên kết giữa Sách và Bảng Tác giả nêu trên.
Tạo bảng
Tạo bảng book author, book_author trong cơ sở dữ liệu mặc định postgres.
CREATE TABLE book (
book_id integer,
name varchar(50)
);
CREATE TABLE author (
author_id integer,
name varchar(50)
);
CREATE TABLE book_author (
book_id integer,
author_id integer
);
Tạo lớp thực thể
@Entity
@Table(name="author")
public class Author implements Serializable{
private int id;
private String name;
...
}
@Entity
@Table(name="book")
public class Book implements Serializable{
private int id;
private String title;
private Set<Author> authors;
...
}
Sử dụng chú thích ManyToMany trong Thực thể Sách.
@Entity
public class Book implements Serializable{
...
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
, fetch = FetchType.EAGER)
@JoinTable(table = @Table(name = "book_author"),
joinColumns = {@JoinColumn(name = "book_id")},
inverseJoinColumns = {@JoinColumn(name = "author_id")})
public Set<Author> getAuthors() {
return authors;
}
...
}
Ứng dụng mẫu
Hãy để chúng tôi tạo một ứng dụng EJB thử nghiệm để kiểm tra các đối tượng mối quan hệ thực thể trong EJB 3.0.
Bươc | Sự miêu tả |
---|---|
1 | Tạo một dự án với tên EjbComponent trong một gói com.tutorialspoint.entity như được giải thích trong chương EJB - Tạo ứng dụng . Vui lòng sử dụng dự án được tạo trong chương EJB - Persistence như vậy cho chương này để hiểu các đối tượng nhúng trong khái niệm EJB. |
2 | Tạo Author.java trong gói com.tutorialspoint.entity như được giải thích trong chương EJB - Tạo ứng dụng . Giữ phần còn lại của các tệp không thay đổi. |
3 | Tạo Book.java trong gói com.tutorialspoint.entity . Sử dụng chương EJB - Persistence làm tài liệu tham khảo. Giữ phần còn lại của các tệp không thay đổi. |
4 | Làm sạch và xây dựng ứng dụng để đảm bảo logic nghiệp vụ đang hoạt động theo yêu cầu. |
5 | Cuối cùng, triển khai ứng dụng dưới dạng tệp jar trên Máy chủ ứng dụng JBoss. Máy chủ ứng dụng JBoss sẽ tự động khởi động nếu nó chưa được khởi động. |
6 | Bây giờ tạo ứng dụng khách EJB, một ứng dụng dựa trên bảng điều khiển theo cách tương tự như đã giải thích trong chương EJB - Tạo ứng dụng theo chủ đềCreate Client to access EJB. |
EJBComponent (Mô-đun EJB)
Author.java
package com.tutorialspoint.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="author")
public class Author implements Serializable{
private int id;
private String name;
public Author() {}
public Author(int id, String name) {
this.id = id;
this.name = name;
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="author_id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return id + "," + name;
}
}
Book.java
package com.tutorialspoint.entity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@Entity
@Table(name="book")
public class Book implements Serializable{
private int id;
private String name;
private Set<Author> authors;
public Book() {
}
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="book_id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
, fetch = FetchType.EAGER)
@JoinTable(table = @Table(name = "book_author"),
joinColumns = {@JoinColumn(name = "book_id")},
inverseJoinColumns = {@JoinColumn(name = "author_id")})
public Set<Author> getAuthors() {
return authors;
}
}
LibraryPersistsBeanRemote.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;
@Remote
public interface LibraryPersistentBeanRemote {
void addBook(Book bookName);
List<Book> getBooks();
}
LibraryPersistsBean.java
package com.tutorialspoint.stateless;
import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
public LibraryPersistentBean() {
}
@PersistenceContext(unitName="EjbComponentPU")
private EntityManager entityManager;
public void addBook(Book book) {
entityManager.persist(book);
}
public List<Book> getBooks() {
return entityManager.createQuery("From Book").getResultList();
}
}
Ngay sau khi bạn triển khai dự án EjbComponent trên JBOSS, hãy để ý nhật ký jboss.
JBoss đã tự động tạo một mục nhập JNDI cho bean phiên của chúng tôi - LibraryPersistentBean/remote.
Chúng tôi sẽ sử dụng chuỗi tra cứu này để lấy đối tượng nghiệp vụ từ xa thuộc loại - com.tutorialspoint.interceptor.LibraryPersistentBeanRemote
Đầu ra nhật ký máy chủ ứng dụng JBoss
...
16:30:01,401 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...
EJBTester (Khách hàng EJB)
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
Các thuộc tính này được sử dụng để khởi tạo đối tượng InitialContext của dịch vụ đặt tên java.
Đối tượng InitialContext sẽ được sử dụng để tra cứu bean phiên không trạng thái.
EJBTester.java
package com.tutorialspoint.test;
import com.tutorialspoint.stateful.LibraryBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EJBTester {
BufferedReader brConsoleReader = null;
Properties props;
InitialContext ctx;
{
props = new Properties();
try {
props.load(new FileInputStream("jndi.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
ctx = new InitialContext(props);
} catch (NamingException ex) {
ex.printStackTrace();
}
brConsoleReader =
new BufferedReader(new InputStreamReader(System.in));
}
public static void main(String[] args) {
EJBTester ejbTester = new EJBTester();
ejbTester.testEmbeddedObjects();
}
private void showGUI() {
System.out.println("**********************");
System.out.println("Welcome to Book Store");
System.out.println("**********************");
System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
}
private void testEmbeddedObjects() {
try {
int choice = 1;
LibraryPersistentBeanRemote libraryBean =
(LibraryPersistentBeanRemote)
ctx.lookup("LibraryPersistentBean/remote");
while (choice != 2) {
String bookName;
String authorName;
showGUI();
String strChoice = brConsoleReader.readLine();
choice = Integer.parseInt(strChoice);
if (choice == 1) {
System.out.print("Enter book name: ");
bookName = brConsoleReader.readLine();
System.out.print("Enter author name: ");
authorName = brConsoleReader.readLine();
Book book = new Book();
book.setName(bookName);
Author author = new Author();
author.setName(authorName);
Set<Author> authors = new HashSet<Author>();
authors.add(author);
book.setAuthors(authors);
libraryBean.addBook(book);
} else if (choice == 2) {
break;
}
}
List<Book> booksList = libraryBean.getBooks();
System.out.println("Book(s) entered so far: " + booksList.size());
int i = 0;
for (Book book:booksList) {
System.out.println((i+1)+". " + book.getName());
System.out.print("Author: ");
Author[] authors = (Author[])books.getAuthors().toArray();
for(int j=0;j<authors.length;j++) {
System.out.println(authors[j]);
}
i++;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
if(brConsoleReader !=null) {
brConsoleReader.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
}
EJBTester thực hiện các tác vụ sau:
Tải các thuộc tính từ jndi.properties và khởi tạo đối tượng InitialContext.
Trong phương thức testInterceptedEjb (), việc tra cứu jndi được thực hiện với tên - "LibraryPersistenceBean / remote" để lấy đối tượng nghiệp vụ từ xa (EJB không trạng thái).
Sau đó, người dùng được hiển thị Giao diện Người dùng trong kho thư viện và họ được yêu cầu nhập một lựa chọn.
Nếu người dùng nhập 1, hệ thống sẽ hỏi tên sách và lưu sách bằng phương thức addBook () phiên đậu không trạng thái. Phiên Bean đang lưu trữ sách trong cơ sở dữ liệu.
Nếu người dùng nhập 2, hệ thống sẽ truy xuất sách bằng phương thức getBooks () của phiên đậu không trạng thái và thoát.
Chạy ứng dụng khách để truy cập EJB
Định vị EJBTester.java trong trình khám phá dự án. Nhấp chuột phải vào lớp EJBTester và chọnrun file.
Xác minh kết quả sau trong bảng điều khiển Netbeans.
run:
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 1
Enter book name: learn html5
Enter Author name: Robert
**********************
Welcome to Book Store
**********************
Options
1. Add Book
2. Exit
Enter Choice: 2
Book(s) entered so far: 1
1. learn html5
Author: Robert
BUILD SUCCESSFUL (total time: 21 seconds)