|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON Feature Java Feature — Bringing Together Eclipse,WTP, Struts, and Hibernate
Bringing Together Eclipse,WTP, Struts, and Hibernate
By: Boris Minkin
May. 10, 2006 01:30 PM
The file in Listing 8 contains two class tags, where each of our domain classes Customer and Order is mapped to the corresponding database table, with each instance variable mapped to a database column. One attribute worth mentioning is "lazy" - we have explicitly set to it to false, the reason being that when lazy is true (default), reading from the database is only done whenever a particular method is accessed. For example, it'll happen only when a getFirstName() is called, rather than pre-reading the whole set of customers right away - when the SQL query is issued. This may sometimes be beneficial when you read a large set of data and want to defer expensive database operations. In our example, we're only reading a small set of customers and don't want additional performance or database access issues to occur later, such as if the database session is closed at that later time, we'll get an exception from Hibernate if we still try to invoke the "lazy" method. The Hibernate configuration is complete, and we have to modify our CommandExecutor class a bit to use the framework and remove hard-coded SQL code. This class has been used as a singleton for storing data sources and getting database connections. First of all, we'll be adding the instance variable to store the Hibernate session factory. The Hibernate session factory is similar to a data source, except instead of getting database connections from it, we'll be getting Hibernate database sessions. The instance variable will look simply as follows: private SessionFactory sessionFactory = null; Next, we want to create an access method for this instance variable (See Listing 9). This will maintain the object state encapsulated, and will also allow using techniques of the lazy initialization (access the data only when needed): In this method, we initialize a session factory for the first time. Hibernate's Configuration object is used to read the configuration file from the classpath and initialize the framework accordingly. We've used the executeDatabaseCommand() method before we started using Hibernate to perform our database operations: using the DatabaseCommand interface that required the executeDatabaseOperation() method. Since we now want to use Hibernate, we're going to introduce another method to the DatabaseCommand interface and another one to the CommandExecutor singleton object - this method will execute all of our database operations using Hibernate framework (See Listing 10). This looks very like the executeDatabaseCommand() method, except that in this case, we're using a Hibernate Session object rather than a normal JDBC connection. The next step would be simply to add the following stub method to the DatabaseCommand interface: public Object executeHibernateOperation(Session session) throws SQLException; Now that we've added this new method to the interface, all the classes implementing this interface will be marked with red bullets in the Eclipse workbench, because the classes implementing the interface have to implement all the methods that it requires. We have four classes implementing the database command interface:
public class CreateCustomer implements DatabaseCommand Hence we have to add an executeHibernateOperation() implementation method to each of them. Let's take a look at the CreateCustomer class first. Its executeDatabaseOperation() method is shown in Listing 11. This method is fairly long and coding one requires a developer to know JDBC: how to create and execute prepared statements. Also, if one were to change the database from MySQL to some other one, it might require that the developer re-write the SQL because it may differ from one database to another. With Hibernate, you just change the SQL dialect in the hibernate.cfg.xml configuration file. Our corresponding executeHibernateOperation() method is in Listing 12. In Listing 12 we tell the session object to save our class in the database. No SQL, no JDBC knowledge, no hard-coding of column and table names. If we have to change the table or column name, we don't have to go through possibly multiple lines of code in the application. Hibernate knows how to save the object, whether this object already exists in the database or not (to do an INSERT or UPDATE operation - it performs a check in either the optimistic way (tries to do an UPDATE, and if that fails, INSERT) or pessimistic way (does a SELECT to see if the row exists, if yes, then does UPDATE, otherwise INSERT). We flush the session after the execution of the command to make sure that all the database commands are executed right away without anything left over in the framework's buffer. In a similar fashion we perform the operation for the CreateOrder class. First, the two operations that we have dealt with (in the JDBC version), CreateCustomer and CreateOrder, are database insert operations. However, one also has to handle database queries to make the application work. For that, we have ListCustomers and ListCustomerOrders commands. Let's look at how we get the customer list. Listing 13 contains a bunch of JDBC calls. First, create an SQL statement, execute it using hard-coded column and table names, and then go through the ResultSet of the database query and construct a Customer domain object explicitly from each row read from the table, where we also have to remember the column order or names. All those operations are error prone and may become hard to maintain whenever changes to the database tables are required. This is where Hibernate comes to the rescue. It introduces a whole new language called the Hibernate Query Language (HQL), where one doesn't need to query database tables, but rather objects. Our executeHibernateOperation() method will look as in Listing 14. Once again this method looks pretty similar to the old one, however, there are some significant differences. Here we are using a bunch of Hibernate objects. The first one is a Query class. It lets one create and execute database queries using either HQL (through the createQuery method) or regular SQL (through the createSQLQuery method). Let's look at the HQL we are using here: from customer in class domain.Customer Basically we're selecting all the customers identified by the variable customer from the domain.Customer class. Obtaining the iterator of the query lets us put "customers" in any collection. In our case it's ArrayList<Customer>. A very similar method can be written for the ListCustomerOrders class, but HQL is a tiny bit more complex as you can see in Listing 15. In this case we use the where-clause in our query. Note that in this where-clause we can use the instance variable of the Order class (custId) to query by. The syntax is similar to Java's dot notation. Finally we have to update our Struts action classes to invoke the executeHibernateOperation() method instead of the executeDatabaseOperationMethod(). This can be done easily using Eclipse editors.
Exporting an Eclipse Project into WAR
Conclusion LATEST JAVA STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK SPONSORED BY INFRAGISTICS
BREAKING JAVA NEWS
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||