初识Hibernate

Hibernate 是J2EE 持久层框架

何为框架?个人理解为底层技术不用程序员自己编写写代码实现,程序员只需要关注API的使用和配置文件的书写

HIbernate框架结构如下所示:



目前最新Hibernate版本4.3.5

Hibernate 的主要认识从API、映射文件、性能三方面


一、Hibernate的API

主要有:1、读取cfg配置文件   Configuration   主要通过configure读取总配置文件信息

2、得到SessionFatory对象      通过Configuration  对象的buildSessionFactory创建SessionFactory实例,4版本之前可以通过cfg.buildSessionFactory直接创建,但是4版本以后,需要创建ServiceRegistry 实例对象ServiceRegistry  sr=new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();,然后通过cfg.buildSessionFactory(sr)来得到SessionFatory实例。

3、获取Session 实例对象   Session  session=sf.openSession();

4、在操作session过程中如果有事物产生,通过session.beginTransaction()得到Transaction 得到实例对象,对增、删、改进行事物操作

5、在操作完所有事物后,需要对session进行关闭。

通过session进行增删查改操作

1、查询单个对象    session.get(XX.class,id);    session.load(XX.class,id) 懒加载

2、通过HQL 语句查询    ,主要涉及参数的传递

A、通过设置下标传递,如:“select from Order o  where o.name=?”       session.createQuery(hql).setParameter(0,name);

B、通过名称来传递,如:“select from Order o  where o.name=:name”       session.createQuery(hql).setParameter(“name”,name);

C、通过Map集合来传递多个参数

D、通过对象来传递多个参数

3、增加单个对象   session.save();

4、更新单个对象  session.update();

5、删除单个对象  session.delete();

二、Hibernate的映射文件

1、cfg配置文件

hinbernate.cfg.xml

标签主要涉及<session-factory> 及<property>

主要对property进行映射,主要设计内容为:

<property name="connection.driver_class">JDBC驱动</property>

<property name="connection.url">数据库连接的url</property>

<property name="connection.name">连接数据库的用户名</property>

<property name="connection.password">连接数据库的密码</property>

方言:即用的是什么数据库

<property name="dialect"></property>

其它参数配置,如是否显示sql语句 等等

<property name="show_sql">true</property>
<property name="format_sql">true</property>

导入映射文件

<mapping resource="要导入的映射文件"  />

2、hbm映射文件

hbm映射文件主要是实体bean对象和数据库中列名一一对应的配置文件

主要标签涉及<class > <id> <property> <one-to-one> <set> <many-to-one> <one-to-many> <many-to-many>

class标签,属性主要涉及: name :对应哪个实体对象类   , table :数据库中对应的表 ,  optimistic-lock  :乐观锁模式  ,值可以是dirty (脏数据)  ,version(版本机制)

id标签,主要涉及属性有 name:实体对象的标号属性(一般是id),column:对应数据库中的主键列  

generator标签,主要属性是class  ,class 取值可以为identity(主键自增长),increment(数据库中主键没有设置主键自增长,hibernate根据当前数据库中主键的值,自动给数据库主键增长值),uuid(随机分配不重复的字符串),assigend(程序员自己手动分配的值),sequence(序列,在ORACLE数据库中,程序员只需创建序列)

property标签,主要属性是name:对应实体对象的属性,column:对应数据库中表的列名 ,type :数据类型,unique:是否唯一。

在项目实际关系中,对象与对象往往会存在很多种复杂关系,主要是一一对应,一对多,多对一,多对多关系,自关联关系,继承关系

一一对应关系(列如 丈夫与妻子):主键关联及唯一外键关联

  主键关联:在数据库中体现为从表的主键取决于主表的主键,在实体对象中是(我有一个唯一的你,你有一个唯一的我)

在映射文件中体现:<one-to-one  name="丈夫实体对象属性" class="妻子的类名" cascade=""></one-to-one>

在从表的映射文件中<generator>标签class属性设置为foreign   <parm name="property">在妻子对象中对应的丈夫类属性名</parm>

cascade:级联关系:表示在对当前对象属性进行操作的时候,和该对象有关系的对象进行相关的级联操作。

  唯一外键关联:

主表对应实体对象映射文件:<many-to-one name="wife" class=""  column="fk_wife_id" cascade="all" unique="true"></many-to-one>

