Using hibernate to process data in Java projects

Source: Internet
Author: User
Tags date generator sql net string version tostring uuid
Data | project

Object-Relational Mapping (O/R mapping) is a common requirement for many software development projects. The activities involved in the data persistence process are tedious and error-prone. If we take into account the inevitable changes in demand, we are faced with a lot of trouble: the data storage structure must be kept in sync with the source code. Plus the portability problem, things get very complicated.

Hibernate can help us easily save data in persistent storage media without wasting much effort in selecting storage, installation, or configuration types. Hibernate allows us to store any type of object, so the application does not need to know that its data will be persisted using hibernate. Of course, everything mentioned here can be reversed: it's common to get ready objects from memory now. The same is true for updating and deleting data.

   before you start

Before you start, you need a hibernate release that you can find on the Hibernate Web site (www.hibernate.org). We will use the 2.0.3 version. For the database, we will use the hypersonic SQL 1.7.1 version, which can be found on hsqldb.sourceforge.net. Hibernate also supports many open-source or business databases, such as MySQL, PostgreSQL, Oracle, DB2, and so on. This tutorial is easy to install for any supported database. See the official documentation for a complete list.

Note: If you do not want the class to be persisted in the database (for example, you only want to serialize), then hibernate The API provides you with the Net.sf.hibernate.persister.EntityPersister class and the Net.sf.hibernate.persister.ClassPersister interface. By writing subclasses or implementing them, you can write your own persistence classes and use them as needed.

After downloading all the necessary installation packages, we must set up the test environment. Basically, all we need to do is put the downloaded. jar file into the classpath. This includes Hsqldb.jar in the lib/directory of Hibernate2.jar and hypersonic in the hibernate release. Hibernate also requires several other libraries that can be found in the
Note: Hibernate uses Apache commons-logging. It is an intelligent tool that, if found log4j, uses it by default. Log4j is an excellent logging library that we will use in this tutorial. If you do not have this software (you really should install this software!) Can be downloaded from the LOG4J homepage and added to the classpath. Using the sample log4j.properties provided by the Hibernate team, it can be found under the
   problem introduced

Each developer performs at least one similar task: Creating an order, putting some products in it, turning it into an order item, and then saving the order.
We use these simple SQL commands to set up the database:

