J2EE development practices based on JBoss in the Win2K environment - 4: BMP entity bean writing and design

zhaozj2021-02-16  57

J2EE development practices based on JBoss in the Win2K environment - 4: BMP entity bean writing and design instructions: This tutorial is published in the 9CBS.NET website (China Programmer Network) Document Center, anyone reproduces please indicate the source, And keep this description. After publishing this series of articles, many netizens have to believe that the author will continue to write this tutorial, the author first thanks to the trust of netizens! Author's contact address is: josserchai@yahoo.com. Foreword: In the "J2EE Development Practice Based on the" Win2K Environment "series, I will implement EJB development through the use of any automation tools, we write EJB classes in the whole process, configure the container environment and Write a deployment document file, so that everyone understands the development process of EJB in learning EJB development process and master it. In the previous three sections, we led everyone to configure the development environment and database connection pool and demonstrated how to develop sessionBean methods. In this section, we will learn how to develop entity beans. I. Entity Bean Programming Based on the Object-Oriented Multi-layer configuration architecture of J2EE, we usually use the following two components: 1. Apply logical components, they are the method provider of the public task, they are completed Work We can understand that it is a short process, such as calculating the price of a order, calculating a solution of an equation. Session beans can complete these applications well, and session beans often contain operational logic used to perform application tasks, which represents one customer's operation or a user session process with user workflow logic. 2, persistent data components, it is an object in multi-layer business applications, such as accounts, business customers, etc. in bank applications. These objects represent data you may need to save in business applications. Such as: You have written an Account class, which represents a bank account, an object instance that represents a specific account in the bank. Maybe you will doubt whether this object component is useful, you may ask: Why can't I store these data directly into the table of the database? If you put your account information in a database table, we need to use it, why do you want to use these object components? There are two points: First, we regard this data as an object to make us operate and manage them very conveniently, and they behave as a compact form of a class. Second, we can use these intermediate objects to increase data to the performance of access data in the cache of the container, and we can get better associations, transactions, and security from the container. Entity beans are these persistent data components, which are between databases and user applications, managed by the container to manage data interactions between them and databases. We can simply understand that entity beans are cache data between databases and user applications. It is in memory of a web container, and its expression is not like a row of rows like a database, its expression is An object instance, an object instance of an entity bean class in a container represents a record in the database. The entity bean does not perform complex tasks or workflow logic because they own the data, which is the object of persistent state. For example: We have to create a bank account, which has three domains: account ID, account household name, account on account. Under normal circumstances, we can insert a line record in the Accounts table of the database. After using the entity bean, we create an account class in memory, which has three properties, then we instantiate an object of the class, which represents a specific account in memory.

That is, we first load the data into memory, then you can handle this memory in memory and change it. At this time, you can do a Java object instead of a lot of database records, such as: You changed the balance of the account At this time, the EJB container automatically maps you to the object's change to the corresponding database record, which is executed by the container. That is, we are responsible for changing the objects of these representative data, the EJB container is responsible for synchronization between these objects and database records. Specifically, how is it synchronized with entity bean objects and data records? This synchronization process requires us to understand the life cycle of entity beans. We briefly describe the synchronization process as follows: When we create an entity bean in the EJB container, the container reads a data record (EjbLoad) to this entity A specific entity bean object is formed in the attribute domain of the bean, and then we can call some methods of this entity bean to operate its data. When this bean object changes, the container is called entity when the data value of this bean object changes. A method of bean's EJBStore () will be updated to the table after the changed data; when the value in the database table changes, when the data value of the entity bean object in the current memory is inconsistent (as we directly change the database record) ), The EJB container is automatically called an EJBLOAD () of the entity bean to reload the values ​​in the database into the properties field of entity beans. When we delete an entity bean object instance in the EJB container, the container is called an EJBREMOVE () of the entity bean. In this method, the data of the entity bean is stored in the database table. At the same time, because there may be many records in the database, all we may have many instance objects of many corresponding entity beans in the EJB container, then what way do we use to distinguish these entity bean instance objects? Just like the primary key in the database table. The answer is: We also give each entity bean a primary key to distinguish these entity bean objects with its primary key. For example, an object of a bank account we can use the account ID to distinguish them. Similarly, we can also find entity bean objects like finding database records, which requires us to write a lookup method. In the entity bean, there is also a phenomenon of passivation, activation in SessionBean, which is then called the EJBActivate () and EJBPassivate () methods of the entity bean, respectively. In order to achieve recording consistency with the database, EJBStore () should be called before the EJBPassivate () method; the EjbLoad () method should be called immediately after the EJBACTIVE () method. In the EJB2.0 specification, the entity bean includes two, namely, the container-managed entity bean and bean itself management entity beans. Both differences: Bean self-managed entity bean is implemented by our bean writer to implement the EJBLOA () and EJBStore (), which controls how to go to EJBLOAD and EJBStore. The accommodation-managed entity bean does not need to write ejbload () and EJBStore (), and automatically implement these processes by the container. Second, the writing method of BMP entity bean and example BMP entity bean writing BMP entity bean and writing sessionbean substantially the same, but there are more things, and more is: writing primary key classes and writing finding entity beans. Finding methods. At the same time, we also ask yourself to implement EjbLoad () and EJBStore.

