打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
精通Hibernate

1.1 应用程序的分层体系结构

应用程序的三层结构:

表述层:提供与用户交互的界面。包括GUI界面(图形用户界面)和WEB页面。

业务逻辑层:实现各种业务逻辑。包括Java应用的持久化层,负责数据访问。

数据库层:负责存放和管理应用的持久性业务数据。

层与层之间存在自上而下的依赖关系。每个层都向上公开接口,封装实现细节。

Hibernate中间件,可以为任何一个需要访问关系数据库的Java应用服务

1.2 软件的模型

概念模型,处于软件分析阶段。概念模型显示了问题域中的实体(定义了实体的属性和实体的关系)

关系数据模型,处于数据库设计阶段,面向关系。关系数据模型是从概念模型基础上建立起来的。一个实体对应一个表,表通过主键来保证每条记录的唯一性,根据关系数据库学,表的主键应当不具有任何业务含义。

域模型,处于软件设计阶段,面向对象。域模型是从概念模型基础上建立起来的。包括域对象和域对象之间的关系。

域对象(Domain Object)即业务对象(Business Object, BO):

实体域对象,采用JavaBean形式的实体域对象即POJO(Plain Old Java Object)。如订单、商品等。

过程域对象,代表应用中的业务逻辑或流程。通常依赖于实体域对象。例如发出订单、登录应用等。

事件域对象,代表应用中的事件。通常由系统中的某种行为触发。例如异常、警告或超时等。

域对象都位于业务逻辑层,实体域对象是应用的业务数据在内存中的表现形式,过程域对象用于执行业务逻辑。

域对象之间的关系:

关联(Association)关系,关联指类之间的应用关系,分为一对一、一对多、多对多关联。如果类A与类B关联,那么被引用的类B被定义为类A的属性。

依赖(Dependency)关系,依赖指类之间的访问关系。如果类A访问类B的属性或方法,或者类A负责实例化类B,那么可以说类A依赖类B。

聚集(Aggregation)关系,聚集指整体与部分之间的关系。对于聚集关系,聚集类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期,当整体消失时,聚集部分就随之消失。例如人和手就是聚集关系。

一般化(Generalization)关系,一般化指类之间的继承关系。

1.3 直接通过JDBC API来持久化实体域对象

JDBC(Java Database Connectivity)API包括:

java.sql.DriverManager :驱动程序管理器,负责创建数据库链接

java.sql.Connection :负责数据库链接

java.sql.Statement :负责执行SQL语句

java.sql.PreparedStatement :负责执行预定义SQL语句

java.sql.ResultSet :负责SQL查询语句的查询结果集

程序中的业务逻辑和数据访问细节分离的模式:

业务逻辑和数据访问耦合、ORM模式、主动域对象模式、JDO模式、CMP模式

1.4 ORM模式简介

对象-关系映射(Object-Relation Mapping, ORM)模式指在单个组件中负责所有实体域对象的持久化,封装数据访问细节,采用对象-关系映射文件(.XML)映射元数据来描述对象-关系映射细节。

一个持久化类和一个表对应,类的每个实例对应表中的一条记录。

ORM模式执行SQL语句的步骤:

1、运用Java反射机制,获得customer对象的类型为Customer.class

2、参考对象-关系映射元数据,Customer类对应CUSTOMER表

3、根据映射信息,生成SQL语句

4、调用JDBC API,执行SQL语句

ORM中间件Hibernate,http://www.hibernate.org/

1.5 实体域对象的其他持久化模式

主动域对象模式

主动域(实体域)对象,在实现中封装了关系数据库模型和数据访问细节。在实体域对象中封装自身的数据访问细节,在过程域对象中完全负责业务逻辑。此时整个应用为三层应用结构:表述层、业务逻辑层、数据库层

JDO模式

(Java Data Objects, JDO)——SUN公司制定的描述对象持久化语义的标准API。此时整个应用为四层应用结构:表述层、业务逻辑层、持久化层(JDO API、JDO 实现、JDBC API)、数据库层

CMP模式

由EJB容器来管理实体EJB的持久化,EJB容器封装了对象-关系的映射和数据访问细节。

EJB组件分为会话EJB(实现业务逻辑)、实体EJB(代表业务实体)

      实体EJB分为基于BMP(Bean-managed Persistence)的实体EJB(由EJB实现本身的数据访问细节)、基于CMP(Container-managed Persistence)的实体EJB(由EJB容器实现数据访问细节)

