初学者的Hibernate教程

欢迎来到Hibernate初学者教程。Hibernate是最广泛使用的Java ORM工具之一。大多数应用程序使用关系数据库来存储应用程序信息,并且在低层级上我们使用JDBC API来连接数据库并执行CRUD操作。

初学者的Hibernate教程

如果你看一下JDBC代码,会发现有很多样板代码,而且有可能会出现资源泄漏和数据一致性问题,因为所有工作都需要开发人员完成。这就是ORM工具发挥作用的地方。对象关系映射(ORM)是一种编程技术,用来将应用程序领域模型对象映射到关系数据库表中。Hibernate是一个基于Java的ORM工具,它提供了将应用程序领域对象映射到关系数据库表(反之亦然)的框架。使用Hibernate作为ORM工具的一些好处有:

    1. Hibernate支持将Java类映射到数据库表,反之亦然。它提供了在所有主要关系数据库上执行CRUD操作的功能。

 

    1. Hibernate消除了使用JDBC时伴随而来的所有样板代码,并负责管理资源,因此我们可以专注于业务用例,而不必担心数据库操作会引发资源泄漏的问题。

 

    1. Hibernate支持事务管理,并确保系统中没有不一致的数据。

 

    1. 由于我们使用XML、属性文件或注解来将Java类映射到数据库表,它为应用程序和数据库之间提供了一个抽象层。

 

    1. Hibernate帮助我们映射连接、集合、继承对象,我们可以轻松地可视化我们的模型类如何表示数据库表。

 

    1. Hibernate提供了一个强大的查询语言(HQL),它类似于SQL。但是,HQL是完全面向对象的,并且理解继承、多态和关联等概念。

 

    1. Hibernate还提供了与一些外部模块的集成。例如,Hibernate Validator是Bean Validation(JSR 303)的参考实现。

 

    1. Hibernate是来自Red Hat社区的开源项目,被全球范围内广泛使用。这使它相比其他选择更好,因为学习曲线较小,有大量的在线文档和论坛中提供的帮助资源。

 

    Hibernate易于与其他Java EE框架进行集成,它非常流行,以至于Spring Framework为将Hibernate与Spring应用程序集成提供了内置支持。

希望以上所有的好处能够说服您选择Hibernate作为您的应用程序对象关系映射的最佳选择。现在让我们来看看Hibernate框架的架构,然后我们将进入一个示例项目,探讨在独立的Java应用程序中配置和使用Hibernate的不同方式。

Hibernate 架构

以下图片展示了Hibernate架构以及它是如何作为应用程序类和JDBC/JTA API之间的抽象层来进行数据库操作的。明显地,Hibernate是建立在JDBC和JTA API之上的。让我们逐个查看Hibernate架构的核心组件。

  • SessionFactory (org.hibernate.SessionFactory): SessionFactory is an immutable thread-safe cache of compiled mappings for a single database. We can get instance of org.hibernate.Session using SessionFactory.
  • Session (org.hibernate.Session): Session is a single-threaded, short-lived object representing a conversation between the application and the persistent store. It wraps JDBC java.sql.Connection and works as a factory for org.hibernate.Transaction.
  • Persistent objects: Persistent objects are short-lived, single threaded objects that contains persistent state and business function. These can be ordinary JavaBeans/POJOs. They are associated with exactly one org.hibernate.Session.
  • Transient objects: Transient objects are persistent classes instances that are not currently associated with a org.hibernate.Session. They may have been instantiated by the application and not yet persisted, or they may have been instantiated by a closed org.hibernate.Session.
  • Transaction (org.hibernate.Transaction): Transaction is a single-threaded, short-lived object used by the application to specify atomic units of work. It abstracts the application from the underlying JDBC or JTA transaction. A org.hibernate.Session might span multiple org.hibernate.Transaction in some cases.
  • ConnectionProvider (org.hibernate.connection.ConnectionProvider): ConnectionProvider is a factory for JDBC connections. It provides abstraction between the application and underlying javax.sql.DataSource or java.sql.DriverManager. It is not exposed to application, but it can be extended by the developer.
  • TransactionFactory (org.hibernate.TransactionFactory): A factory for org.hibernate.Transaction instances.