Below we will come to instance to be a BMP entity bean, which uses a BEAN that represents a bank account, and we define a bank account has three domains: account ID, household name, and account amount, where account ID is the primary key. First we build a database name TEST in the MySQL database, then build a table accunts in this library, the following SQL statement can be implemented: Create Table Accounts (ID VARCHAR (64), Ownername Varchar (64), Balance Double 13, 2), Primary Key ('ID')); then we need to configure the JBoss database connection pool so we connect to the database in the BMP entity bean, we use the mysql database here, see the series of tutorials Section 2, the specific is to create a new mysql-ds.xml file in the jboss / server / all / deploy / directory, the content is as follows: mysql jdbc: mysql: //10.0.0.18: 3306 / test org.gjt. mm.mysql.driver root Note IP and database in the above file The username and password are the same as yourself. Below we will start to write our entity bean. Similarly, we first build a working directory to store all the files before our entity bean. As shown in the previous section, all directories are built in the MyProject directory in the JBoss directory. The creation of the directory is as follows: Built a MyProject directory in the JBoss installation directory, if you built it in the previous section, you can not build, then build an AccountBMP directory in myProject directory to store all the files of this bean; then Enjoy a new EJB directory and a src directory in the AccountBMP directory, then create a new Account.jar directory and a client directory in the EJB directory. Then create an Account Directory in the Account.jar directory and a meta-inflicity and new EJB directory below; Similarly, create a new Account directory in the cient directory and build an EJB directory under Account. The built-in directory structure is shown in Figure 1: Figure 1 Next, let's write our bank account entity bean, enter the src directory, all source files are placed in this directory.

The first step in the preparation Remote Interface: //Account.javapackage account.ejb; import javax.ejb *; import java.rmi.RemoteException; public interface Account extends EJBObject {// business methods public void storeinto (double amt) throws AccountException,. RemoteException; public void getout (double amt) throws AccountException, RemoteException; // get on entity Bean / setter methods public double getBalance () throws RemoteException; public void setBalance (double balance) throws RemoteException; public String getOwnerName () throws RemoteException; public void setOwnerName (String name) throws RemoteException; public String getAccountID () throws RemoteException; public void setAccountID (String id) throws RemoteException;} we can see that in this method, we threw out a AccountException own definition of abnormal we here give its code is as follows: //AccountException.javapackage account.ejb; // custom exception class public class AccountException extends exception {public AccountException () {super ();} public AccountException (exception e) {super (e.tostring ());} public accountException (String s) {super (s);}} then we write Home interface, as shown below: //accounthome.javaPackage Account.ejb; i mport javax.ejb *;. import java.util.Collection; import java.rmi.RemoteException; public interface AccountHome extends EJBHome {Account create (String accountID, String ownerName, double balance) throws CreateException, RemoteException; public Account findByPrimaryKey (AccountPK key ) throws FinderException, RemoteException; public Collection findByOwnerName (String name) throws FinderException, RemoteException; // this method is independent of all of the accounts (i.e., EJB instance) public double getTotalBankValue () throws AccountException, RemoteException;} Note: in the above Home interface In, we define three findings, usually, we define the method of finding entity beans in the HOME interface, define business methods in the Remote interface, and they are all implemented in the bean class.