1.6 Hibernate API 简介

提供访问数据库的操作的接口:Session接口、Transation接口、Query接口

用于配置Hibernate的接口:Configuration接口

Hibernate核心接口:

Configuration接口:配置Hibernate、根启动Hibernate。Hibernate应用通过Configuration实例来指定对象-关系映射文件的位置或动态配置Hibernate的属性,然后创建SessionFactory对象实例。

SessionFactory接口:初始化Hibernate、充当数据存储源的代理、创建Session对象。

一个SessionFactory实例对应一个数据存储源,Hibernate应用从SessionFactory中获得Session对象实例。

特性:它是线程安全的,意味着同一个实例可以被应用的多个线程共享;它是重量级的,意味着不能随意创建或销毁实例,一个数据库访问只需创建一个实例。

Session接口:负责保存、更新、删除、加载、查询对象

Session接口被称为持久化管理器,每个Session实例都有自己的缓存,用来存放被当前工作单元加载的对象且只能被当前工作单元访问。

特性:它不是线程安全的,应该避免多个线程共享同一个Session实例;它是轻量级的,意味着创建或销毁实例不需要消耗太多的资源,可以为每个请求分配单独的Session实例,或者为每个工作单元分配单独的Session实例。

Transation接口:Hibernate的数据库事务接口,对底层的事务接口做了封装

封装的底层事务接口:

JDBC API、JTA(Java Transation)API、CORBA(Common Object Request Broker Architecture)API

通过一致的Transation接口来声明事务边界,有利于应用在不同环境或容器中移植。

Query接口和Criteria接口:执行数据库查询,控制执行查询的过程。

Query接口封装了一个面向对象的查询语句(Hibernate Query Language, HQL)

Criteria接口封装了基于字符串形式的查询语句,擅长于执行动态查询。

回调接口:Interceptor接口、Lifecycle接口、Validatable接口

当一个对象发生了特定的事件(如加载、保存、更新、删除),Hibernate应用可以通过回调来响应事件。

回调接口按实现方式可分为:

Lifecycle接口和Validatable接口:由持久化类来实现接口。

Lifecycle接口,使持久化类的实例能响应被加载、保存、删除的事件。

Validatable接口,使持久化类的实例在被保存前进行数据验证。

Interceptor接口:不必由持久化类来实现接口。Interceptor实现类负责响应持久化类的实例被加载、保存、更新、删除的事件。

映射类型接口:Type接口、UserType接口、CompositeUserType接口

Type接口,表示Hibernate映射类型,用于把域对象映射为数据库的关系数据。

Type接口的实现类:PrimitiveType类,映射Java基本类型。DateType类,映射Java日期类型。

扩展接口:

定制主键的生成策略:IndentifierGenerator接口

定制本地SQL方言:Dialect抽象类

定制缓存机制:Cache接口、CacheProvider接口

定制JDBC连接管理:ConnectionProvider接口

定制事务管理:TransationFactory接口、Transation接口、TransationManagerLookup接口

定制ORM策略:ClassPersister接口及其子接口

定制属性访问策略:PropertyAccesser接口

创建代理:ProxyFactory接口

定制客户化映射类型:UserType接口、CompositeUserType接口。

te内部封装了通过JDBC访问数据库的操作,向上层应用提供了面向对象的数据访问API。

Java应用中使用Hibernate的步骤:

1、创建Hibernate配置文件

2、创建持久化类

3、创建对象-关系映射文件

4、通过Hibernate API编写访问数据库的代码

2.1 创建Hibernate的配置文件

Hibernate配置文件有两种形式:

一、XML格式文件(配置文件形式)

例:默认为 hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<hibernate-configuration>
<session-factory>
    <property name="connection.driver_class"><!--指定连接数据库用的驱动-->
      com.microsoft.jdbc.sqlserver.SQLServerDriver
    </property>
    <property name="connection.url"><!--指定连接数据库的路径-->
      jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=db_Material
    </property>
    <property name="connection.username">sa</property><!--指定连接数据库的用户名-->
    <property name="connection.password"></property><!--指定连接数据库的密码-->
    <property name="show_sql">true</property><!--当show_sql属性为true时表示在程序运行时在控制台输出SQL语句,默认为false,建议在调试程序时设为true,发布程序之前再改为false,因为输出SQL语句会影响程序的运行速度-->
    <mapping resource="com/actionForm/GoodsForm.hbm.xml"/><!--指定持久化类映射文件-->
    ……     <!--此处省略了指定其他持久化类映射文件的代码-->
