Comparing JDBC to Hibernate
If you are reading this book, you almost certainly have either written or maintained applications in which a surprisingly large amount of code is devoted to maintaining the glue between your Java code and your relational database. (From here on, we'll assume that you have chosen to standardize on Java as your preferred programming language, and on SQL as your preferred relational database language. While object/relational technology is available for a variety of other programming environments, Hibernate is a Java-based system.)
Anyone who has built a Java application using JDBC has experienced the difficulties inherent in the mismatch between Java and SQL. Let's look at an example of retrieving data using JDBC, shown in Listing 1.1.
Listing 1.1. Simple JDBC Code
package com.cascadetg.ch01;
import java.sql.*;
public class JDBCClient
{
static void printColumn(String in)
{
System.out.print(in);
System.out.print(" | ");
}
public static void main(String[] args)
{
Driver myDriver = null;
Connection myConnection = null;
try
{
myDriver = (Driver)Class
.forName("com.mysql.jdbc.Driver")
.newInstance();
myConnection = DriverManager.getConnection(
"jdbc:mysql://localhost/sample", "root",
"");
Statement myStatement =
myConnection.createStatement();
ResultSet myResults = myStatement.executeQuery(
"SELECT ID, weight, name FROM Animal");
while (myResults.next())
{
printColumn(myResults.getLong("ID") + "");
printColumn(myResults.getInt("weight") + "");
printColumn(myResults.getString("name"));
System.out.println();
}
} catch (Exception e)
{
e.printStackTrace();
} finally
{
try
{
if (myConnection != null)
myConnection.close();
} catch (Exception e)
{
}
}
}
}
As you can see, the retrieval of the individual data is both error-prone and time-consuming. It's very easy to make a mistake in any of the hard-coded strings, and more complex SQL can lead to (possibly inadvertent) database-specific code.
Now let's look at a similar retrieval performed using Hibernate, as shown in Listing 1.2. The output of Listing 1.2 (excluding informational messages provided by Hibernate) is identical to that of Listing 1.1.
Listing 1.2. Simple Hibernate Code
package com.cascadetg.ch01;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
public class HibernateClient
{
static String[] props =
{
"hibernate.connection.driver_class",
"com.mysql.jdbc.Driver",
"hibernate.connection.url",
"jdbc:mysql://localhost/sample",
"hibernate.connection.username", "root",
"hibernate.connection.password", "",
"hibernate.dialect",
"net.sf.hibernate.dialect.MySQLDialect",
"hibernate.show_sql", "true"
};
static void printColumn(String in)
{
System.out.print(in);
System.out.print(" | ");
}
public static void main(String[] args)
{
try
{
// One-time only configuration code, run only
// during application initialization.
Configuration myConfiguration = new
Configuration();
myConfiguration.addClass(
com.cascadetg.ch01.Animal.class);
for (int i = 0; i < props.length; i = i + 2)
myConfiguration.setProperty(props[i], props[i
+1]);
SessionFactory sessionFactory =
myConfiguration.buildSessionFactory();
Session hibernateSession =
sessionFactory.openSession();
Criteria query = hibernateSession.createCriteria(
com.cascadetg.ch01.Animal.class);
// Here we get and loop over the results
java.util.Iterator results =
query.list().iterator();
while (results.hasNext())
{
// Notice that the result set is cast to the
// Animal
// object directly - no manual binding
// required.
Animal myAnimal = (Animal)results.next();
printColumn(myAnimal.getId() + "");
printColumn(myAnimal.getWeight() + "");
printColumn(myAnimal.getName());
}
} catch (Exception e)
{
e.printStackTrace();
}
}
}
The first thing you should notice when examining the code in Listing 1.2 is that there are no hard-coded SQL strings in the query. In addition, there is no need to retrieve data using JDBC result set queries; you simply work with returned Animal objects. In this example, both the Java source for the Animal class and the schema for the corresponding Animal table are generated automatically by Hibernate.
It's possible to express complex relationships, including one-to-many and even many-to-many, using Hibernate, with Hibernate intelligently loading and caching data, automatically generating potentially very complex joins in order to optimally retrieve the data. This binding of the Java code and database schema is known as object/relational mapping.
 |