Moreover, we have to play the name of the lookup method for FindByxxxx (), this lookup method is associated with an entity bean object, if we need other search methods, you can define the name, such as getTotalbankValue above ) Method, and we have to pay attention to: The name here is naming in the bean implementation. In general, each BMP must define a FindByPrimaryKey () method. Next, let's write the primary key class of this entity bean, the lattice format is fixed, as shown below: //accountpk.javaPackage Account.ejb; import java.io.serializable; // Primary key PUBLIC CLASS Accountpk Implements java.io .Serializable {public String accountID; public AccountPK (String id) {this.accountID = id;} public AccountPK () {} public String toString () {return accountID;} public int hashCode () {return accountID.hashCode (); } Public Boolean Equals (Object Account) {Return ((Accountpk) Accent) .accountid.equals (this.accountid);}} The three methods must be implemented. Then, let's implement our entity bean class, it is very long, I hope not to think that it has a suspicion of the number of words. This class consists of four parts: SETTER / GETTER method, the method, business method and finding method, the business method, and the search method, which is a self-explanatory class, all of which are placed in the program. Package account.ejb; // The following introduces the necessary package import java.sql. *; import javax.naming. *; import javax.ejb. *; import java.util. *; // BMP entity bean, it represents the bank One account public class accountbean implements entityBean {// The following is the first part, define domains, and setter / getter methods protected entryContext CTX; // Defines the status domain of BMP management, which corresponds to the fields in the database.

private String accountID; // primary key private String ownerName; // the name of the primary account private double balance; // amount on account // constructor public AccountBean () {System.out.println ( "New Bank Account EntityBean Object created by JBOSS Container. ");} // Entity Bean Domain Wield / Setter Method PUBLIC DOUBLE GETBALANCE () {Return this.balance;} public void setBalance (double balance) {this.balance = Balance;} public void setownername String name) {this.ownerName = name;} public String getOwnerName () {return this.ownerName;} public String getAccountID () {return this.accountID;} public void setAccountID (String id) {this.accountID = id;} Public void setentityContext (entityContext CTX) {this.ctx = CTX;} public entryContext getentityContext () {return this.ctX;} // The following is the second part, implement the method // EJB of the container // EJB, they are Public void ejbactivate () {system.out.println ("ejbactivate () Called (" ejbactivate () Called ("ejbactivate () Called (" ejbctivate) ("ejbctivate () (" ejbPassivate () Called ! ");} // Public void ejbremove () THROWS RemoveException {system.out.println (" Ejbremove () Called! ");} // From database loading to keep synchronous public void ejbl OAD () {system.out.println ("EjbLoad () Called!"); // Query the entity environment to get the primary key of the current entity bean object so that we know which instance to load this.ctX this.ctx.getPrimaryKey (); String id = pk.accountid; preparedStatement pstmt = null; connection conn = null; try {conn = getConnection (); // This is the method of our own definition, see it, it is obtained from the connection pool // passed Use the account ID query, get the account from the database PSTMT = conn.preparestatement ("SELECT OWNERNAME, Balance from Accounts WHERE ID =?"); PSTMT.SetString (1, ID); ResultSet RS = PStmt.executeQuery (); rs. Next (); // Save the results of the query to the entity bean object domain this.OwnerName = rs.getstring ("ownername"); this.balance = rs.getdouble ("balance");

} catch (exception ex) {throw new ejbexception ("Account" PK "Failed to Load from Database", EX);} finally {try {if (pstmt! = null) PSTMT.Close ();} catch (Exception e) {} try {if (conn! = null) conn.close ();} catch (exception e) {}}} // updated database, timely reflecting the current value of entity bean instance in this memory, PUBLIC VOID EJBSTORE ( ) {System.out.println ("EJBStore () Called!"); PreparedStatement PSTMT = NULL; connection conn = null; try {conn = getConnection (); // put the value of the current entity bean to save, Timely update database PSTMT = conn.preparestatement ("Update Accounts Set OwnerName"); pstmt.setstring (1, this.Ownername); PSTMT.SetDouble (2, this.balance); PSTMT .SetString (3, this.accountid); PSTMT.ExecuteUpdate ();} catch (exception ex) {throw new ejbexception ("Account" Accountid "Failed to Save to Database", EX);} Finally {Try { (PSTMT! = null) pstmt.close ();} catch (exception e) {} try {if (conn! = null) conn.close ();} catch (exception e) {}}} // Container call, Separate this Bean instance with a specific environment object, fixed method public void unsentityContext () {system.out.println ("unsenetityContext () Called!"); This.ctx = null;} // After the ejbcreate call ,fixed Method public void ejbPostCreate (String accountID, String ownerName, double balance) {} // This is the corresponding Home interface create () method returns to the main key public AccountPK ejbCreate this account (String accountID, String ownerName, double balance) THROWS CREATEEXCEPTION {PreparedStatement PSTMT = NULL; Connection Conn = NULL; Try {// Incoming the parameters incorporated when the client calls, creating an entity bean instance system.out.println ("Ejbcreate () Called!"); this.accountid = Accountid; this.OwnerName = OwnerName; this.balance = Balance; conn = getConnection (); // Insert this account to the database PSTMT = conn.preparestatement ("

