EJB的持久性

2018-12-07 14:44 更新

EJB 3,实体bean使用EJB 2很大程度上是由持久化机制取代。现在实体Bean是一种简单的POJO映射表。

以下是持续性的关键参与者的API:


1、实体 - 表示数据存储记录的持久化对象。它能很好的进行“可串行化”。


2、EntityManager坚持做界面的数据操作如添加/删除/更新/持久对象发现(实体)。它也有助于使用查询接口执行查询


3、持久性单元(persistence.xml)  持久性单元描述了持久性机制的属性。

4、数据源(* ds.xml) - 数据源描述了数据存储相关的属性,比如URL链接。用户名,密码等。


为了演示EJB持久化机制,我们将执行以下任务:


步骤1.在数据库中创建表。

步骤2.创建与表对应的Entity(实体)类。

步骤3.创建数据源和持久性单元

步骤4.创建一个具有无状态EJB的EntityManager(依赖注入)实例。

步骤5.更新无状态EJB。添加方法为通过实体管理器添加记录,并从数据库中获取记录。

步骤6.基于控制台的应用程序客户端将访问无状态的EJB以将数据保存到数据库中。

创建表

创建一个tablebooksin默认databasepostgres。

CREATE TABLE books(id     integer PRIMARY KEY,name   varchar(50));

创建实体类

//mark it entity using Entity annotation//map table name using Table annoation@Entity@Table(name="books")publicclassBookimplementsSerializable{privateintid;privateStringname;publicBook(){}//mark id as primary key with autogenerated value//map database column id with id field@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="id")publicintgetId(){returnid;}...}

创建数据源和存储单元

数据源(jboss-ds.xml)
<?xml version="1.0"encoding="UTF-8"?><datasources><local-tx-datasource><jndi-name>PostgresDS</jndi-name><connection-url>jdbc:postgresql://localhost:5432/postgres</connection-url><driver-class>org.postgresql.driver</driver-class><user-name>sa</user-name><password>sa</password><min-pool-size>5</min-pool-size><max-pool-size>20</max-pool-size><idle-timeout-minutes>5</idle-timeout-minutes></local-tx-datasource></datasources>

持久性单元(persistence.XML)
<persistenceversion="1.0"xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"><persistence-unitname="EjbComponentPU"transaction-type="JTA"><jta-data-source>java:/PostgresDS</jta-data-source><exclude-unlisted-classes>false</exclude-unlisted-classes><properties/></persistence-unit><persistence-unitname="EjbComponentPU2"transaction-type="JTA"><provider>org.hibernate.ejb.HibernatePersistence</provider><jta-data-source>java:/PostgresDS</jta-data-source><exclude-unlisted-classes>false</exclude-unlisted-classes><properties><propertyname="hibernate.hbm2ddl.auto"value="update"/></properties></persistence-unit></persistence>

创建无状态有EntityManager的EJB实例
@StatelesspublicclassLibraryPersistentBeanimplementsLibraryPersistentBeanRemote{//pass persistence unit to entityManager.@PersistenceContext(unitName="EjbComponentPU")privateEntityManagerentityManager;publicvoidaddBook(Bookbook){entityManager.persist(book);}publicList<Book>getBooks(){returnentityManager.createQuery("From Books").getResultList();}...}

在构建EJB模块之后,我们需要一个客户端来访问无状态bean,我们将在下一节中创建它。

示例应用程序

让我们创建一个测试EJB应用程序来测试EJB持久化机制。

StepDescription
1在EJB - 创建一个Applicationchapter中解释的packagecom。再在tutorialspoint.entity下创建一个名为EJB Component的项目。 您还可以使用在EJB中创建的项目 - 创建Applicationchapter,以便了解本章EJB持久性概念
2CreateBook.javaunder packagecom.tutorialspoint.entityand修改如下所示。
3CreateLibraryPersistentBean.javaandLibraryPersistentBeanRemoteas在EJB中解释 - 创建Applicationchapter并修改它们如下所示。
4Createjboss-ds.xmlinEjbComponent> setupfolder andpersistence.xmlinEjbComponent> src> conffolder。 这些文件夹可以在Netbeans中的文件选项卡中看到。 修改这些文件,如上所示。
5清理并构建应用程序以确保业务逻辑按照要求工作。
6最后,在JBoss Application Server上以jar文件的形式部署应用程序。 如果JBoss应用程序服务器尚未启动,它将自动启动。
7现在创建EJB客户端,一个基于控制台的应用程序,其方式与在EEB - 在ApplicationCreate Client下创建Applicationchapter以访问EJB中说明的方式相同。 修改它如下所示。

EJBC组件(EJB模块)

Book.java
packagecom.tutorialspoint.entity;importjava.io.Serializable;importjavax.persistence.Column;importjavax.persistence.Entity;importjavax.persistence.EntityListeners;importjavax.persistence.GeneratedValue;importjavax.persistence.GenerationType;importjavax.persistence.Id;importjavax.persistence.Table;@Entity@Table(name="books")publicclassBookimplementsSerializable{privateintid;privateStringname;publicBook(){}@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="id")publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}}

LibraryPersistentBeanRemote.java
packagecom.tutorialspoint.stateless;importcom.tutorialspoint.entity.Book;importjava.util.List;importjavax.ejb.Remote;@RemotepublicinterfaceLibraryPersistentBeanRemote{voidaddBook(BookbookName);List<Book>getBooks();}