CREATE TABLE ORDERS (         ID VARCHAR not null PRIMARY KEY,         order_date TIMESTAMP not NULL,         price_total DOUBLE not NU LL) CREATE TABLE products (         ID VARCHAR not null PRIMARY KEY,         NAME VARCHAR not NULL, price         DOUBLE not NULL,         AMOUNT INTEGER NOT NULL] CREATE TABLE order_items (         ID VARCHAR not null PRIMARY KEY,         order_id VARCHAR not null,
  
   PRODUCT_ID VARCHAR NOT NULL,         AMOUNT INTEGER is not NULL,         
  

This data model is very simple. For an actual "quality of production" data model, we will need foreign keys, indexes, extra fields, and so on. For this tutorial, the data model above is OK.

   Java Code

While these business requirements are simple and easy to understand, the traditional way to write a bunch of prepared statements is quickly annoying. And hibernate will liberate us. All we need is a simple set of mapping files. But first we need to write Java classes.

Note: We will put all the classes that will be persisted into the test.hibernate package and put all the helper classes in the test package.

   Product

This simple class defines only the necessary fields: ID, product name, product price, and current inventory for this product. Since Hibernate uses plain, unformatted JavaBeans, all we need to do is create getter and setter methods and default constructors for each important field (in our case, all fields are important fields).

Package test.hibernate; public class Product {     private String ID;     private String name;     private double price;     private int amount;          Public String GetId () {return         ID;     }     public void SetId (string string) {         id = string;     }     Default constructors and others      //For brevity, the Getter/setter method does not show     

We also need to rewrite the ToString () method. This will help us use simple System.out.println (obj) to track application flow:

Public String toString () {     return       "[Product]" + name + "(+ ID +      

This is all the product class code. But the product does not implement any interfaces, nor does it inherit any classes, and how does hibernate know how to persist the object of that type? The answer is simple: Hibernate can handle any type of Java object as long as it follows the JavaBeans convention.

  Order

The next class we need to create is Order, which is even simpler than product: It contains only the ID, the creation date, the total price, and the set of the OrderItems included in the order. Of course, you also need to create getter and setter methods and the default constructor.

Package test.hibernate; Import Java.util.Date; Import Java.util.HashSet; Import Java.util.Set; public class Order {     private String ID;     private date date;     Private double pricetotal;     Private Set OrderItems = new HashSet ();          The Create time of this order is automatically set to public order     () {         this.date = new Date ();     }     Public String GetId () {return         ID;     }     public void SetId (string string) {         id = string;     }     For simplicity, other getter/setter methods do not show     

Also rewrite the ToString () method. Don't forget to execute loops on OrderItems!

   OrderItem

This class is a little more complex, but it's still easy to understand. Our business needs determine that we need a certain amount of products and we will put them in an order. Those products will automatically become order items. Then you need to customize the constructor.

Package test.hibernate; public class OrderItem {/** * Creates a valid order item.     Automatically set the price of an order item and correct the inventory availability of the product * * @param order * The order item belongs @param product that the order item is created for * @param amount * *                               Public OrderItem (order, product product, int amount) {         This.order = order;         This.product = product;         This.amount = amount;         Product.setamount (Product.getamount ()-amount);             This.price = Product.getprice () * amount; //also requires a default constructor to ensure that hibernate work/** * Null constructors follow the JavaBeans convention */Public OrderItem () {//NULL default structure     Create function}//field private String ID;     Private product product;     Private order;     Private String productId;     Private String orderId;     private double price;          private int amount;     Public String GetId () {return id;     Public String GetProductID () {return Product.getid (); } publiC String Getorderid () {return Order.getid ();            //Other Getter/setter method does not show//... file://to display the order item public String toString () {return     "[OrderItem] id=" + ID + "amount=" + Amount + "price=" + Price + "(" + Product + ")";  } }

Now we have all the classes that reflect the structure of the database. The only thing left unexplained is how to put the product in an order. Simply add the following method to the Order class:

/** * Add a product to the order. The product automatically becomes an order item.  * Pricetotal is automatically updated. *  * @param P added to the order of the product * @param amount Added volume */public void addproduct (product p,                         int amount) {    OrderItem ord Eritem = new OrderItem (this,                           p, amount);                              This.pricetotal = this.pricetotal                       + p.getprice () * amount;                          

   Start Hibernate

In our hypothetical application, the basic usage pattern is simple: we will create an product and then persist it (or, in other words, save it); We will search for and load a persistent product and make sure it is available; we will update and delete the product.

  Create and persist product

Now we are finally using the hibernate. The scenario used is very simple:

    1. Create a valid product.
    2. Use Net.sf.hibernate.cfg.Configuration to get net.sf.hibernate.SessionFactory when the application starts.
    3. Open the Net.sf.hibernate.Session by calling Sessionfactory#opensession ().
    4. Save product, close session.


As we can see, there is no mention of JDBC, SQL, or anything like that. Very exciting! The following example follows the steps mentioned above:

Package test; Import net.sf.hibernate.Session; Import Net.sf.hibernate.SessionFactory; Import net.sf.hibernate.Transaction; Import net.sf.hibernate.cfg.Configuration; Import test.hibernate.Product; Usage://Java test. Insertproduct Name Amount Price public class Insertproduct {public     static void Main (string[] args)                          throws Excepti On {         //1. Create Product object         Product P = new product ();         P.setname (Args[0]);         P.setamount (Integer.parseint (args[1));         P.setprice (Double.parsedouble (args[2));         2. Start Hibernate         Configuration cfg = new Configuration ()                          . addclass (product.class);         Sessionfactory SF = Cfg.buildsessionfactory ();         3. Open session session         Sess = Sf.opensession ();         4. Save product, close session         Transaction T = sess.begintransaction ();         Sess.save (p);         T.commit ();         Sess.close ();     

Let's run it! By running Java test. Insertproduct Milk 100 1.99 order, insert 100 bottles of milk at a price of 1.99. We will get the following output log:

Nov 2003 9:05:50 AM net.sf.hibernate.cfg.Environment 
  
    info:hibernate 2.0.3 Nov, 2003 9:05:50 AM Net.sf.hib Ernate.cfg.Environment 
   
     INFO:hibernate.properties not found Nov, 2003 9:05:50 AM Net.sf.hibernate.cfg.Environ ment 
    
      info:using cglib Reflection Optimizer Nov, 2003 9:05:50 AM net.sf.hibernate.cfg.Environment 
     
       INF O:JVM proxy Support:true Nov, 2003 9:05:50 AM net.sf.hibernate.cfg.Configuration addclass info:mapping T/hibernate/product.hbm.xml Exception in thread "main" net.sf.hibernate.MappingException: resource:test/ Hibernate/product.hbm.xml not found at Net.sf.hibernate.cfg.Configuration.addClass (configuration.java:285) 
     
    
   
  

It doesn't work. Two of these lines are particularly interesting:

INFO:hibernate.properties not found and resource:test/hibernate/product.hbm.xml not found.

Of course, Info line says we need a hibernate.properties configuration file. In this file, we configure the database, username and password, and other options to be used. Use the example provided below to connect the hypersonic database mentioned earlier:


Modify appropriately (for example, you may need to modify hibernate.connection.url) and save it to classpath.

It's easy, but what is the Test/hibernate/product.hbm.xml resource? It is an XML file that defines how Java objects are persisted (mapped) to a database. In this file, we define which database table the data is stored in, which fields map to which column of the database table, how different objects relate to each other, and so on. Let's take a look at Product.hbm.xml.

<?xml version= "1.0" encoding= "UTF-8"? DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping dtd//en" "Http://hibernate.sourceforge.net/hibern                        Ate-mapping-2.0.dtd "> 

    • element and its child elements to define the connection between the Java class and the database.
    • element that defines which column each field is stored to, its type, name, and so on.


elements are not very well understood at first sight. But when you know that it's a child of , it's obvious: because the application doesn't know how its data is persisted (as we always say), we need a surrogate key that doesn't have any business implications to help hibernate manipulate the object. Newly created products none of the id,hibernate will create them for us. We chose to use the UUID string, but it provides a number of ID generators (sequential, scoped, even user-assigned, and so on), and can also write their own ID generators.

Now, create (copy, paste) the Product.hbm.xml content and put the files and Test.hibernate.Product classes in the same package (for example, the directory where Product.java files are placed) and rerun Java test. Insertproduct Milk 100 1.99 command. Now we see more logs and ... There's no other thing! Does it work properly? In Session Sess = Sf.opensession (); Before and after Sess.close () add System.out.println (p) to see what's wrong with produc. Run the program again. You will see a log output similar to the following: The ID number will be different.


Hibernate created the product id! for us Let's see if product is stored in the database. Executes the SELECT * from products, and the database returns output similar to the following:

ID                              |name  | Price | AMOUNT | 40288081f907f42900f907f448460001| Milk  |1.99  |100    

Product information has been successfully inserted into the database, and we have not even written a single line of SQL statements!

Insert some other product, such as bread, coffee, beer, etc., so that you can continue to learn the following tutorial.

  Find and Load Products

Finding and loading objects that have been persisted is very simple in hibernate. Using its query Language , we can easily get an object (or set of objects) by ID, name, or other attribute. We can get the complete object or some of its properties. Hibernate will handle the rest of the work, and finally, we will have a fairly useful object hierarchy. Let's take a look at test. Findproductbyname class.

Package test; Import java.util.List; Import Net.sf.hibernate.Hibernate; Import net.sf.hibernate.Session; Import Net.sf.hibernate.SessionFactory; Import net.sf.hibernate.cfg.Configuration; Import test.hibernate.Product; Usage://Java test.         Findproductbyname name public class Findproductbyname {public static void main (string[] args) throws Exception { Executed query String query = "SELECT product from Product" + "in class Test.hibernate.Prod         UCT "+" where product.name=:name ";         Search for content String name = Args[0];         Initialize Configuration cfg = new Configuration (). addclass (Product.class);         Sessionfactory SF = Cfg.buildsessionfactory ();                  Open Session Sess = Sf.opensession ();         Search for and return to List List = Sess.find (query, name, hibernate.string); if (list.size () = = 0) {System.out.println ("No products named "+ name);         System.exit (0);         Product P = (product) list.get (0);         Sess.close ();     System.out.println ("Found product:" + P); } }

There are several noteworthy points in the Findproductbyname:

    • There is a query string that has a WHERE clause, which is similar to a standard SQL statement.
    • The method for initializing hibernate is the same as in the first example. This time, we have configuration files and mapping files.
    • Sess.find () executes the query and sets the supplied product name to the type hibernate.string search parameters.
    • As a result, we get a java.util.List that contains the found product.
    • Use product P = (product) list.get (0); We use the usual type conversion method to get the found object.


Executes Java test. Findproductbyname Milk to see what is displayed in the console.

Note: Queries are case-sensitive, so searching for lowercase milk will not return any results. Use the lower () or upper () SQL functions to enable case-insensitive searches. In this case, we use the where lower (Product.name) =lower (: Name) in the query string. For more information about queries, see the documentation. In addition, if you do not want to display all the info log information, you can modify the Log4j.properties file and set the log level to warn.

  Update and DELETE products

Until now, you should have a basic understanding of how hibernate works, so we'll shorten the lengthy example and show only the important parts.

To increase the price of all products by 10% in a single transaction, we can write the following:

Double percentage = double.parsedouble (Args[0])/100; Sess = Sf.opensession (); Transaction t = sess.begintransaction (); List contains products iterator ITER = List.iterator (); while (Iter.hasnext ()) {     Product p = (Product) iter.next ();                 P.setprice (P.getprice () * (1 + percentage));     Sess.saveorupdate (P);       

Finally, to remove product, call Sess.delete (product), of course. If the database shuts down autocommit, do not forget to call commit () COMMIT transaction.

Now, we've done all the basic things for a single object--Create, read, update, and delete. It looks rather interesting, but we can do it better. Now let's learn how to manipulate the set of objects without having to write SQL statements. All the magic is done through the mapping file.

Orders,orderitems

Sometimes it is feasible to manipulate objects one by one, but we want to be able to cascade load and update. Now let's see how to do that.

We need to check both order and OrderItem. As mentioned earlier, we add a product to an order and it becomes a orderitem. Order to save a OrderItem set internally. We want to save the order and let hibernate do other work: Save the OrderItem and update the available inventory (quantity) of the added product. It sounds complicated, but it's actually very simple. Hibernate knows how to handle related objects in a pair of multiple, One-to-many, One-to-many, and many-to-many ways. We'll start with the mapping file.

Order.hbm.xml

<?xml version= "1.0" encoding= "UTF-8"? DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping dtd//en" "Http://hibernate.sourceforge.net/hibern Ate-mapping-2.0.dtd "> 

This mapping file is very easy to understand except for the last element <set>. It represents the connection between different classes, and in our case these classes are order and OrderItem. Attributes and child elements are easy to understand: a set-Type field, named OrderItems (see the order source code above), contains objects of type Test.hibernate.OrderItem, as the <one-to-many> child elements explain. These objects are persisted in the table Order_items, and the order_id column contains the keys for the OrderItem type of object.

Cascade= "All" is a very important attribute. It explains how hibernate moves when manipulating the objects that are connected to it. In our example, when we create an order, we certainly want all of its orderitem to be created; Of course, when an order is deleted, we also want all of its orderitem to be deleted. There are three additional options for the Cascade property (None, Save-update, and delete), and we'll look at how to use them in the following example.

   OrderItem.hbm.xml

This object is more interesting. Its instance is automatically created in the order, and it does not exist outside of it. However, because they represent product when the order is created, we need them. If the price of a product changes, we certainly do not want all the relevant orderitem and order prices to be changed. All we need is to update the available inventory of product when OrderItem is created. Finally, when an order is deleted, its orderitem is deleted, but we cannot change the product! It sounds complicated, especially if you want to write all of these SQL statements. But hibernate them into two lines in the mapping file!

<?xml version= "1.0" encoding= "UTF-8"? DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping dtd//en" "Http://hibernate.sourceforge.net/hibern         Ate-mapping-2.0.dtd "> 

  usage Examples

  Create an order. In this example, we create and persist an order. Run this example repeatedly to see how the number of products changes after each successful order creation.

// ... Configuration cfg = new Configuration ()                     . addclass (Product.class)                     . addclass (Order.class)                     

   find orders by price range. In this example, we'll show you how to use a query with two parameters. Hibernate correctly loads orders with the appropriate order items and products.

// ... String query = "Select O from o"     + "in class Test.hibernate.Order"     + "where O.pricetotal >:p ricetotallower" 
  + "and O.pricetotal:p ricetotalupper"; // ...                 Query q = sess.createquery (query); Q.setdouble ("Pricetotallower",               double.parsedouble (args[0)); Q.setdouble ("Pricetotalupper",               

   Delete orders within a certain price range. This is an important example. Here we will see how hibernate is an intelligent tool. As mentioned earlier, when an order is deleted, its order items also need to be deleted, but the product cannot be changed. After you run the example, check the database to make sure that the product has not changed.

// ... String query = "Select O from o"     + "in class Test.hibernate.Order"     + "where O.pricetotal >:p ricetotallower" 
  + "and O.pricetotal:p ricetotalupper"; Transaction tx = Sess.begintransaction (); Sess.delete (query,      new object[]{new double (args[0)),                   new double (Args[1)},      new type[]{hibernate.double ,                 hibernate.double}            );        

   Concluding remarks

This article shows how powerful hibernate is. You've learned how easy it is to persist any type of Java object, manipulate object hierarchies, handle collections, and use transactions. But Hibernate's function is more than that. It handles full transactions, inheritance, several types of collections using commit and rollback, and provides very powerful object-oriented query Language HQL,HQL support associations and joins, polymorphism, subqueries, etc. You can then read the Hibernate reference documentation and start using hibernate in your daily work.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.