Hibernate笔记 2:配置文件详解

来自Wikioe
跳到导航 跳到搜索


关于

配置文件是 Hibernate 中相当重要的部分,对于 Hibernate、数据库、orm 等内容的都依赖于配置文件。


1、配置文件可以是: .xml文件.properties文件(属性文件);
2、配置文件中均需要引入 dtd 约束;
   - (xml 的约束格式包括:dtd、schema,而 Hibernate 的配置文件中均使用 dtd)

核心配置文件

Hibernate 核心配置文件,其名称与位置均是固定的。


关于“Hibernate 核心配置文件”:
1、文件名称和位置固定:
   - 位置:必须位于 src 下。
   - 名称:必须为“hibernate.cfg.xml”(或“hibernate.properties”)。
2、hibernate 操作过程中,只会加载核心配置文件,其他配置文件不会加载。
   - “映射关系配置文件”需要配置到“核心配置文件”中,才会被加载。

文件格式

<?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>
		
		<!-- 第一部分 数据库信息 -->
		...

		<!-- 第二部分 hibernate信息 -->
		...
		
		<!-- 第三部分 映射文件 -->
		<mapping resource="..."/>

	<session-factory>
</hibernate-configuration>
  1. 配置数据库信息:
    • 使用不同的数据库驱动(不同版本驱动)时,配置信息可能有差别。【可以从类似“mysql-connector”的包里去找相应内容】
    示例:
    1. 使用“mysql-connector-java-5.0.4-bin.jar”时:
      		<property name="hibernate.connection.driver.class">com.mysql.jdbc.Driver</property>
      		<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property>
      		<property name="hibernate.connection.username">root</property>
      		<property name="hibernate.connection.password">admin</property>
      
    2. 使用“mysql-connector-java-8.0.11.jar”时:
      		<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
      		<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day02?useSSL=false&amp;serverTimezone=UTC</property>
      		<property name="hibernate.connection.username">root</property>
      		<property name="hibernate.connection.password">admin</property>
      
  2. 配置 Hibernate 信息:
    		<!-- 控制台输出 sql 语句 -->
    		<property name="hibernate.show_sql">true</property>
    
    		<!-- 格式化输出的 sql 语句 -->
    		<property name="hibernate.format_sql">true</property>
    
    		<!-- hibernate 的 DDL 规则(update:无则创建,有则更新) -->
    		<property name="hibernate.hbm2ddl.auto">update</property>
    
    		<!-- 配置数据库方言(让 hibernate 框架识别不同数据库特有的方言) -->
    		<property name="hibernate.dialect">org.hibernate.dialect.MySqlDialect</property>
    
  3. 配置“映射关系配置文件”:
    • 需要定位到(需要加载的)“映射关系配置文件”所在包的位置。
    示例:
    		<mapping resource = "cn/itcast/entity/User.hbm.xml"/>
    

常用配置

名称 用途
hibernate.dialect 操作数据库方言
hibernate.connection.driver_class 连接数据库驱动程序
hibernate.connection.url 连接数据库 URL
hibernate.connection.username 数据库用户名
hibernate.connection.password 数据库密码
hibernate.show_sql 在控制台上输出 SQL 语句
hibernate.format_sql 格式化控制台输出的 SQL 语句
hibernate.hbm2ddl.auto 当 SessionFactory 创建时是否根据映射文件自动验证表结构或自动创建、自动更新数据库表结构。
  • 该参数的取值为: none、 validate、 update、 create 和 create-drop。
hibernate.connection.autocommit 事务是否自动提交
hibernate.hbm2ddl.auto 的取值:(DDL,即“数据库定义语言”,如:create drop alter 等)
  • none:不用 Hibernate 自动生成表;
  • create:每次都会创建新的表;【用于测试】
  • create-drop:每次都会创建新的表,执行程序结束后删除表;【用于测试】
  • update:如果数据库中有表则直接使用,否则创建新表,且可以更新表结构;
  • validate:只会使用原有的表,对映射关系进行校验;