LibraryPersistentBean.java
packagecom.tutorialspoint.stateless;importcom.tutorialspoint.entity.Book;importjava.util.List;importjavax.ejb.Stateless;importjavax.persistence.EntityManager;importjavax.persistence.PersistenceContext;@StatelesspublicclassLibraryPersistentBeanimplementsLibraryPersistentBeanRemote{publicLibraryPersistentBean(){}@PersistenceContext(unitName="EjbComponentPU")privateEntityManagerentityManager;publicvoidaddBook(Bookbook){entityManager.persist(book);}publicList<Book>getBooks(){returnentityManager.createQuery("From Book").getResultList();}}

1、在JBOSS上部署EjbComponent项目后,请注意jboss日志。

2、JBossJBoss已经为LibraryPersistentBean  / remote自动创建了一个JNDI条目。

3、我们将使用这个查找字符串来获取类型为-com.tutorialspoint.stateless.LibraryPersistentBeanRemote的远程业务对象。

JBoss应用程序服务器日志输出
...16:30:01,401INFO[JndiSessionRegistrarBase]Bindingthe followingEntriesinGlobalJNDI:LibraryPersistentBean/remote-EJB3.xDefaultRemoteBusinessInterfaceLibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote-EJB3.xRemoteBusinessInterface16:30:02,723INFO[SessionSpecContainer]Startingjboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB316:30:02,723INFO[EJBContainer]STARTED EJB:com.tutorialspoint.stateless.LibraryPersistentBeanRemoteejbName:LibraryPersistentBean16:30:02,731INFO[JndiSessionRegistrarBase]Bindingthe followingEntriesinGlobalJNDI:LibraryPersistentBean/remote-EJB3.xDefaultRemoteBusinessInterfaceLibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote-EJB3.xRemoteBusinessInterface...

EJBTester(EJB客户端)

jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactoryjava.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfacesjava.naming.provider.url=localhost
1、这些属性用于初始化java命名服务的InitialContext对象

2、InitialContext对象将用于查找无状态会话bean

ejbtester.java
packagecom.tutorialspoint.test;importcom.tutorialspoint.stateless.LibraryPersistentBeanRemote;importjava.io.BufferedReader;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStreamReader;importjava.util.List;importjava.util.Properties;importjavax.naming.InitialContext;importjavax.naming.NamingException;publicclassEJBTester{BufferedReaderbrConsoleReader=null;Propertiesprops;InitialContextctx;{props=newProperties();try{props.load(newFileInputStream("jndi.properties"));}catch(IOExceptionex){ex.printStackTrace();}try{ctx=newInitialContext(props);}catch(NamingExceptionex){ex.printStackTrace();}brConsoleReader=newBufferedReader(newInputStreamReader(System.in));}publicstaticvoidmain(String[]args){EJBTesterejbTester=newEJBTester();ejbTester.testEntityEjb();}privatevoidshowGUI(){System.out.println("**********************");System.out.println("Welcome to Book Store");System.out.println("**********************");System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");}privatevoidtestEntityEjb(){try{intchoice=1;LibraryPersistentBeanRemotelibraryBean=LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");while(choice!=2){StringbookName;showGUI();StringstrChoice=brConsoleReader.readLine();choice=Integer.parseInt(strChoice);if(choice==1){System.out.print("Enter book name: ");bookName=brConsoleReader.readLine();Bookbook=newBook();book.setName(bookName);libraryBean.addBook(book);}elseif(choice==2){break;}}List<Book>booksList=libraryBean.getBooks();System.out.println("Book(s) entered so far: "+booksList.size());inti=0;for(Bookbook:booksList){System.out.println((i+1)+". "+book.getName());i++;}}catch(Exceptione){System.out.println(e.getMessage());e.printStackTrace();}finally{try{if(brConsoleReader!=null){brConsoleReader.close();}}catch(IOExceptionex){System.out.println(ex.getMessage());}}}}

EJBTester正在执行以下任务。

从jndi.properties加载属性并初始化InitialContext对象。

在testStatefulEjb()方法中,使用name - “LibraryStatefulSessionBean / remote”来完成jndi查找,以获取远程业务对象(有状态的ejb)。

然后用户显示图书馆商店用户界面,他/她被要求输入选择。

如果用户输入1,系统要求书名并使用无状态会话bean addBook()方法保存书。 会话Bean通过EntityManager在数据库中持久化调用这本书。

如果用户输入2,系统使用有状态会话Bean getBooks()方法检索书籍并退出。

然后,使用name - “LibraryStatelessSessionBean / remote”进行另一个jndi查找,以再次获取远程业务对象(无状态ejb),并完成书目列表。


运行客户端以访问EJB

在项目资源管理器中找到EJBTester.java。 右键单击EJBTester类和selectrun文件。

在Netbeans控制台中验证以下输出。
run:**********************WelcometoBookStore**********************Options1.AddBook2.ExitEnterChoice:1Enterbook name:LearnJava**********************WelcometoBookStore**********************Options1.AddBook2.ExitEnterChoice:2Book(s)entered so far:11.learn javaBUILD SUCCESSFUL(total time:15seconds)

再次运行客户端以访问EJB

在访问EJB之前重新启动JBoss。

在项目资源管理器中找到EJBTester.java。 右键单击EJBTester类和selectrun文件。

在Netbeans控制台中验证以下输出。
run:**********************WelcometoBookStore**********************Options1.AddBook2.ExitEnterChoice:1Enterbook name:LearnSpring**********************WelcometoBookStore**********************Options1.AddBook2.ExitEnterChoice:2Book(s)entered so far:21.learn java2.LearnSpringBUILD SUCCESSFUL(total time:15seconds)
上面显示的输出表明,书籍存储在持久性存储中,并从数据库中检索可以到。
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号