从表对应实体对象映射文件:<one-to-one name="husband" cascade="all" class="com.lovo.one2one.Husband" property-ref="wife"></one-to-one>

一对多对应关系(一个客户有多个订单)

客户类映射文件:

<set name="orders" table="t_order" cascade="all" inverse="true">
<key column="fk_custmoer_id"></key>
<one-to-many class="com.lovo.one2many.Order"/>
</set>

订单类映射文件:

<many-to-one name="custmoer" class="com.lovo.one2many.Customer" cascade="save-update" column="fk_custmoer_id" ></many-to-one>

多对多对应关系(玩家和武器),需要中间表进行关联

在映射文件中对应关系体现为

<set name="weapons" table="中间表名字" cascade="save-update" inverse="true">
<key column="fk_user_id"></key>
<many-to-many class="com.lovo.many2many.Weapon" column="fk_weapon_id"></many-to-many>
</set>

自关联关系(对象中的子对象也是该类的实体),在映射中体现为既有一对多关系也有多对一关系


三、性能操作

性能操作主要从延迟加载、缓存处理、事物锁来体现

延迟加载:用hibernate进行数据查询的时候,如果对象属性中有其他类的对象属性和集合的时候,不会直接查询出这个属性,而是当需要的时候,再去进行查询,以减少内存的开销。但是如果我们在关闭session以后,再想得到对象属性,将会报无法连接session异常。

改变延迟加载的方法有:

1、在映射文件中加上 Lazy 属性,Lazy="false"   ,但是这样会大量消耗内存

2、在映射文件中加上fetch 属性,fetch="join" 

3、通过Hibernate提供的Hibernate.initialize  方法进行主动加载

4、直接在HQL 文件中加上  left join fetch 语句进行查询。

个人习惯用第三种和第四中方法改变延迟加载。

缓存:缓存是介于内存和物理存储的介质。

Hibernate 主要分为一级缓存及二级缓存,一级缓存是基于Session,即一旦开启session,一级缓存默认开启。二级缓存是由SessionFactory实现,默认没有开启,需要导入其它组件。主要有Ehcached、OSCache、JBoss(服务器集群)、SwarmCache(服务器集群)

在应用二级缓存的时候,首先要在cfg.xml配置文件中开启二级缓存及配置二级缓存属性

<property name="hibernate.cache.EhCacheProvider" >true</property>
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
<property name="hibernate.cache.use_query_cache" >true</property>

然后需要配置缓存属性(单独的配置文件)

<ehcache>
  <diskStore path="d:/cache"/>      
  <defaultCache
  maxElementsInMemory="1000" 
  eternal="false" 
  overflowToDisk="true" 
  timeToIdleSeconds="300" 
  timeToLiveSeconds="100"
  diskPersistent="false"  
  diskExpiryThreadIntervalSeconds="120" />
</ehcache>

最后需要在映射文件中设置缓存策略(需要用到二级缓存的配置文件中)

<cache usage="read-write" />

read-only:只允许读,read-wite:读和写

或者在cfg.配置文件中指定,在最后写!

<class-cache usage="read-only" class=""/>

二级缓存适合长期保持一致的数据


事物锁机制:在进行事物操作的时候,不能对正在进行操作的数据进行事物操作

悲观锁:正在对表进行查询操作的时候,对数据进行锁住。

通过session.get(Order.class,1,LockOptions.UPGRADE)    单个查询进行上锁

通过  session.CreateQuery(hql).setLockOptions(LockOptions.UPGrADE).list() 对多个数据进行上锁

悲观锁在对数据进行查询的时候,就对数据进行上锁

乐观锁是在对数据进行事物操作的时候,才对数据惊喜上锁

乐观锁主要有三个方法进行实现:

A、乐观锁   version机制,在实体对象中增加version 属性,在表中增加f_version列

B、通过胀数据机制,在Mapping 映射中设置
optimistic-lock="dirty" dynamic-update="true"* 来设置锁机制

C、通过时间戳的机制,在实体对象中新增Timestamp(时间戳)属性,在表中增加t_ts列


总结:Hibernate虽然减轻了程序员的代码复杂性,而且计较智能。但是在性能操作方面,特别是大批量数据操作的时候,Hiberrnate并没有优势,需要重多方面去考虑Hibernate的性能,如果有大批量的数据操作,建议直接通过session.doWork()操作SQL 语句。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值