配置:连接池

SessionFactory 内部还维护了一个连接池,如果需要使用第三方连接池(如:C3PO),则需要手动进行配置。

步骤:

  1. 引入 C3PO 相关 JAR 包:
    • c3p0-0.9.2.1.jar
    • hibernate-c3p0-5.0.7.Final.jar
    • mchange-commons-java-0.2.3.4.jar
  2. 配置 C3PO 连接池(hibernate.cfg.xml 中):
    		<!-- 配置C3PO连接池 -->
    		<property name= "connection.provider_c1ass">org.hibernate.connection.C3POConnectionProvider</property>
    		
    		<!-- 连接池中可用数据库连接的最少数目 -->
    		<property name= "c3p0.min_size">5</property>
    		
    		<!-- 连接池中所有数据库连接的最大数目 -->
    		<property name= "c3p0.max_size">20</property>
    		
    		<!-- 数据库连接的过期时间(单位:秒):
    			如果池中某个连接处于空闲状态的时间超过了 timeout 时间,就会从连接池中消除
    		-->
    		<property name= "c3p0.timeout">120</property>
    		
    		<!-- 检查连接池中的空闲连接的时间间隔(单位:秒)-->
    		<property name= "c3p0.idle_test_period ">3000</property>
    

配置:事务管理

事务隔离级别

用于设置事务的隔离级别。

配置:

		<!-- 配置 Hibernate 事务隔离级别 -->
		<property name="hibernate.connection.isolation">4</property>
可选值:
  • 1:Read uncommitted isolation;
  • 2:Read committed isolation;
  • 4:Repeatable read isolation;
  • 8:Serializable isolation。

Session 管理方式

用于追踪 Session,以实现“在我们定义的上下文环境中调用 getCurrentSession 方法获得的总是同一个 session”。

Hibernate 5 中自身提供了三种管理 Session 对象的方法。

配置:

		<!-- 配置 Session 管理方式 -->
		<property name="current_session_context_class">thread</property>
可选值:
  • thread:Session 对象的生命周期与本地线程绑定;【使用“本地事务”(JDBC 事务)】
  • jta:Session 对象的生命周期与 JTA 事务绑定;【使用“全局事务”(JTA 事务)】
  • managed由 Hibernate 托管程序来管理 Session 对象的生命周期。【不常用】
全局事务:资源管理器管理和协调的事务,可以跨越多个数据库和进程。资源管理器一般使用 XA 二阶段提交协议与“企业信息系统”(EIS)或数据库进行交互。   

本地事务:在单个 EIS 或数据库的本地并且限制在单个进程内的事务。本地事务不涉及多个数据来源。

映射配置文件

“映射关系”,即:实体类和数据库表一一对应的关系。


关于“映射关系配置文件”:
1、文件名称位置 没有固定要求;
   - 建议:在实体类所在包里面创建,名称为“<实体类名称>.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> 

	<!-- class 标签:建立“类”和“表”的映射
		* name 属性 :类中的全路径
		* table 属性 :表名(如果类名和表名一致,则该属性可以省略)
		* catalog 属性:数据库名称,可以省略
	-->
	<class name="XXX.XXX.XXX" table="ZZZ">
		
		<!-- id 标签:建立“类中的唯一性属性”与“表中的主键”的映射
			* name 属性 :类中的属性名
			* column 属性:表中的字段名(如果“类的属性名”和“表中的字段名”一致,则可省略)
			* length 属性:字段的长度
			* type 属性:类型。写Java数据类型,Hibernate数据类型(默认),SQL类型
		-->
		<id name="xxx" column="zzz">
			<!-- 主键生成策略 -->
			<generator class="???"/> 
		</id> 
		
		<!-- id 标签: 建立“类中的普通属性”与“表中的字段”的映射
			* name 属性 :类中的属性名
			* column 属性:表中的字段名(如果“类的属性名”和“表中的字段名”一致,则可省略)
			* length 属性:字段的长度
			* type 属性:类型。写Java数据类型,Hibernate数据类型(默认),SQL类型
		-->
		<property name="xxx" column="zzz" type="???"/>
		<property name="xxx" column="zzz" type="???"/>
		<property name="xxx" column="zzz"/>
		<property name="xxx" column="zzz"/>
	</class> 