</session-factory>
</hibernate-configuration>

二、Java属性文件(采用“键=值”形式)

例:默认为 hibernate.properties

数据库基本配置代码
   1. hibernate.query.substitutions = true 1, false 0, yes 'Y', no 'N' 
这个配置意思是当你在Hibernate里面输入true的时候,Hibernate会转化为0插入数据库,当你在Hibernate里面输入 false的时候,Hibernate会转化为1插入数据库,后面的Y,N同理。对于某些数据库,例如Oracle来说,没有boolean数据类型,就是采用1代表true,0代表false,因此使用这个配置在Hibernate里面直接用true/false会非常直观。

   1. hibernate.dialect = net.sf.hibernate.dialect.MySQLDialect //指定数据库使用的SQL方言
   2. hibernate.connection.driver_class = com.mysql.jdbc.Driver //指定数据库的驱动程序
   3. hibernate.connection.url = jdbc:mysql:///test //指定连接数据库的URL
   4. hibernate.connection.username = root   //指定连接数据库的用户名
   5. hibernate.connection.password =123   //指定连接数据库的口令
   6. hibernate.connection.password =123 
数据库的连接参数代码
   1. hibernate.connection.pool_size = 1 
   2. hibernate.statement_cache.size = 25 
这是Hibernate自带的连接池的配置参数,在默认情况下将采用。提醒一点,Hibernate这个连接池是非常原始非常简单的连接池,如果你在项目中用Hibernate的话,建议你首选App Server的连接池,次选Hibernate带的DBCP连接池。自带的连接池应该做为末选。
如果你采用DBCP连接池,除了要配置DBCP连接池以外,还需要下行的代码:
   1. hibernate.connection.provider_class = net.sf.hibernate.connection.DBCPConnectionProvider 
其它的连接池同理。
如果采用App Server的连接池,假设App Server连接池的DataSource的JNDI名称为"mypool"的话,配置应该如下:
   1. hibernate.dialect = net.sf.hibernate.dialect.MySQLDialect 
   2. hibernate.connection.datasource = mypool 
   3. hibernate.connection.provider_class = net.sf.hibernate.connection.DatasourceConnectionProvider 
其它参数就不必写了,因为已经在App Server配置连接池的时候指定好了。
如果你不是在App Server环境中使用Hibernate,例如远程客户端程序,但是你又想用App Server的数据库连接池,那么你还需要配置JNDI的参数,例如Hibernate连接远程Weblogic上的数据库连接池:
   1. hibernate.dialect = net.sf.hibernate.dialect.MySQLDialect 
   2. hibernate.connection.datasource = mypool 
   3. hibernate.connection.provider_class = net.sf.hibernate.connection.DatasourceConnectionProvider 
   4. hibernate.jndi.class = weblogic.jndi.WLInitialContextFactory 
   5. hibernate.jndi.url = http://servername:7001/ 
最后,如果你需要在EJB或者JTA中使用Hibernate,需要下行的代码:
   1. hibernate.transaction.factory_class = net.sf.hibernate.transaction.JTATransactionFactory 
杂项配置:
   1. hibernate.show_sql = false 
是否将Hibernate发送给数据库的sql显示出来,这是一个非常非常有用处的功能。当你在调试Hibernate的时候,让Hibernate打印sql语句,可以帮助你迅速解决问题。
其他代码
   1. #hibernate.connection.isolation = 4 
指定数据库的隔离级别,往往不同的数据库有自己定义的隔离级别,未必是Hibernate的设置所能更改的,所以也不必去管它了。
性能配置代码
   1. hibernate.jdbc.fetch_size = 50 
   2. hibernate.jdbc.batch_size = 25 
