Hibernate是一个开放源代码的对象关系映射框架(Framework),它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
作为一个Framework,Hibernate其实算是一个半成品的应用程序。Hibernate主要完成的是JavaBean和关系型数据库中数据项的一一映射关系,即Object Relationship Mapping(ORM,对象关系映射)。记得在学习JDBC的时候,会把链接数据库的一些信息写入到一个Properties文件中,然后加载该文件。而在Hibernate中,链接数据库所需要的信息(包括数据库的url,username,password,数据库连接池等)都会在一个Hibernate.cfg.xml配置文件中完成(当然你也可以用Hibernate.properties)。在JDBC中,为了方便处理从数据库中的出来的数据,我会把查询到的数据用一个RowMapper接口封装成一个具体的JavaBean对象(这个接口主要在业务逻辑层实现),而在Hibernate中,只需要简单的给你要持久化到数据库中的JavaBean配置一个对应的映射文件即可。当然这个映射文件并非简单的是对查询到的数据的一个封装,它既然是对象和数据库中数据项的双向映射,更重要的是,它还把数据之间的关联关系给处理的很好,避免了在JDBC当中对复杂数据关系的处理(比如对具有复杂关联关系的数据表的连接查询)。
好了,废话不多说,初识Hibernate,对它的功能也并不是那么了解,还是通过学习的过程来慢慢了解它的强大的好。下面是第一个Hibernate应用程序实例。
先看第一个Hibernate应用程序的文件结构:
在新建的应用程序中引入Hibernate所需的jar包,好的办法是创建user lib,然后加入外部jar包,这样方便以后的再次引入。然后是MySQL数据库的connector,为了方便测试,还要引入Eclipse自带的lib:JUnit4。
接着创建一个需要对之持久化到数据库的类,也就是一个JavaBean:Event
package model;
import java.io.Serializable;
import java.util.Date;
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
private long id;
private String title;
private Date date;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
要点:
1、id是为了作为event的唯一标识(identifier),为了使用Hibernate提供的所有特性,每个持久化实体(Persistent Entity)类都需要这么一个identifier。2、由于我们通常不会操作对象的标识(identifier),所以可以把setId()方法设置为private,这是由于Hibernate可以直接访问public,protected,和private的访问器(accessor)和字段(field)。要不要把setId()设置为private,这取决于我们的习惯。
3、所有的持久化类,必须有无参的构造方法,这意味着如果我们写了含参的构造方法之后,必须再把无参的给加上。这是因为Hibernate必须用Java的反射机制来给我们创建对象。
OK,根据前面所说,有了持久化类,就要有与之对应的映射文件:Event.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="model">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="native" />
</id>
<property name="date" type="timestamp" column="EVENT_DATE" />
<property name="title" />
</class>
</hibernate-mapping>映射文件是重点:
1、Hibernate需要知道怎样去加载(load)和存储(store)持久化类的对象。这正是 Hibernate 映射文件发挥作用的地方。映射文件告诉 Hibernate 它应该访问数据库(database)里面的哪个表table及应该使用表里面的哪些column。
2、DTD,这个没有必要记住,可以在hibernate3包下找到:org.hibernate下的hibernate-mapping.dtd
3、hibernate-mapping元素的package属性值和class元素的name属性值一起指定了这是哪个persistent class的映射。class元素的table属性指定了该持久化类在数据库中对应的表。
4、id元素是对identifier属性的声明。name属性声明了它在JavaBean中的字段名和setId()和getId()访问器。column属性值是它在数据库表中的列。子元素generator,其class属性包括native,sequence,increment,hilo等值,这里的native说明其id生成策略取决于数据库的方言(dialect)。
5、property元素是声明JavaBean和数据库表中的普通列,name和column属性和id元素的类似。需要注意的是type既不是Java中的类型也不是数据库中的类型,而是Hibernate映射类型(Mapping Types),他们能把java数据类型和SQL数据类型相互转化。缺省的时候,hibernate会试着自己去匹配,但是有时候可能会有点小问题,比如java.util.Date类型的hibernate就不知道是转化为SQL Date,timestamp还是time类型的。这里用了timestamp时间戳。
持久化对象和映射文件有了,之后就是hibernate配置文件:hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping resource="model/Event.hbm.xml" />
</session-factory>
</hibernate-configuration>这个Hibernate配置文件的注释足以说明一切。值得一提的是<property name="hbm2ddl.auto">update</property>
这里的update替换为create时是没有数据表的时候给创建数据表,已经有数据表的时候会删除数据表并重建。Mapping元素的resource属性,应该是目录层次而不是包层次。
在JDBC中,有一个Connection对象,与之对应的,Hibernate中有Session对象。一个好的习惯是创建一个util类,来生成SessionFactory:HibernateUtil
package util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final String CONFIG_FILE = "/hibernate.cfg.xml";
private static final SessionFactory sessionFactory = buildFactory();
private static SessionFactory buildFactory() {
try {
return new Configuration().configure(CONFIG_FILE)
.buildSessionFactory();
} catch (Throwable ex) {
// TODO Auto-generated catch block
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
事实上,如果配置文件hibernate.cfg.xml名字和位置都如上代码中一样的话,用new Configuration().configure()
取代上面的new Configuration().configure(CONFIG_FILE);这个从Configuration的源码中可以看到。
OK,万事俱备,可以写一个测试类来测试一下了。
package test;
import java.util.Date;
import model.Event;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.junit.Test;
import util.HibernateUtil;
public class EventTest {
@Test
public void createAndStoreEvent() {
String title = "MyEvent";
Date date = new Date();
//获取Session对象
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
//获取事务控制对象
Transaction tx = session.getTransaction();
//开启事务
tx.begin();
Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(date);
//用hibernate提供的api保存对象
session.save(theEvent);
//提交事务
tx.commit();
}
}
这里值得一提的是,hibernate中,无论是什么事务,都需要有事务的开启和提交。
OK,测试成功,第一个Hibernate应用就完成了。因为是最开始,为了使自己能对流程有个深刻的印象,所以比较啰嗦。
给自己:学习不可能一口吃成个胖子,要虚心,不能好高骛远。Inner peace!!!
本文介绍了Hibernate作为对象关系映射框架的基本概念,包括其在Java应用中的作用,以及如何通过配置文件、映射文件和持久化类实现数据库操作。文章通过一个简单的实例展示了创建Hibernate应用程序的步骤,包括创建JavaBean、映射文件和配置文件,并通过测试类验证了功能。

被折叠的 条评论
为什么被折叠?