</hibernate-mapping>
  1. <class> 用于配置“实体类”与“表”的对应;
    • “name”属性值为“实体类的全路径”;
  2. <id> 用于配置“(具有唯一性的)实体类的属性”与“(具有唯一性的)表的字段”的对应;
    • “column”属性可以省略(与“name”一致);
    • <generator> 用于配置主键的“增长方式”;
      1. uuid
      2. native(自增);
  3. <property> 用于配置“实体类的属性”与“表的字段”的对应;
    • “column”属性可以省略(与“name”一致);
    • “type”属性用于设置生成表字段的类型(自动对应类型);


示例,“Customer.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> 
	<class name="cn.itcast.domain.Customer" table="customer">		
		<id name="cust_id" column="id"> 
			<generator class="native"/> 
		</id> 
		<property name="cust_name" column="name"/> 
		<property name="cust_source" column="source"/> 
		<property name="cust_industry" column="industry"/> 
		<property name= "cust_level" column= "level"/> 
		<property name="cust_phone" column="phone"/> 
		<property name="cust_mobile" column="mobile"/>
	</class> 
</hibernate-mapping>

实体关系配置

实体关联:一对多

一端

...
<hibernate-mapping>
	<class name="full.path.Class_A" table="table_X">
		<id name="a" column="x">
			<generator class="native"/>
		</id>
		
		<property name="a1" column="x1" length="32"/>
		<property name="a2" column="x2"/>
		
		<!-- 配置关联关系 -->
		<!-- set 标签:“关联对象集合”
			* name:“关联对象集合”的名称
		-->
		<set name="a_bbb" cascade="save-update,delete">
			<!-- key 标签:关联关系中的外键
				* column:【关联关系中的“外键字段名称”(即,“多端”数据表的外键)】
			-->
			<key column="foreign-key-of-table_Y"></key>
			<!-- one-to-many 标签:配置数据表外键
				* class:“关联对象集合”的类型全名
			-->
			<one-to-many class= "full.path.Class_B"/>
		</set>
	</class>
</hibernate-mapping>

多端

...
<hibernate-mapping>
	<class name="full.path.Class_B" table="table_Y">
		<id name= "b" column="y">
			<generator class="native"/>
		</id>
		
		<property name="b1" column="y1" length="32"/>
		<property name="b2" column="y2"/>
		
		<!-- 配置关联关系 -->
		<!-- many-to-one 标签:“关联对象”
			* name:“关联对象”的属性名称
			* class:“关联对象”的类型全名
			* column:【关联关系中的“外键字段名称”(即,“多端”数据表的外键)】	
		-->
		<many-to-one name="b_a" class="full.path.Class_A" column="foreign-key-of-table_Y"/>
	</class>
</hibernate-mapping>

实体关联:多对多

格式

...
<hibernate-mapping>
	<class name="full.path.Class_A" table="table_X">
		<id name= "a" column="x"> 
			<generator class="native"/> 
		</id>
	
		<property name="a1" column="x1"/> 
		<property name="a2" column="x2"/> 
		<property name="a3" column="x3"/> 
		
		<!-- 配置关联关系 -->
		<!-- set 标签:“关联对象集合”
			* name:“关联对象集合”的名称
			* table:中间表表名
		-->
		<set name="a_bbb" table="table_X_Y">
			<!-- key 标签:关联关系中的外键
				* column:【“当前表的主键” 所对应的 “中间表的外键字段”】
			-->
			<key column="_x"></key>
			<!-- one-to-many 标签:配置数据表外键
				* class:“关联对象集合”的类型全名
				* column:【“关联表的主键” 所对应的 “中间表的外键字段”】
			-->
			<many-to-many class= "full.path.Class_B" column="_y"/>
		</set>
	</class>