这两个选项非常非常非常重要!!!将严重影响Hibernate的CRUD性能!
代码注释:
   1. C = create, R = read, U = update, D = delete 
Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数。例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会 1次性把1万条取出来的,而只会取出Fetch Size条数,当纪录集遍历完了这些记录以后,再去数据库取Fetch Size条数据。因此大大节省了无谓的内存消耗。当然Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。这有点像平时我们写程序写硬盘文件一样,设立一个Buffer,每次写入Buffer,等Buffer满了以后,一次写入硬盘,道理相同。
Oracle数据库的JDBC驱动默认的Fetch Size=10,是一个非常保守的设定,根据我的测试,当Fetch Size=50的时候,性能会提升1倍之多,当Fetch Size=100,性能还能继续提升20%,Fetch Size继续增大,性能提升的就不显著了。因此我建议使用Oracle的一定要将Fetch Size设到50。
不过并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支持。MySQL就像我上面说的那种最坏的情况,他总是一下就把1万条记录完全取出来,内存消耗会非常非常惊人!这个情况就没有什么好办法了
Batch Size是设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,有点相当于设置Buffer缓冲区大小的意思。Batch Size越大,批量操作的向数据库发送sql的次数越少,速度就越快。我做的一个测试结果是当Batch Size=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,Batch Size = 50的时候,删除仅仅需要5秒!!!可见有多么大的性能提升!很多人做Hibernate和JDBC的插入性能测试会奇怪的发现Hibernate速度至少是JDBC的两倍,就是因为 Hibernate使用了Batch Insert,而他们写的JDBC没有使用Batch的缘故。以我的经验来看,Oracle数据库 Batch Size = 30 的时候比较合适,50也不错,性能会继续提升,50以上,性能提升的非常微弱,反而消耗内存更加多,就没有必要了。
代码
   1. #hibernate.jdbc.use_scrollable_resultset = true 
设定是否可以使用JDBC2.0规范的可滚动结果集,这对Hibernate的分页显示有一定的作用,默认就好了。
代码
   1. #hibernate.cglib.use_reflection_optimizer = false 
默认打开,启用cglib反射优化。cglib是用来在Hibernate中动态生成PO字节码的,打开优化可以加快字节码构造的速度。
不过,当你在调试程序过程中,特别是和proxy,lazy loading相关的应用中,代码出错,但是出错提示信息有语焉不详,那么你可以把cglib优化关掉,这样Hibernate会输出比较详细的调试信息,帮助你debug。

2.2 创建持久化类

持久化类是值其实例需要被Hibernate持久化到数据库中的类。持久化类通常是域模型中的实体类。持久化类符合JavaBean规范。get/set方法

Hibernate要求持久化类必须提供一个不带参数的默认构造方法(访问级别是public或protected)。在程序运行时,Hibernate运用Java反射机制,调用java.lang.reflect.Constructor.newInstance()方法来构造持久化类实例。

2.3 创建数据库 Schema

主键Id对应

2.4 创建对象-关系映射文件

Hibernate采用XML格式的文件来指定对象和关系数据之间的映射。在运行时,Hibernate将根据这个映射文件来生成各种SQL语句。创建一个名为Customer.hbm.xml的文件,它用于把持久化类Customer类映射到数据库CUSTOMERS表,这个文件应该和Customer.class文件存放在同一个目录下。

Customer.hbm.xml文件的代码:
<?xml version="1.0"?>
  <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  <hibernate-mapping>
  <class name="mypack.Customer" table="CUSTOMERS">
  <id name="id" column="ID" type="long">
   <generator class="increment"/>
  </id>
  <property name="name" column="NAME" type="string" not-null="true" />
  <property name="email" column="EMAIL" type="string" not-null="true" />
  <property name="phone" column="PHONE" type="int" />
  <property name="address" column="ADDRESS" type="string" />
  <property name="sex" column="SEX" type="character"/>
  <property name="married" column="IS_MARRIED" type="boolean"/>
  <property name="description" column="DESCRIPTION" type="text"/>
  <property name="image" column="IMAGE" type="binary"/>
  <property name="birthday" column="BIRTHDAY" type="date"/>
  <property name="registeredTime" column="REGISTERED_TIME" type="timestamp"/>
  </class>
  </hibernate-mapping>

