Hibernate笔记 2:配置文件详解
跳到导航
跳到搜索
关于
配置文件是 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>
- 配置数据库信息:
- 使用不同的数据库驱动(不同版本驱动)时,配置信息可能有差别。【可以从类似“mysql-connector”的包里去找相应内容】
- 示例:
- 使用“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>
- 使用“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&serverTimezone=UTC</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">admin</property>
- 配置 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>
- 配置“映射关系配置文件”:
- 需要定位到(需要加载的)“映射关系配置文件”所在包的位置。
- 示例:
<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),则需要手动进行配置。
步骤:
- 引入 C3PO 相关 JAR 包:
- c3p0-0.9.2.1.jar
- hibernate-c3p0-5.0.7.Final.jar
- mchange-commons-java-0.2.3.4.jar
- 配置 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>
<class>
用于配置“实体类”与“表”的对应;- “name”属性值为“实体类的全路径”;
<id>
用于配置“(具有唯一性的)实体类的属性”与“(具有唯一性的)表的字段”的对应;- “column”属性可以省略(与“name”一致);
<generator>
用于配置主键的“增长方式”;- uuid;
- native(自增);
<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,则默认与“关联类”中的“主键属性”(数据库主键对应的类属性)相关联。(相当于“主键关联”的效果)
- 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>