Hibenate学习笔记

来源:互联网 发布:自考和成考和网络教育 编辑:程序博客网 时间:2024/06/05 22:54
 1,Session 的几个主要方法:
   ①save,persist保存数据,persist在事务外不会产生insert语句。
   ②delete删除对象。
   ③updae更行对象,如果数据库中没有记录,会出异常。
   ④get根据ID查。会立刻访问数据库。
   ⑤load,根据ID查,(返回的是代理,不会立即访问数据库)。
   ⑥saveOrUpdate,merge(根据ID和version的值来确定是save或update),调用merge你的对象还是脱管。
   ⑦lock(把对象变成持久对象,但不会同步对象的状态)。
对象状态:
  ①瞬时状态(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new 出来且与session没 有关联的对象。
  ②持久状态(persistent):数据库中有数据与之对应,当前与session有关联,且相关联的session没有关闭,事务没有提交; 持久状态状态发生改变,在事务提交时会影响到数据库。(hibernate能检测到)。
  ③脱管状态(detached):数据库中有数据与之对应,但当前没有session与之关联;托管对象状态发生改变,hibernate不能检 测到。

2,HQL:
   ⑴from Object as object where object.name=?可以通过Query的setString(int i,String str)(i从0开始)方法来对问号 来填充;还有更好的方法:from Obejct as object where object.name=:username 
   可以通过Query的setString(String Str1,String str2)方法来处理,str1为冒号的变量。
   ⑵分页:通过Query的setFirstResult(int i)和setMaxResult(int i)来处理。
   ⑶通过Session的createQuery(String hql)创建查询。
   ⑷可通过Query的list方法来返回对象。当返回的结果为一条时,也可以通过uniqueResult方法返回对象。
   ⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇

3,Criteria:
   与HQL类似,但是HQL更加强大。


4,持久化类使用JavaBean的风格,为需要被访问的属性提供getter 和setter方法。那么为什么不把属性设置为public的呢?而你不 用提供setter和getter方法。这是因为定义一个public类型的 属性不能分别控制属性的访问级别以及修改访问级别权限。加 入有这样的业务系统不允许修改客户的名字,如果采用JavaBean可 以很容易做 到这一点,只需要把setter方法设置成private类型 getter方法设置为public。

5,值得注意的是,java应用程序不能访化类的private类型的getter方法和setter方法,而Hibernate没有这样的限制,它能 够访问各种级别的getter方法和setter。

6,Hibernate访问持久化类属性的策略:
在对象 - 关系映射文件中,<property>元素的access属性用于指定Hibernate访问持久化类的方式。它有一下2个值可选。
    ·property:这是,默认的值,表明Hibernate是通过相应的setter和getter方法来访问类的属性的,这是优先的推荐方式,为持久化类提供setter和getter方法可以更灵活的封装持久化类。
    ·field:表明Hibernate是通过java反射技术类访问持久化类的,例如,如果Customer类没有为name属性提供setter和getter方法,就可以把name属性设置为field,使Hiernate可以直接访问name属性。

7,Hibernate即支持包装类类型,也支持基本类型,推荐使用包装类型,Hibernate API对java包装类提供了友好的支持。

8,SQL引用标识符:
在SQL语法中,标识符是指用于为数据库表、视图、字段或索引等命名的字符串,常用标识符不包含空格、也不包含特殊字符,
如果数据库中表明名或字段中包含刻个或者特殊字符,那么可以使用引用标识符。对于不同的数据库系统,引用标识符都是不同的,在MS SQL Server中,引用标识符的形式为[uuu name];在mysql中引用标识符是`uuu name`。

9,为了保证持久化类对象的OID的唯一性和不可改变性,通常由Hibernate或底层数据库来给OID赋值,因此,可以把OID的setId方法设置为private,以禁止Java应用程序随意更高OID。而不把getId设置public。

10,Hibernate提供的内置标识生成器(8):
   ·increment:适用于代理主键。由Hibernate自动生成标识符,每次增长量为1。
   ·identity:适用代理主键。有底层数据库生成标识器前提条件是底层数据支持自动增长字段类型。
   ·sequence适用于代理主键。Hibernate根据底层数据库的序列来生成标识符。前提条件是底层数据库支持序列。
   ·hilo:适用于代理主键。Hibernate根据high/low算法来生成标识符。Hibernate把特定表的字段作为‘high’值。在默认的情况下选用hibernate_unique_key表的next_hi字段。
   ·native适用于代理主键。根据底层的数据库对自动标识符的支持能力。来支持identity,sequence,或hilo。
   ·uuid.hex使用于代理主键。hibernate采用128位的UUID算法来生成标识符。
   ·assigned:适用于自然主键。由Java应用程序负责生成标识符。为了能让Java应用程序设置OID,不能把setId方法声明为 private。应该尽量避免使用自然主键。

11,<many-to-one>属性值建立了custom属性和ORDERS表的外键CUSTOM_ID之间的映射。它包括以下属性:
   ·name:设定待映射持久化类的属性名,此处为,Order类属性的custom。
   ·colomn:设定持久化类的属性名,此处为ORDERS表外键CUSTOM_ID。
   ·class:设定持久化类的属性的类型,此处设定custom属性为Custom类型。
   ·not-null:略。

12,以上面的Custom和Order类为例,如果在没有session.save(custom)情况下,执行session.save(Order1)、session.save(Order2)会抛出异常。
custom对象是瞬时对象,Order1对象通过session.save(Order1),成了持久化对象,而Hibernate不会自动持久化Order1所关联的custom对象。所以在数据库中CUSTOM_ID为空。
如果希望持久化Order对象会自动持久化所关联的Custom对象,可以把<many-to-one>的cascade属性设置为‘save-update’,cascade默认属性为’none‘。当cascade属性设置为‘save-update’表明保存或更新当前对象时,会级联保存或更新它关联的对象。

13,当需要使用一对多映射时,可以用<set>属性,<set>包括以下属性:
   ·name:设定待映射的持久化的属性名,这里为Custom类的order属性。
   ·cascade:当前取值为‘save-update’,表示级联保存和更新。
<set>属性还包含2个子元素:
   <key>和<one-to-many>,<one-to-many>元素设定所关联的持久化类,此处为Order类。<key>元素设定与所关联的持久化类对应的表的外键,此处为ORDERS表的CUSTOM_ID字段。
   ·<set>元素表明Custom类的order属性为java.util.Set集合类型。
   ·<class>子元素表示order集合中存放一组Order对象。
   ·<key>子元素表示ORDERS表通过外键CUSTOM_ID参照CUSTOMS表。
   ·cascade属性:略。

13,当需要映射(这里指单向映射,双向同理)<many-to-many>时,需要一个中间表,
如:
   CATEGORIES表 CATEGORY_ITEM表 ITEMS表
 -------------- --------------------- ----------
   ID<PK>    CATEGORY_ID<<PK>><<FK>> ID<<PK>>
   NAME ITEM_ID<<PK>><<FK>> NAME
                            BASE_PRICE
在Category.hbm.xml文件中,映射Category类的item属性的代码如下:
   <set name="items" table="CATEGORY_ITEM" lazy="true" cascaed="save-update">
       <key colum="CATEGORY_ID"/> ---> //通过CATEGORY_ID在CATEGORY_ITEM表里找到对应的ITEM_ID。
       <many-to-many class="mypack.Item" colum="ITEM_ID"> ---> //通过ITEM_ID在ITEMS找到item详细信息。  
   </set>
解析:<set>元素的<key>子元素指定CATEGORY_ITEM表中参照CATEGORIES表的外键为CATEGORY_ID,<many-to-many>子元素的class属性指定items集合存放的是Item对象,column属性指定CATEGORY_ITEM表中参照ITEMS表的外键为ITEM_ID。

14,组件关联关系的映射:假如name属性不是一个的String类型,而是一个复杂类型。我们可以定义一个类Name,里面有 firstName和lastName两个属性,我们可以在User.hbm.xml中使用如下标签:
   <component name="name">
    <property name="firstName" colum="firstName"/>
    <property name="lastName" colum="lastName"/>
   <component/>
那么在user表中就有多了两个字段:firstName和lastName。

15, 使用一对多关联关系映射,效率是比较低的 ,因为要查两张表,如果另一张表数据很多的话,就会影响性能。
     使用多对多关联关系映射,效率是更低的,因为需要查三张表,所以尽量少使用。

16,学习Hibernate如何处理对象之间关联关系的底层细节时,可以从两方面去思考:
   ·如何将对象的关联关系保存到数据库中,
   ·如何检索出关联的对象。

17,cascaed用来说明当对主对象进行某种操作时是否及其关联的从对象也做类似的操作。
cascaed的取值有:none、all、save-update、lock、fresh、evict、replicate、persist、merge。delete-orphan(one-to-many)。
一般对many-to-many、many-to-one不设置级联,在one-to-one和one-to-many中设置级联。

18,inverse属性(只会在Set、List、Map、Array集合标签里出现,List集合是有序的集合,如果使用此属性那么List就不会记住序号,所以尽量不要使用),表示是否放弃关联关系,如果值为true表是放弃维护关系,false反之。比如说可以让学生记住老师的名字,而不要让老师去记住学生的名字,这样可以提高性能。
   例如我们可以在部门这一端放弃关联关系,

19,hibernate.jdbc.fetch_size 50
hibernate.jdbc.batch_size 25
这两个选项非常非常非常重要!将严重影响Hibernate的CRUD性能(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越小,读数据库的次数越多,速度越慢。
因此我建议使用Oracle的一定要将Fetch Size设到50。
不过并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支持。
·Batch Size是设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,有点相当于设置Buffer缓冲区大小的意思。Batch Size越大,批量操作的向数据库发送sql的次数越少,速度就越快。我做的一个测试结果是当Batch Size=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,Batch Size = 50的时候,删除仅仅需要5秒!!!

20,hibernate.max_fetch_depth设置外连接抓取树的最大深度 取值. 建议设置为0到3之间 
 就是每次你在查询时,会级联查询的深度,譬如你对关联vo设置了eager的话,如果fetch_depth值太小的话,会发多很多条sql
原创粉丝点击