INSERT INTO Accounts (ID, Ownername, Balance) VALUES (?,?,?) "); PSTMT.SetString (1, Accountid); PSTMT.SetString (2, OwnerName); PSTMT.SetDouble (3, balance); PSTMT. EXECUTEUPDATE (); // Generate a primary key and return it Return New Accountpk (AccountId);} catch (e) {throw new createException (E.TOSTRING ());} finally {try {if (pstmt! = null) PSTMT. CLOSE ();} catch (exception e) {} try {if (conn! = null) conn.close ();} Catch (Exception E) {}}}} // Part 3, business logic method // Deposit Part of the money to the user account to Public Void StoreInto (Double Amt) throws AccountException {System.out.Println ("StoreInto (" AMT ") Called!"); This.balance = Amt;} // From the bank account Take a certain amount of money public void getout (double amt) throws account. ");"); // If you want to take the money than the account balance IF (AMT> Balance) { Throw New AccountException ("Your Balance is Not Enough!");} this.balance - = Amt;} // Get the JDBC connection of the database from the connection pool PUBLIC Connection getConnection () THROWS Exception {Try {Context CTX = New InitialContext (); javax.sql.datasource DS = (javax.sql.datasource) ctx.lookup ("java: / mysql"); // To pay attention to uniform returnnection ();} catch (Exception) e) {system.out.println ("COULDN 'Get DataSource!"); E.PrintStackTrace (); throw e;}} // Part 4, define and implement the lookup method defined in the HOME interface, pay attention to them The difference between the naming and home connections // // uses the primary key to find an account // Note, its naming method is to add an EJB before and change the corresponding method name in the Home interface to // first each entity EJB capitalization // this method must define a public AccountPK ejbFindByPrimaryKey (AccountPK key) throws FinderException {PreparedStatement pstmt = null; Connection conn = null; try {System.out.println ( "ejbFindByPrimaryKey () called!"); Conn = getConnection (); PSTMT = conn.preparestatement ("SELECT ID from Accounts where id =?"); pstmt.setstring (1, key.tostring ()); resultset = pstmt.executeQuery (); rs.next );

// There is no error, the description is found, return to the primary key return key;} catch (e) {throw new FinderException (E.TOSTRING ());} finally {try {if (pstmt! = Null) PSTMT.Close () ;} catch (exception e) {} try {if (con! = null) conn.close ();} catch (exception e) {}}} // uses its name to find an account // Note, its name The way is the front add an EJB and then change the corresponding method name in the HOME interface to // First letter uppercase public collection ejbfindBYOWNERNAME (String name) throws FinderException {preparedState pstMt = null; connection conn = null; vector v = new Vector (); try {system.out.println (" Name ") Called! "); Conn = getConnection (); PSTMT = conn.preparestatement (" SELECT ID from accounts where iprePareStatement ("SELECT ID from Accounts WHERE OWNERNAME =?"); PSTMT .setString (1, name); ResultSet RS = pstmt.executeQuery (); while (rs.next ()) {string id = rs.getstring ("id"); v.addeElement (new account);} Return v;} catch (e) {throw new FinderException (E.TOString ());} finally {try {if (pstmt! = null) PSTMT.Close ();} catch (exception e) {} try {ix (conn! = null) Conn.close ();} catch (exception e) {}}} // It returns the balance of all bank accounts in the bank // This method is independent of all accounts (ie EJB instances), It is considered that it is a method of all EJB instances // Note: Its naming method is added with a H. omepublic double ejbHomeGetTotalBankValue (throws AccountException {PreparedStatement pstmt = null); Connection conn = null; try {conn = getConnection (); pstmt = conn.prepareStatement ( "select sum (balance) as total from accounts"); ResultSet rs = pstmt. ExecuteQuery (); if (rs.next ()) {RETURN RS.GETDOUBLE ("Total");}}}}}}}} Catch (Exception E) {E.PrintStackTrace (); throw new accountException (e);} finally {i i (PSTMT! = null) pstmt.close ();} catch (exception e) {} try {if (conn! = null) conn.close ();} catch (exception e) {}}} throw new accountException ("Error ! ");}} At this, we have written our CMP entity bean.

