Hibernate 基础配置及常用功能(一)
本来是想等全部框架测试完以后再统一发布的,但是随着测试的一点点增加感觉把需要叙述的东西放在一起终将会是一场灾难。所以还是打算分成几章来描述,其中还包括一些有待解决的问题。短期很难腾出时间来仔细阅读Hibernate 5.x以后版本的官方文档,只能先记录下来。
首先声明一点,我在写这篇文章的时候结合了5.0.6和4.3.11两个版本,结果发现新版有不少变化,一些在4.3.11中正常的功能在新版本之中有很大不同。
一、通过Maven引入依赖
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.learnhow</groupId> <artifactId>Hibernate_Demo</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>Hibernate_Demo Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- 引入新版依赖 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.0.6.Final</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.13</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.20.0-GA</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- Hibernate官方推荐的数据库连接池是c3p0 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>5.0.6.Final</version> </dependency> </dependencies> <build> <finalName>Hibernate5_Demo</finalName> </build> </project>
以上的配置中加入了对c3p0数据源的依赖,实际使用中却很少使用。因为在生产环境中,更主流的配置方法是通过Spring来结合各个模块,因此数据源也是在Spring中配置的。更何况现在国内比较流行使用alibaba的druid。
下面提供的是4.11.3版本的依赖,就是核心版本和c3p0版本号变了一下,其他都一样。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.learnhow</groupId> <artifactId>Hibernate_Demo</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>Hibernate_Demo Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- 引入4.x版本依赖包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.11.Final</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.13</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.20.0-GA</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- 这里配置的c3p0数据源最好和你所使用的hibernate版本一致 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>4.3.11.Final</version> </dependency> </dependencies> <build> <finalName>Hibernate4_Demo</finalName> </build> </project>
二、配置hibernate.cfg.xml文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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> <!-- 数据源配置 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/learnhow</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- 数据源配置中只要使用了hibernate.c3p0.前缀,Hibernate就会调用c3p0数据源 --> <!-- 连接池中保留的最小连接数 --> <property name="hibernate.c3p0.min_size">5</property> <!-- 连接池中保留的最大连接数 --> <property name="hibernate.c3p0.max_size">10</property> <!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 --> <property name="hibernate.c3p0.timeout">1800</property> <!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 --> <property name="hibernate.c3p0.acquire_increment">3</property> <!-- SQL 数据库方言,配置数据库类型 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- session交给hibernate管理 --> <property name="current_session_context_class">thread</property> <!-- 是否显示sql语句 --> <property name="show_sql">true</property> <!-- 是否对语句格式化输出 --> <property name="format_sql">true</property> <!-- 使用hibernate管理输出表的创建及设置创建模式 --> <property name="hbm2ddl.auto">update</property> <!-- 用户配置 --> </session-factory> </hibernate-configuration>
值得一提的是,网上有很多讲关于如何在Hibernate中配置c3p0数据源的文章,几乎90%都是错误的。原因是Hibernate4.x版本以后就更改了数据源的配置方式,但是官方文档并没有及时修改,因此大家都仅仅是翻译了一下。我在配置的时候参考了5.0.6版本中有关配置c3p0数据源的说明。原文如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
5.1.2. Using c3p0
Important
To use this integration, the application must include the hibernate-c3p0 module jar (as well as its dependencies) on the classpath.
Hibernate also provides support for applications to use c3p0 connection pooling. When using this c3p0 support, a number of additional configuration settings are recognized.
Transaction isolation of the Connections is managed by the ConnectionProvider itself. See Section 5.1.7, “ConnectionProvider support for transaction isolation setting”.
Additional settings
hibernate.connection.driver_class
The name of the JDBC Driver class to use
hibernate.connection.url
The JDBC connection url.
Any settings prefixed with hibernate.connection. (other than the "special ones")
These all have the hibernate.connection. prefix stripped and the rest will be passed as JDBC connection properties
hibernate.c3p0.min_size or c3p0.minPoolSize
The minimum size of the c3p0 pool. See http://www.mchange.com/projects/c3p0/#minPoolSize
hibernate.c3p0.max_size or c3p0.maxPoolSize
The maximum size of the c3p0 pool. See http://www.mchange.com/projects/c3p0/#maxPoolSize
hibernate.c3p0.timeout or c3p0.maxIdleTime
The Connection idle time. See http://www.mchange.com/projects/c3p0/#maxIdleTime
hibernate.c3p0.max_statements or c3p0.maxStatements
Controls the c3p0 PreparedStatement cache size (if using). See http://www.mchange.com/projects/c3p0/#maxStatements
hibernate.c3p0.acquire_increment or c3p0.acquireIncrement
Number of connections c3p0 should acquire at a time when pool is exhauted. See http://www.mchange.com/projects/c3p0/#acquireIncrement
hibernate.c3p0.idle_test_period or c3p0.idleConnectionTestPeriod
Idle time before a c3p0 pooled connection is validated. See http://www.mchange.com/projects/c3p0/#idleConnectionTestPeriod
c3p0.initialPoolSize
The initial c3p0 pool size. If not specified, default is to use the min pool size. See http://www.mchange.com/projects/c3p0/#initialPoolSize
Any other settings prefixed with hibernate.c3p0.
Will have the hibernate. portion stripped and be passed to c3p0.
Any other settings prefixed with c3p0.
Get passed to c3p0 as is. See http://www.mchange.com/projects/c3p0/#configuration
大意就是配置c3p0数据源首先需要引入相关依赖,然后只需要在配置文件中增加的任何一条语句是以hibernate.c3p0.为前缀,Hibernate就会默认使用c3p0管理数据库。
如果不需要配置第三方数据源也可以使用Hibernate直接操作数据库,只需要把有关c3p0的配置删掉就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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> <!-- 数据库连接配置 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/learnhow</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- JDBC连接池,开发环境设置1就可以了 --> <property name="connection.pool_size">1</property> <!-- 数据库方言 --> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <!-- session交给hibernate管理 --> <property name="current_session_context_class">thread</property> <!-- 是否显示sql语句 --> <property name="show_sql">true</property> <!-- 是否对语句格式化输出 --> <property name="hbm2ddl.auto">update</property> </session-factory> </hibernate-configuration>
三、获取SessionFactory
使用过Hibernate3.x版本的大概都知道,Hibernate是通过SessionFactory作为管理接口的。在4.x版本后,官方提供了一个新的配置方法,即所有的操作都必须首先在StandardServiceRegistry中注册。具体方法如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package util; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try{ Configuration configuration = new Configuration().configure(); StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); 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() { return sessionFactory; } }
但是在5.x版本中,官方又更改了获取SessionFactory的方法,我查了新版本的文档似乎并没有找到修改的原因和官方提供的获取SessionFactory的标准方法。以下我修改的代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package util; import org.hibernate.SessionFactory; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); public static SessionFactory getSessionFactory() { return sessionFactory; } private static SessionFactory buildSessionFactory() { final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build(); try { SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory(); return sessionFactory; } catch (Exception e) { System.out.println(e); StandardServiceRegistryBuilder.destroy(registry); } return null; } }
以上三步基本可以完成对Hibernate的功能配置,不过实际使用中这样配置已经不多见了。