Hibernate是Java Persistence API (JPA)的实现。

Hibernate提供了Java Persistence API的实现,因此我们可以使用JPA注释来处理模型bean,并且Hibernate会负责配置它以用于CRUD操作。我们将通过注释示例来讨论这个问题。

请给出一个以中国传统文化为例的实际应用例子

在开发Hibernate应用程序时,我们需要提供两套配置。第一套配置包含特定于数据库的属性,用于创建数据库连接和Session对象。第二套配置包含模型类和数据库表之间的映射关系。我们可以使用基于XML或属性的配置来配置与数据库连接相关的配置。我们可以使用基于XML或注解的配置来提供模型类和数据库表的映射关系。我们将使用javax.persistence中的JPA注解来进行基于注解的映射。我们的最终项目将如下图所示。在Eclipse或您喜欢的IDE中创建一个Maven项目,您可以使用任何自己喜欢的名称。在我们继续项目的不同组件之前,我们需要进行数据库设置。

数据库表设置

我使用的是 MySQL 数据库,下面的脚本用于创建必要的表。

CREATE TABLE `Employee` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `role` varchar(20) DEFAULT NULL,
  `insert_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;

请注意,MySQL会自动生成员工表格中的“id”列,因此我们不需要插入它。

Hibernate项目依赖

我们最终的pom.xml文件如下所示。

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.Olivia.hibernate</groupId>
  <artifactId>HibernateExample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>HibernateExample</name>
  
  <dependencies>
  	<dependency>
  		<groupId>org.hibernate</groupId>
  		<artifactId>hibernate-core</artifactId>
  		<version>4.3.5.Final</version>
  	</dependency>
  	<!-- Hibernate 4 uses Jboss logging, but older versions slf4j for logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
        	<groupId>mysql</groupId>
        	<artifactId>mysql-connector-java</artifactId>
        	<version>5.0.5</version>
        </dependency>
  </dependencies>
  
  <build>
  	<finalName>${project.artifactId}</finalName>
  </build>
</project>

hibernate-core 组件包含了所有核心的 hibernate 类,所以通过将其包含在项目中,我们将得到所有必要的功能。需要注意的是,我在我的样例项目中使用的是最新的 Hibernate 版本(4.3.5.Final),而 Hibernate 在不断演进中,我已经看到了许多核心类在每个主要版本发布时的变化。所以如果你使用的是其他版本,有一小部分可能需要修改 Hibernate 的配置才能使其正常工作。然而,对于所有 4.x.x 的版本,我确信它能够正常工作。Hibernate 4 使用 JBoss 日志库,而旧版本使用 slf4j 进行日志记录,所以我在我的项目中也包含了 slf4j-simple 组件,尽管实际上并不需要,因为我使用的是 Hibernate 4。mysql-connector-java 是连接到 MySQL 数据库的 MySQL 驱动程序,如果你使用其他数据库,则需要添加相应的驱动程序组件。

领域模型类

如上图所示,我们有两个模型类,Employee和Employee1。Employee是一个简单的Java Bean类,我们将使用基于XML的配置来提供其映射详情。Employee1是一个Java Bean类,其中字段使用JPA注解,因此我们无需在单独的XML文件中提供映射。

package com.Olivia.hibernate.model;

import java.util.Date;

public class Employee {

	private int id;
	private String name;
	private String role;
	private Date insertTime;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
	public Date getInsertTime() {
		return insertTime;
	}
	public void setInsertTime(Date insertTime) {
		this.insertTime = insertTime;
	}
	
}

员工类是一个简单的Java bean,这里没有什么特别需要讨论的。

package com.Olivia.hibernate.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name="Employee", 
	   uniqueConstraints={@UniqueConstraint(columnNames={"ID"})})
public class Employee1 {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="ID", nullable=false, unique=true, length=11)
	private int id;
	
	@Column(name="NAME", length=20, nullable=true)
	private String name;
	
	@Column(name="ROLE", length=20, nullable=true)
	private String role;
	
	@Column(name="insert_time", nullable=true)
	private Date insertTime;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
	public Date getInsertTime() {
		return insertTime;
	}
	public void setInsertTime(Date insertTime) {
		this.insertTime = insertTime;
	}
}

javax.persistence.Entity注解用于标记一个类作为实体Bean,可以被Hibernate持久化,因为Hibernate提供了JPA实现。javax.persistence.Table注解用于定义表映射和列的唯一约束。javax.persistence.Id注解用于定义表的主键。javax.persistence.GeneratedValue用于定义字段将会被自动生成,生成策略采用GenerationType.IDENTITY,以便将生成的“id”值映射到Bean并可以在Java程序中检索。javax.persistence.Column用于将字段映射到表列,我们还可以为Bean属性指定长度、可为空性和唯一性。

Hibernate映射XML配置

如上所述,我们将使用基于XML的配置来进行Employee类的映射。我们可以选择任何名称,但为了清晰起见,最好选择与表或Java bean名称相符的名称。我们的Employee bean的Hibernate映射文件如下所示: employee.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
	<class name="com.Olivia.hibernate.model.Employee" table="EMPLOYEE">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="increment" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="role" type="java.lang.String">
            <column name="ROLE" />
        </property>
        <property name="insertTime" type="timestamp">
        	<column name="insert_time" />
        </property>
    </class>
</hibernate-mapping>

XML配置很简单,与基于注解的配置实现相同功能。

Hibernate配置文件

我们将创建两个Hibernate配置XML文件——一个用于基于XML的配置,另一个用于基于注解的配置。hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- Database connection properties - Driver, URL, user, password -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
		<property name="hibernate.connection.username">scdev</property>
		<property name="hibernate.connection.password">scdev123</property>
		<!-- Connection Pool Size -->
		<property name="hibernate.connection.pool_size">1</property>
		
		<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
		<property name="hibernate.current_session_context_class">thread</property>
		
		<!-- Outputs the SQL queries, should be disabled in Production -->
		<property name="hibernate.show_sql">true</property>
		
		<!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle etc
			Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 

		<!-- mapping file, we can use Bean annotations too --> 
		<mapping resource="employee.hbm.xml" />
	</session-factory>
</hibernate-configuration>

大多数属性与数据库配置有关,其他属性的具体细节在注释中给出。请注意,对于Hibernate映射文件的配置,我们可以在这里定义多个Hibernate映射文件并进行配置。同时要注意,映射是针对会话工厂的。 hibernate-annotation.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- Database connection properties - Driver, URL, user, password -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
		<property name="hibernate.connection.username">scdev</property>
		<property name="hibernate.connection.password">scdev123</property>
		
		<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
		<property name="hibernate.current_session_context_class">thread</property>
		
		<!-- Mapping with model class containing annotations -->
		<mapping class="com.Olivia.hibernate.model.Employee1"/>
	</session-factory>
</hibernate-configuration>

大部分的配置和基于XML的配置是相同的,唯一的区别在于映射配置。我们可以为类和包提供映射配置。

Hibernate的SessionFactory

我已经创建了一个实用类,其中我正在从基于XML的配置和基于属性的配置创建SessionFactory。对于基于属性的配置,我们可以有一个属性文件并在类中读取它,但为了简单起见,我正在在类本身中创建Properties实例。

package com.Olivia.hibernate.util;

import java.util.Properties;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

import com.Olivia.hibernate.model.Employee1;

public class HibernateUtil {

	//XML based configuration
	private static SessionFactory sessionFactory;
	
	//Annotation based configuration
	private static SessionFactory sessionAnnotationFactory;
	
	//Property based configuration
	private static SessionFactory sessionJavaConfigFactory;

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
        	Configuration configuration = new Configuration();
        	configuration.configure("hibernate.cfg.xml");
        	System.out.println("Hibernate Configuration loaded");
        	
        	ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        	System.out.println("Hibernate serviceRegistry created");
        	
        	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        	
            return sessionFactory;
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    private static SessionFactory buildSessionAnnotationFactory() {
    	try {
            // Create the SessionFactory from hibernate.cfg.xml
        	Configuration configuration = new Configuration();
        	configuration.configure("hibernate-annotation.cfg.xml");
        	System.out.println("Hibernate Annotation Configuration loaded");
        	
        	ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        	System.out.println("Hibernate Annotation serviceRegistry created");
        	
        	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        	
            return sessionFactory;
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
	}

    private static SessionFactory buildSessionJavaConfigFactory() {
    	try {
    	Configuration configuration = new Configuration();
		
		//Create Properties, can be read from property files too
		Properties props = new Properties();
		props.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
		props.put("hibernate.connection.url", "jdbc:mysql://localhost/TestDB");
		props.put("hibernate.connection.username", "scdev");
		props.put("hibernate.connection.password", "scdev123");
		props.put("hibernate.current_session_context_class", "thread");
		
		configuration.setProperties(props);
		
		//we can set mapping file or class with annotation
		//addClass(Employee1.class) will look for resource
		// com/scdev/hibernate/model/Employee1.hbm.xml (not good)
		configuration.addAnnotatedClass(Employee1.class);
		
		ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
    	System.out.println("Hibernate Java Config serviceRegistry created");
    	
    	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    	
        return sessionFactory;
    	}
        catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
	}
    
	public static SessionFactory getSessionFactory() {
		if(sessionFactory == null) sessionFactory = buildSessionFactory();
        return sessionFactory;
    }
	
	public static SessionFactory getSessionAnnotationFactory() {
		if(sessionAnnotationFactory == null) sessionAnnotationFactory = buildSessionAnnotationFactory();
        return sessionAnnotationFactory;
    }
	
	public static SessionFactory getSessionJavaConfigFactory() {
		if(sessionJavaConfigFactory == null) sessionJavaConfigFactory = buildSessionJavaConfigFactory();
        return sessionJavaConfigFactory;
    }
	
}

使用基于XML的配置创建SessionFactory与基于注释的映射是相同的。对于基于属性的配置,我们需要在Configuration对象中设置属性,并在创建SessionFactory之前添加注释类。总体而言,创建SessionFactory包括以下步骤:

    1. 创建Configuration对象并进行配置

 

    1. 创建ServiceRegistry对象并应用配置设置。

 

    通过将ServiceRegistry对象作为参数传递给configuration.buildSessionFactory()方法,来获取SessionFactory对象。

我们的应用程序现在差不多已经准备好了,让我们编写一些测试程序并执行它们。

“Hibernate XML配置测试”

我们的测试程序如下所示。

package com.Olivia.hibernate.main;

import java.util.Date;

import org.hibernate.Session;

import com.Olivia.hibernate.model.Employee;
import com.Olivia.hibernate.util.HibernateUtil;

public class HibernateMain {

	public static void main(String[] args) {
		Employee emp = new Employee();
		emp.setName("Pankaj");
		emp.setRole("CEO");
		emp.setInsertTime(new Date());
		
		//Get Session
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		//start transaction
		session.beginTransaction();
		//Save the Model object
		session.save(emp);
		//Commit transaction
		session.getTransaction().commit();
		System.out.println("Employee ID="+emp.getId());
		
		//terminate session factory, otherwise program won't end
		HibernateUtil.getSessionFactory().close();
	}

}

程序是自解释的,当我们执行测试程序时,我们获得以下输出。

May 06, 2014 12:40:06 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
May 06, 2014 12:40:06 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
May 06, 2014 12:40:06 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 06, 2014 12:40:06 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
May 06, 2014 12:40:06 AM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: hibernate.cfg.xml
May 06, 2014 12:40:06 AM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: hibernate.cfg.xml
May 06, 2014 12:40:07 AM org.hibernate.cfg.Configuration addResource
INFO: HHH000221: Reading mappings from resource: employee.hbm.xml
May 06, 2014 12:40:08 AM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
Hibernate Configuration loaded
Hibernate serviceRegistry created
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=scdev, password=****}
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 1 (min=1)
May 06, 2014 12:40:08 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 06, 2014 12:40:08 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 06, 2014 12:40:08 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select max(ID) from EMPLOYEE
Hibernate: insert into EMPLOYEE (NAME, ROLE, insert_time, ID) values (?, ?, ?, ?)
Employee ID=19
May 06, 2014 12:40:08 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]

请注意,它正在打印所生成的员工ID,请查看数据库表以确认。

Hibernate注解配置测试

package com.Olivia.hibernate.main;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.Olivia.hibernate.model.Employee1;
import com.Olivia.hibernate.util.HibernateUtil;

public class HibernateAnnotationMain {

	public static void main(String[] args) {
		Employee1 emp = new Employee1();
		emp.setName("David");
		emp.setRole("Developer");
		emp.setInsertTime(new Date());
		
		//Get Session
		SessionFactory sessionFactory = HibernateUtil.getSessionAnnotationFactory();
		Session session = sessionFactory.getCurrentSession();
		//start transaction
		session.beginTransaction();
		//Save the Model object
		session.save(emp);
		//Commit transaction
		session.getTransaction().commit();
		System.out.println("Employee ID="+emp.getId());
		
		//terminate session factory, otherwise program won't end
		sessionFactory.close();
	}

}

当我们执行以上程序时,我们得到以下输出结果。

May 06, 2014 12:42:22 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
May 06, 2014 12:42:22 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
May 06, 2014 12:42:22 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 06, 2014 12:42:22 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
May 06, 2014 12:42:22 AM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: hibernate-annotation.cfg.xml
May 06, 2014 12:42:22 AM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: hibernate-annotation.cfg.xml
May 06, 2014 12:42:23 AM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
Hibernate Annotation Configuration loaded
Hibernate Annotation serviceRegistry created
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=scdev, password=****}
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
May 06, 2014 12:42:23 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 06, 2014 12:42:23 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 06, 2014 12:42:23 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Employee ID=20
May 06, 2014 12:42:23 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]

请查看输出并将其与基于XML的配置的输出进行比较,您会注意到一些差异。例如,我们在基于注释的配置中没有设置连接池大小,所以它将设置为默认值20。

测试 Java 配置的 Hibernate

package com.Olivia.hibernate.main;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.Olivia.hibernate.model.Employee1;
import com.Olivia.hibernate.util.HibernateUtil;

public class HibernateJavaConfigMain {

	public static void main(String[] args) {
		Employee1 emp = new Employee1();
		emp.setName("Lisa");
		emp.setRole("Manager");
		emp.setInsertTime(new Date());
		
		//Get Session
		SessionFactory sessionFactory = HibernateUtil.getSessionJavaConfigFactory();
		Session session = sessionFactory.getCurrentSession();
		//start transaction
		session.beginTransaction();
		//Save the Model object
		session.save(emp);
		//Commit transaction
		session.getTransaction().commit();
		System.out.println("Employee ID="+emp.getId());
		
		//terminate session factory, otherwise program won't end
		sessionFactory.close();
	}

}

以上测试程序的输出结果是:

May 06, 2014 12:45:09 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
May 06, 2014 12:45:09 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
May 06, 2014 12:45:09 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 06, 2014 12:45:09 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Hibernate Java Config serviceRegistry created
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=scdev, password=****}
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
May 06, 2014 12:45:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
May 06, 2014 12:45:10 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
May 06, 2014 12:45:10 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 06, 2014 12:45:10 AM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 06, 2014 12:45:10 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Employee ID=21
May 06, 2014 12:45:10 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]

对于初学者来说,关于Hibernate的教程就到这里了,希望这些内容足以让你入门。未来的教程中,我们将深入了解Hibernate框架的不同特性。请从下方链接下载完整的项目,并尝试使用它来进一步学习。

下载 Hibernate 初学者项目。

发表回复 0

Your email address will not be published. Required fields are marked *


广告
将在 10 秒后关闭
bannerAds