Hibernate配置文件中映射元素详解
什么是Hibernate ?
Hibernate可以完成[对象]<=>[关系]的映射工作,也就是经常听到的Object/Relation Mapping(ORM),在没有ORM的时候,开发者需要自己开发对象到数据库的映射工作,一般来说在Java世界中是通过JDBC来实现,在.Net世界是通过ADO.net来实现,众所周知这一项任务是繁琐耗时的,因为要在代码中内置大量的SQL语句,这使得代码的可读性和可维护性大大降低。现在,Hibernate可以为我们来做这项工作,我们只需要配置一个Mapping文件即可,剩下的所有事情就交给Hibernate吧,这样可以节省对象持久化相关的至少30%的JDBC/ADO.net编程工作量,这是多么的令人兴奋阿。
1、什么是持久化层?
企业软件架构比较流行的三层结构是大家比较熟悉的,那就是自上而下为:
[显示表述层]=>[业务逻辑层]=>[数据库层]
这种结构中,业务逻辑层不仅负责业务逻辑,而且直接访问数据库,提供对业务数据的增、删、改、查的操作。为了把数据访问的细节和业务逻辑分开,可以把数据访问作为单独的持久化层。重新分层后自上而下变为:
[显示表述层]=>[业务逻辑层]=>[持久化层]=>[数据库层]
这样持久化层封装数据访问细节,为业务逻辑提供面向对象的API。一个完善的持久化层应该达到以下几个目标:
(1)代码重用性高,能够完成所有的DB访问操作;
(2)能够支持多种数据库平台;
(3)具有独立性,持久化层的具体实现的变化不能影响上层的实现。
正因为这几个目标的艰巨,在企业级开发中花费大量的时间,采用高级相关技术工程师去重头开发自己的持久层不是很可行的,Hibernate作为持久层中间件,它的具体实现对上层是透明的,开发者无需关系它的具体实现,只需要知道如何访问他的接口就行了。
2、什么是ORM?
ORM(Object-Relation Mapping)是对象-关系映射,当下流行的开发语言都是面向对象的,如Java,C#。而当下流行的DB大多都是面向关系的,也就是关系数据库。这样在面向对象与面向关系之间需要一个桥梁,才能使二者协同无缝联合工作,ORM就是这个桥梁。映射关系如下:
[类]<=>[表] [对象实例]<=>[表的行] [属性]<=>[表的列]
那么这些映射关系是如何制定的呢?——只需要一个映射文件(XML)即可,在其中配置持久化类与DB表的映射关系后,ORM中间件在运行时参照此文件内容,对象持久化的DB中或把DB中数据加载到持久化类中。
Hibernate就是一个卓越的ORM中间件。
3、ORM是怎么映射的?
要把类的属性与DB表的Field对应,ORM就必须能识别类的属性名字和数值。这就必须才用反射(Reflection)技术,相信有一定开发经验的人对此技术都是耳熟能详了吧,当前主流开发语言都支持此技术,如Java和.net,而且具体用法都如出一辙。当然对于那些只想使用ORM而不关心ORM的具体实现的朋友,这些内容不了解也没有任何影响。这也恰恰是ORM的好处啊。
4、Hibernate采用的一个技术
当配置为自动决定何时把对象数据写入DB的模式下,Hibernate采用了一个自动识别对象属性变化的技术。即Hibernate知道持久化类哪些属性发生了变化,然后据此来决定后便的操作。关于此技术更具体的内容,以后再详述。
5、缓存
从内存中获取数据要比从DB中获取数据快得多,所以很多ORM都采用缓存结束来提高持久化效率,Hibernate也不例外。在Session中保留所有已经持久化的对象实例作为缓存,如果需要获取的数据在缓存中存在,则不去DB中加载。当然缓存中数据与DB中数据的一致性问题,Hibernate就是通过刚刚说过的[识别对象属性变化]的技术来实现的。
6、什么是HQL?
HQL(Hibernate Query Language)是Hibernate自己的查询语句,它与SQL相似,但是HQL是面向对象的,它引用类名及类的属性名,而不是表名及表的字段名。
本文中将讲述Hibernate的基本配置及配置文件的应用,这对于正确熟练使用Hibernate是相当关键的。
配置文件中映射元素详解
对象关系的映射是用一个XML文档来说明的。映射文档可以使用工具来生成,如XDoclet,Middlegen和AndroMDA等。下面从一个映射的例子开始讲解映射元素,映射文件的代码如下。
<?xml version="1.0"?>
<!--
所有的XML映射文件都需要定义如下所示的DOCTYPE。
Hibernate会先在它的类路径(classptah)中搜索DTD文件。
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
hibernate-mapping有几个可选的属性:
schema属性指明了这个映射的表所在的schema名称。
default-cascade属性指定了默认的级联风格 可取值有 none、save、update。
auto-import属性默认让我们在查询语言中可以使用非全限定名的类名 可取值有 true、false。
package属性指定一个包前缀。
-->
<hibernate-mapping schema="schemaName" default-cascade="none"
auto-import="true" package="test">
<!--用class元素来定义一个持久化类 -->
<class name="People" table="person">
<!-- id元素定义了属性到数据库表主键字段的映射。-->
<id name="id">
<!-- 用来为该持久化类的实例生成唯一的标识 -->
<generator class="native"/>
</id>
<!-- discriminator识别器 是一种定义继承关系的映射方法-->
<discriminator column="subclass" type="character"/>
<!-- property元素为类声明了一个持久化的,JavaBean风格的属性-->
<property name="name" type="string">
<column name="name" length="64" not-null="true" />
</property>
<property name="sex"
not-null="true"
update="false"/>
<!--多对一映射关系-->
<many-to-one name="friend"
column="friend_id"
update="false"/>
<!--设置关联关系-->
<set name="friends" inverse="true" order-by="id">
<key column="friend_id"/>
<!—一对多映射-->
<one-to-many class="Cat"/>
</set>
</class>
</hibernate-mapping>
组件应用的方法
组件有两种类型,即组件(component)和动态组件(dynamic-component)。在配置文件中,component元素为子对象的元素与父类对应表的字段建立起映射关系。然后组件可以声明它们自己的属性、组件或者集合。component元素的定义如下所示:
<component name="propertyName" class="className" insert="true|false"
upate="true|false" access="field|property|ClassName">
<property ...../>
<many-to-one .... />
........
</component>
在这段代码中,name是指属性名,class是类的名字,insert指的是被映射的字段是否出现在SQL的INSERT语句中,upate指出被映射的字段是否出现在SQL的UPDATE语句中,access指出访问属性的策略。
Hiebernate的基本配置
Hibernate的数据库连接信息是从配置文件中加载的。
Hibernate的配置文件有两种形式:一种是XML格式的文件,一种是properties属性文件。properties形式的配置文件默认文件名是hibernate.properties,一个properties形式的配置文件内容如下所示:
#指定数据库使用的驱动类
hibernate.connection.driver_class = com.mysql.jdbc.Driver r
#指定数据库连接串
hibernate.connection.url = jdbc:mysql://localhost:3306/db
#指定数据库连接的用户名
hibernate.connection.username = user
#指定数据库连接的密码
hibernate.connection.password = password
#指定数据库使用的方言
hibernate.dialect = net.sf.hibernate.dialect.MySQLDialect
#指定是否打印SQL语句
hibernate.show_sql=true
在配置文件中包含了一系列属性的配置,Hibernate将根据这些属性来连接数据库。
在XML格式的配置文件中,除了基本的Hibernate配置信息,还可以指定具体的持久化类的映射文件,这可以避免将持久化类的配置文件硬编码在程序中。XML格式的配置文件的默认文件名为hibernate.cfg.xml,一个XML配置文件的示例如下所示:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--显示执行的SQL语句-->
<property name="show_sql">true</property>
<!--连接字符串-->
<property name="connection.url">jdbc:mysql://localhost:3306/STU</property>
<!--连接数据库的用户名-->
<property name="connection.username">root</property>
<!--数据库用户密码-->
<property name="connection.password">root</property>
<!--数据库驱动-->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!--选择使用的方言-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--映射文件 -->
<mapping resource="com/stuman/domain/Admin.hbm.xml" />
<!--映射文件-->
<mapping resource="com/stuman/domain/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
properties形式的配置文件和XML格式的配置文件可以同时使用。当同时使用两种类型的配置文件时,XML配置文件中的设置会覆盖properties配置文件的相同的属性。
对象标识符号
在关系数据库表中,主键(Primary Key)用来识别记录,并保证每条记录的唯一性。在Java语言中,通过比较两个变量所引用对象的内存地址是否相同,或者比较两个变量引用的对象值是否相同来判断两对象是否相等。Hibernate为了解决两者之间的不同,使用对象标识符(OID)来标识对象的唯一性。OID是关系数据库中主键在Java对象模型中的等价物。在运行时,Hibernate根据OID来维持Java对象和数据库表中记录的对应关系。如下代码所示,三次调用了Session的load()方法,分别加载OID为1或3的User对象。
Transaction tx = session.beginTransaction();
User user1 = (User)session.load(User.class,new Long(1));
User user2 = (User)session.load(User.class,new Long(1));
User user3 = (User)session.load(User.class,new Long(3));
System.out.println( user1 == user2 );
System.out.println( user1 == user3 );
应用程序在执行上述代码时,第一次加载OID为1的User对象,从数据库中查找ID为1的记录,然后创建相应的User实例,并把它保存在Session缓存中,最后将该实例的引用赋值给变量user1。第二次加载OID为1的对象时,直接把Session缓存中OID为1的实例的引用赋值给变量user2。因此,表达式user1==user2的结果为true。
标识的生成可以使用不同的策略,表1为Hibernate内置的标识生成策略。
表1 Hibernate标识生成策略
标识符生成器
描述
increment 适用于代理主键。由Hibernate自动以递增方式生成。
identity 适用于代理主键。由底层数据库生成标识符。
sequence 适用于代理主键。Hibernate根据底层数据库的序列生成标识符,这要求底层数据库支持序列。
hilo 适用于代理主键。Hibernate分局high/low算法生成标识符。
seqhilo 适用于代理主键。使用一个高/低位算法来高效的生成long,short或者int类型的标识符。
native 适用于代理主键。根据底层数据库对自动生成标识符的方式,自动选择identity、sequence或hilo。
uuid.hex 适用于代理主键。Hibernate采用128位的UUID算法生成标识符。
uuid.string
适用于代理主键。UUID被编码成一个16字符长的字符串。
assigned 适用于自然主键。由Java应用程序负责生成标识符。
foreign 适用于代理主键。使用另外一个相关联的对象的标识符。
Hibernate映射类型
在对象/关系映射文件中,Hibernate采用映射类型作为Java类型和SQL类型的桥梁。Hibernate映射类型分为2种:内置映射类型和自定义映射类型。
1、内置映射类型
Hibernate对所有的Java原生类型、常用的Java类型如String、Date等都定义了内置的映射类型。表2列出了Hibernate映射类型、对应的Java类型以及对应的标准SQL类型。
表2 Hibernate内置映射类型
Hibernate映射类型 Java类型 标准SQL类型 大小
integer/int java.lang.Integer/int INTEGER 4字节
long java.lang.Long/long BIGINT 8字节
short java.lang.Short/short SMALLINT 2字节
byte java.lang.Byte/byte TINYINT 1字节
float java.lang.Float/float FLOAT 4字节
double java.lang.Double/double DOUBLE 8字节
big_decimal java.math.BigDecimal NUMERIC
character java.lang.Character/java.lang.String/char CHAR(1) 定长字符
string java.lang.String VARCHAR 变长字符
boolean/ yes_no/true_false java.lang.Boolean/Boolean BIT 布尔类型
date java.util.Date/java.sql.Date DATE 日期
timestamp java.util.Date/java.util.Timestamp TIMESTAMP 日期
calendar java.util.Calendar TIMESTAMP 日期
calendar_date java.util.Calendar DATE 日期
binary byte[] BLOB
BLOB
text java.lang.String TEXT CLOB
serializable 实现java.io.Serializablej接口的任意Java类 BLOB BLOB
clob java.sql.Clob CLOB CLOB
blob java.sql.Blob BLOB BLOB
class java.lang.Class VARCHAR 定长字符
locale java.util.Locale VARCHAR 定长字符
timezone java.util.TimeZone VARCHAR 定长字符
currency java.util.Currency VARCHAR 定长字符
2、自定义映射类型
Hibernate提供了自定义映射类型接口,允许用户以编程的方式创建自定义的映射类型。用户自定义的映射类型需要实现net.sf.hibernate.UserType或net.sf.hibernate.CompositeUserType接口。具体的创建自定义映射类型的方法请参考hibernate官方文档或相关资料,这里不再详细介绍。
分享到:
相关推荐
Java JDBC(Java Database Connectivity)是Java编程语言中用于与各种数据库进行交互的一组接口和类。它提供了一种标准化的方法,让程序员可以使用SQL语句访问数据库,而无需关心具体的数据库实现细节。在Java应用...
Java JDBC学生数据管理系统是一个利用Java编程语言和JDBC(Java Database Connectivity)技术设计的应用,用于高效管理和操作学生数据。这个系统提供了用户友好的界面,使得用户可以方便地执行SQL(Structured Query...
Java JDBC(Java Database Connectivity)是Java编程语言中用于与各种关系数据库进行交互的一组接口和类。它作为标准API,允许开发人员通过编写Java代码来访问和操作数据库,无需了解数据库特定的SQL语法或者驱动...
Java JDBC(Java Database Connectivity)是Java编程语言中用于与各种关系数据库进行交互的一组标准API。JDBC使得Java开发者能够编写可移植的数据库应用程序,无需针对不同数据库系统编写不同的代码。JDBC的核心是一...
Java JDBC(Java Database Connectivity)是Java语言中用于与数据库交互的一种技术,它为开发者提供了一种标准的方法来访问各种类型的数据库。在Java中连接SQL Server数据库时,你需要一个特定的驱动程序,通常是一...
### Java JDBC规范详解 #### 一、概述与背景 JDBC,即Java Database Connectivity,是Java平台中一种标准的数据访问技术,它允许Java程序通过一套统一的API接口访问各种关系型数据库。JDBC的出现解决了Java应用与...
Java JDBC(Java Database Connectivity)是Java编程语言中用于与各种数据库进行交互的一组接口和类。它是Java标准版(Java SE)的一部分,允许Java开发者执行SQL语句并处理结果。在深入探讨Java JDBC之前,先要理解...
Java JDBC 连接池是Java开发中非常关键的一部分,它能有效地管理数据库连接,提高应用程序的性能和效率。本实例提供了完美的Java JDBC连接池配置,适用于Oracle、MySQL和SQL Server等主流数据库,允许开发者轻松地在...
**JAVA JDBC教程** Java JDBC(Java Database Connectivity)是Java平台中的一个标准API,它允许Java应用程序连接到各种类型的数据库,实现数据的存取和处理。JDBC为开发者提供了一种统一的方式来访问不同的数据库...
javaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.pptjavaJDBC编程.ppt
java jdbc odbc 桥连接包 如何实现JDBC-ODBC桥连接到Access
最全的javaJDBC技术的BaseDao,相当于框架封装了,引用之后直接调用其中的方法传递参数以及sql语句就可以使用了。
本项目"javajdbc宠物商店-Mysql数据库"是基于Java JDBC实现的一个宠物商店管理系统的数据库部分,它提供了与MySQL数据库交互的能力。在这个项目中,我们将深入探讨以下几个核心知识点: 1. **JDBC API**: JDBC API...
在Java编程语言中,JDBC(Java Database Connectivity)是一个用于与各种数据库进行交互的标准接口。JDBC提供了一套规范,使得Java程序员可以使用统一的方法来访问数据库,包括Oracle数据库。Oracle是世界上最流行的...
Java JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,它提供了标准的API,使得Java程序员能够使用SQL语句来访问数据库。本篇将通过一个小型示例,详细介绍如何...
Java JDBC(Java Database Connectivity)是Java编程语言中用于与各种数据库进行交互的一组接口和类。它是Java平台标准的一部分,允许开发人员编写数据库独立的代码,使得Java应用程序能够连接到不同类型的数据库,...
全面的 Java JDBC 编程学习知识总结 一张图搞定! 结构性强,便于记忆! 资源博客:https://blog.csdn.net/CodeYearn/article/details/89196038
Java JDBC(Java Database Connectivity)驱动则是Java程序与各种数据库进行交互的标准接口,使得Java开发者能够方便地访问和操作数据库。在本压缩包中,我们可能找到了用于连接MySQL 8.0的Java JDBC驱动,这将帮助...
SQLite JDBC 是一个开源的 Java 驱动程序,允许 Java 应用程序通过 JDBC API 连接到 SQLite 数据库。SQLite 是一个轻量级、自包含的数据库引擎,无需单独的服务器进程,非常适合嵌入式应用或者对小型项目的数据存储...
Java JDBC(Java Database Connectivity)是Java平台中用于与数据库交互的一组接口和类,它使得开发者可以使用标准的Java API来访问各种类型的数据库系统。在Java应用中,JDBC驱动扮演着桥梁的角色,将Java程序与...