It is very long, the key length is in our way to achieve most of the synchronous database. In the next section, we can see that these methods do not need to be implemented in CMP, which is implemented by the container. Below us to deploy it and write an RMI-IIOP client to test our entity bean. Third, the deployment and test of the example BMP entity should be deployed our BMP. First we write a deployment descriptor, including two parts: one is a standard EJB2.0 specification EJB-jar.xml file, the other is The specific container is a deployment descriptor file for our JBoss. Enter the c: /jboss/myproject/accountbmp/eb/account.jar/meta-inf directory, create a new ejb-jar.xml file, the content is as follows: < Enterprise-Beans> Account Account.ejb.accountHome Account.ejb.account Account. Ejb.accountBean bean account.ejb.accountpk false < / Entity> Account Remote * Required Descriptor, Element Persistence-Type Indicates that we use bean management persistent Beans, if it is managed by the container, set to Container. Element Prim-Key-Class indicates the main key class. Element Reentrant Indicates if the bean can call itself, such as Beana calling beanb, beanb returns to calling beana, this situation we call beana is reusable, this is the self-cycle of the execution path, if we want Support this reward, this is written as true, we don't want to support this reward, so writing False. Element Assembly-Descriptor will take Bean and transaction, we don't talk here.

Similarly, in the c: /jboss/myproject/accountbmp/eb/account.jar/meta-inf directory newly created a JBoss-Service.xml file, this is a unique descriptor file with the JBoss container, its contents are as follows: Account Account True It describes how our client calls this entity bean information on how to pass JNDI. Next, we have entered the src directory, compiling our bean classes, enter the src directory, execute: com * .java (Note: com.bat is the compilation batch file we prepared in this series of tutorial) in SRC The directory directory produces a series of .class files, we move these files to: c: /jboss/myproject/accountbmp/eb/account.jar/account/ejb directory ready to publish it. Publish EJB, we will copy the Acquounjar directory to JBoss server deployment: c: / jboss / server / all / deploy, start the JBoss server, if there is no exception during the startup process, then our entity bean Released successfully. Let's write a client test program to test our BMP entity bean, enter the src directory, write the accountclient.java file, the content is as follows: it is self-explanatory. Package account.ejb; import javax.ejb. *; import javax.naming. *; import java.rmi. *; import javax.rmi. *; import java.util. *; import java.io. *; public class accountclient {public static void main (String [] args) throws Exception {Account account = null; InitialContext ctx = null; try {Properties env = new Properties (); // config.properties file should be placed in the directory and the directory of hello packet In the same directory. That is, it // and the Hello folder is in one folder.

Env.Load ("config.properties"); // Get a naming contextsystem.out.println (ENV); CTX = new javax.naming.initialcontext (env); System.Out.println ("Got Context "); // Get a reason to the INTEREST bean // JBoss default jndi named jboss-service.xml: jndi-nameObject ref = ctx.lookup (" account "); system.out.println (" Got Reference "); AccountHome AccountHome = (AccountHome) PortableRemoteObject.narrow (Ref, account.ejb.accountHome.class); // Create an EJB object AccountHome.Create (" 987-654-321 "," abner chai ", 2000); Account = AccountHome.Create ("123-456-7890", "John Smith", 100); System.out.Println ("Total of Accounts in Bank IS: AccountHome.gettotalbankValue ()); item i = accounthome.findbyownername ("John Smith"). Iterator (); I.hasNext ()) {Account = (Account) javax.rmi.portableremoteObject.narrow (I.Next (), Account.class;} else {throw new Exception ("Could Not Find Account");} system.out.println ("Initial Balance =" Account.getBalance ()); Account.StoreInto (100); System.out.Println ("After StoreInto 100, Account Balance = " Account.getBalance (); accountpk pk = (accountpk) Account.getPrimaryKey (); // Release the old object reference, use ID = null; Account = AccountHome.FindByPrimaryKey (PK); // Remove 50 yuan Account . GetOut (50); System.out.Println ("After get out 50, account balance =" account.getBalance ()); // Remove 200 rations System.out.Println ("Now Get Out 200); // It should throw an exception because the money is not enough.

转载请注明原文地址:https://www.9cbs.com/read-24523.html

New Post(0)