映射文件的文档类型定义DTD(Document Type Definition,文档类型定义),它对XML文件的语法和格式做了定义。Hibernate的XML解析器将根据DTD来核对XML文件的语法。
每一种XML文件都有独自的DTD文件。Hibernate的对象-关系映射文件使用的DTD文件在Hibernate软件包的src/hibernate目录下也提供了hibernate-mapping-3.0.dtd文件。<hibernate-mapping>元素是对象-关系映射文件的根元素,其他元素(即DTD代码中括号以内的元素,如<class>子元素)必须嵌入在<hibernate-mapping>元素以内。在<class>元素中又嵌套了好多子元素,在<class>元素中,<id>子元素必须存在且只能存在一次。此外,在映射文件中,父元素中的各种子元素的定义必须符合特定的顺序。例如,根据<class>元素的DTD可以看出,必须先定义<id>子元素,再定义<property>子元素。

把Customer持久化类映射到CUSTOMERS表

Customer.hbm.xml文件用于映射Customer类。如果需要映射多个持久化类,那么既可以在同一个映射文件中映射所有类,也可以为每个类创建单独的映射文件,映射文件和类同名,扩展名为"hbm.xml"。后一种做法更值得推荐,因为在团队开发中,这有利于管理和维护映射文件。

<class>元素指定类和表的映射,它的name属性设定类名,table属性设定表名。以下代码表明和Customer类对应的表为CUSTOMERS表:<class name="mypack.Customer" table="CUSTOMERS">,如果没有设置<class>元素的table属性,Hibernate将直接以类名作为表名,也就是说,在默认情况下,与mypack.Customer类对应的表为Customer表。

<class>元素包含一个<id>子元素及多个<property>子元素。<id>子元素设定持久化类的OID和表的主键的映射。以下代码表明Customer类的id属性和CUSTOMERS表中的ID字段对应。
<id name="id" column="ID" type="long">
    <generator class="increment"/>
</id>

 

<id>元素的<generator>子元素指定对象标识符生成器,它负责为OID生成惟一标识符。

<property>子元素设定类的属性和表的字段的映射。<property>子元素主要包括name、type、column和not-null属性。

1.<property>元素的name属性

<property>元素的name属性指定持久化类的属性的名字。

2.<property>元素的type属性

<property>元素的type属性指定Hibernate映射类型。Hibernate映射类型是Java类型与SQL类型的桥梁。Customer类的属性的Java类型、Hibernate映射类型,以及CUSTOMERS表的字段的SQL类型的对应关系:

Customer类的属性 Java类型             Hibernate映射类型 CUSTOMERS表的字段 SQL类型 
name                       java.lang.String   string                       NAME                            VARCHAR(15)

如果Customer类的属性为java.lang.String类型,并且与此对应的CUSTOMERS表的字段为VARCHAR类型,那么应该把Hibernate映射类型设为string,例如:
<property name="name" column="NAME" type="string" not-null="true" />

如果Customer类的属性为java.lang.String类型,并且与此对应的CUSTOMERS表的字段为TEXT类型,那么应该把Hibernate映射类型设为text,例如:
<property name="description" column="DESCRIPTION" type="text"/>

如果Customer类的属性为byte[]类型,并且与此对应的CUSTOMERS表的字段为BLOB类型,那么应该把Hibernate映射类型设为binary,例如:
<property name="image" column="IMAGE" type="binary"/>

如果没有显式设定映射类型,Hibernate会运用Java反射机制先识别出持久化类的属性的Java类型,然后自动使用与之对应的默认的Hibernate映射类型。例如,Customer类的address属性为java.lang.String类型,与java.lang.String对应的默认的映射类型为string,因此以下两种设置方式是等价的:
<property name="address" column="ADDRESS"/>

或者:
<property name="address" type="string" />

对于Customer类的description属性,尽管它是java.lang.String类型,由于CUSTOMERS表的DESCRIPTION字段为text类型,因此必须显式地把映射类型设为text。

3.<property>元素的not-null属性

如果<property>元素的not-null属性为true,表明不允许为null,默认为false。例如以下代码表明不允许Customer类的name属性为null:
<property name="name" column="NAME" type="string" not-null="true" />

Hibernate在持久化一个Customer对象时,会先检查它的name属性是否为null,如果为null,就会抛出以下异常:
net.sf.hibernate.PropertyValueException: not-null property references 
a null or transient value:mypack.Customer.name

如果数据库中CUSTOMERS表的NAME字段不允许为null,但在映射文件中没有设置not-null属性:<property name="name" column="NAME" type="string" />

那么Hibernate在持久化一个Customer对象时,不会先检查它的name属性是否为null,而是直接通过JDBC API向CUSTOMERS表插入相应的数据,由于CUSTOMERS表的NAME字段设置了not null约束,因此数据库会抛出错误:708 ERROR JDBCExceptionReporter:58 - General error, message from server: 
"Column NAME cannot be null"

 