</hibernate-mapping>
  • 另一边同理。

实体关联:一对一

一对一关系,可分为“主键关联”、“外键关联”。    ——都需要在其中一边建立外键。

以下以“主控端”(不建立外键)与“非主控端”(建立外键)来区分。    —— 如需“单项关联”,则仅配置“非主控端”。

<one-to-one> 标签:

  • 默认使用“主键关联”;
    • 需要用到 constrained 属性。
  • 对于“外键关联”,需要用到 property-ref 属性;
  • 没有 column 属性,但可以有 class 等属性;

主键关联

主控端:

...
<hibernate-mapping>
	<class name="full.path.Class_A" table="table_X">
		<id name="a" column="x">
			<!-- 主键生成策略 -->
			<generator class="native"/>
		</id>
		
		<property name="a1" column="x1"/> 
		<property name="a2" column="x2"/> 
		<property name="a3" column="x3"/> 
		
		<!-- one-to-one 标签:默认使用“主键关联” 
			* name:“关联对象”的属性名称
		-->
		<one-to-one name="a_b"></one-to-one>
	</class>
</hibernate-mapping>

非主控端:

...
<hibernate-mapping>
	<class name="full.path.Class_B" table="table_Y">
		<id name="b" column="y">
			<!-- 主键生成策略“foreign”:申明该主键就是外键 -->
			<generator class="foreign">
				<!-- 将主键属性指向“关联对象” -->
				<param name="property">b_a</param>
			</generator>
		</id>
		
		<property name="b1" column="y1"/>
		<property name="b2" column="y2"/>
		
		<!-- one-to-one:默认使用“主键关联”
			* name:“关联对象”的属性名称
			* constrained:1、表明主键作为外键使用;2、级联关系的作用【???】
		-->
		<one-to-one name="b_a" constrained="true"></one-to-one>
	</class>
</hibernate-mapping>

外键关联

主键端:

...
<hibernate-mapping>
	<class name="full.path.Class_A" table="table_X">
		<id name="a" column="x">
			<!-- 主键生成策略 -->
			<generator class="native"/>
		</id>
		
		<property name="a1" column="x1"/> 
		<property name="a2" column="x2"/> 
		<property name="a3" column="x3"/> 
		
		<!-- one-to-one:用作“外键关联”
			* name:“关联对象”的属性名称
			* property-ref:【“关联类”中与当前类相关的属性】(Class_B 的“关联对象”的属性名称)
			* class:“关联对象”的类型全名(“关联类”的全路径名称)
		-->
		<one-to-one name="a_b" property-ref="b_a" class="full.path.Class_B"></one-to-one>
	</class>
</hibernate-mapping>
  • property-ref 用于指定“当前类”与“关联类”中的哪个“属性”作关联。
    • 如果不指定 property-ref,则默认与“关联类”中的“主键属性”(数据库主键对应的类属性)相关联。(相当于“主键关联”的效果)

非主控端:

...
<hibernate-mapping>
	<class name="full.path.Class_B" table="table_Y">
		<id name="b" column="y">
			<!-- 主键生成策略 -->
			<generator class="native"/>   
		</id>
		
		<property name="b1" column="y1"/>
		<property name="b2" column="y2"/>
		
		<!-- many-to-one 标签:通过 unique 将 many-to-one 约定为特例,用作 one-to-one 
			* name:“关联对象”的属性名称
			* column:【关联关系中的“外键字段名称”】(即,“table_Y 表的外键字段”)
			* unique:【指定此端(many)为一】
		-->
		<many-to-one name="b_a" column="_y" unique="true"></many-to-one>
	</class>
</hibernate-mapping>