值得注意的是,对于实际Java应用,当持久化一个Java对象时,不应该依赖Hibernate或数据库来负责数据验证。在四层应用结构中,应该由表述层或者业务逻辑层负责数据验证。例如对于Customer对象的name属性,事实上在表述层就能检查name属性是否为null,假如表述层、业务逻辑层和Hibernate持久化层都没有检查name属性是否为null,那么数据库层会监测到NAME字段违反了数据完整性约束,从而抛出异常,包含非法数据的Customer对象从表述层依次传到数据库层,随后从数据库层抛出的错误信息又依次传到表述层,这种做法显然会降低数据验证的效率。

 

既然如此,把<property>元素的not-null属性设为true,有何意义呢?这主要是便于在软件开发和测试阶段能捕获表述层或者业务逻辑层应该处理而未处理的异常,提醒开发人员在表述层或者业务逻辑层中加入必要的数据验证逻辑。

4.<property>元素的column属性

<property>元素的column属性指定与类的属性映射的表的字段名。以下代码表明和address属性对应的字段为ADDRESS字段:
<property name="address" column= "ADDRESS" type="string"/>

 

如果没有设置< property >元素的column属性,Hibernate将直接以类的属性名作为字段名,也就是说,在默认情况下,与Customer类的address属性对应的字段为address字段。

<property>元素还可以包括<column>子元素,它和<property>元素的column属性一样,都可以设定与类的属性映射的表的字段名。以下两种设置方式是等价的:
<property name="address" column= "ADDRESS" type="string"/>

或者:
<property name="address" type="string">
    <column name="ADDRESS" />
</property>

 

<property>元素的<column>子元素比column属性提供更多的功能,它可以更加详细地描述表的字段。例如,以下<column>子元素指定CUSTOMERS表中的NAME字段的SQL类型为varchar(15),不允许为null,并且为这个字段建立了索引:

 

<property name="name" type="string">
    <column name="NAME" sql-type="varchar(15)" not-null="true" index="idx_name" />
</property>

 

<column>子元素主要和hbm2ddl工具联合使用。当使用hbm2ddl工具来自动生成数据库Schema时,hbm2ddl工具将依据<column>子元素提供的信息来定义表的字段。如果数据库Schema是通过手工方式创建的,就不必通过<column>子元素设定字段的详细信息,通常只需设定它的name属性和not-null属性就可以了,例如:

<property name="name" type="string">
    <column name="NAME" not-null="true" />
</property>

 

或者:

<property name="name" column="NAME" type="string" not-null="true" />

 

除了not-null属性以外,<column>子元素的多数属性(如sql-type或index属性)都不会影响Hibernate的运行时行为。

 

Hibernate采用XML文件来配置对象-关系映射,有以下优点:
1、Hibernate既不会渗透到上层域模型中,也不会渗透到下层数据模型中。
2、软件开发人员可以独立设计域模型,不必强迫遵守任何规范。
3、数据库设计人员可以独立设计数据模型,不必强迫遵守任何规范。
4、对象-关系映射不依赖于任何程序代码,如果需要修改对象-关系映射,只需修改XML文件,不需要修改任何程序,提高了软件的灵活性,并且使维护更加方便

2.5 通过 Hibernate API 操纵数据库

1、根据默认位置的Hibernate配置文件的配置信息,创建一个Configuration实例

Configuration config = new Configuration();
config.addClass(Customer.class);

2、初始化Hibernate,创建SessionFactory实例

public static SessionFactory sessionFactory;
sessionFactory = config.buildSessionFactory();

3、将每一个Session实例和一个数据库事务绑定

Session session = sessionFactory.openSession();
Transaction tx;
    tx = session.beginTransaction(); //开始事务
    session.save(Customer); //执行事务(保存)
    session.delete("from Customer as c"); //执行事务(删除)
    tx.commit(); //提交事务
    tx.rollback(); //撤销事务
session.close(); //关闭Session

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Hibernate3.2 .1参考文档
Hibernate实体映射配置1(java@注解方式)
Hibernate框架(一)
Hibernate—第一季who are you
Hibernate的Property解析
Hibernate day01 day02 day03 day04
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服