`
weishuwei
  • 浏览: 326323 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

以前的hibernate笔记,贴上共享

阅读更多

1,一对一关系:
说明:Student和Certificate是一对一关系;
#1)基于主键的关联
Student.hbm.xml(主):
<one-to-one name="cer" class="Certificate" fetch="join" cascade="all"/>
Certificate.hbm.xml(从):
<class name="Certificate" table="Certificate">
<id name="id">
    <generator class="forgien">
    <parm name="property>stu</parm>
    </generator>
</id>
<one-to-one name="stu" class="Student" constrained="true"/>
</class>
constrained="true"表示以stu的主键作为外键;
#2)基于外键
Student.hbm.xml:
Student.hbm.xml同上面配置没什么区别;
Certificate.hbm.xml:
基于外键的跟语意不同了,这里不是用<one-to-one>表示,而是用<many-to-one>表示;
<many-to-one name="stu" class="Student" unique="true" column="stu_id"/>
注意:a),unique="true"表示该many-to-one其实表达的是一对一关系;


一般是基于外键的,那么在保存Certificate就要注意了;我是在Certificate中定义Student时,就初始化该对象了,Student stu=new Student();
然后创建Certificate时,cer.getStu().setId(stuId); serService.save(cer);

2,一对多关系:
#1)one-to-many
<bag name="replies" inverse="true" cascade="all-delete-orphan" lazy="true" order-by="createTime desc">
       <key column="topicId"></key>
       <one-to-many class="TopicReply"/>
</bag>
#2)many-to-one
<many-to-one name="user" class="UserMember" column="userId" unique="true">
</many-to-one>
#1)many-to-one默认就是延迟加载,所以在读取多的时候,是不会读取一方的;
#2)many-to-one是不能设置lazy="true"的;
#3)lazy属性:
lazy只能设置为false,proxy,no-proxy 3个值;默认为proxy;
lazy设为proxy,当child.getParent().getName()时,parent会被抓取;
若为no-proxy,调child.getParent().getName()时,parent是不会被抓取的,同时这种方式需要编译时字节码增强,否则和proxy没区别。
#4)fetch属性:
设置<many-to-one>的fetch="join",只对get()查询起作用,对list查询没起作用
在映射文档中定义的抓取策略将会对以下列表条目产生影响:
1,通过get()或load()方法取得数据。
2,只有在关联之间进行导航时,才会隐式的取得数据。
3,条件查询
4,使用了subselect抓取的HQL查询
不管你使用哪种抓取策略,定义为非延迟的类图会被保证一定装载入内存。注意这可能意味着在一条HQL查询后紧跟着一系列的查询。


3,多对多关系:
注意:多对多关系一般是双向的,大多情况下并不需要该关系,我们可以把它们转化为一对多关系;
Student.hbm.xml
<set name="courses" table="student_course" cascade="save-update">
     <key column="stu_id"/> <!-- 注意,这里的列名是该类对应的表的id
     <many-to-many class="Course" column="course_id"/>
</set>
这里注意2个列名不要写反了就是了;
******************************************************************
从hibernate3.0.5到hibernate3.2.5,中间已经经历了很多个版本。我一看到那无数的bug fix就胆颤心惊,毕竟用hibernate支撑的系统是比较重要的业务,我很怕hibernate低版本出问题,从私心来说也想升到新版本,所以我很想说服领导采用最新的hibernate3.2.5。

代价:
从hibernate3.0.5升级到hibernate3.2.5,会对旧系统有影响,不是仅仅更换一个hibernate.jar包就行了,至少有以下几点需修改:
1,Hibernate3.2.X的很多sql函数如count(), sum()的唯一返回值从Integer变为Long
2,Hibernate3.2.X要求ehcache版本为1.2以上.

好处:
hibernate3.2.x支持Annotation,这个对我们公司不具说服力,因为我们公司习惯了hbm,不可能换。
有些流行的开源软件也要求hibernate要3.2以上,这个有一定说服力.
那么与hibernate3.0.5相比,hibernate3.2.x还具备哪些比较有说服力的优点呢?
******************************************************************
可以用fetch来代替outer-join

Criteria.setFetchMode(java.lang.String, FetchMode), Serialized Form

FetchMode.DEFAULT
FetchMode.SELECT--Equivalent to outer-join="false".
FetchMode.JOIN--Equivalent to outer-join="true".
FetchMode.EAGER:Deprecated. use FetchMode.JOIN
FetchMode.LAZY: Deprecated. use FetchMode.SELECT

left join fetch和left join是不一样的,因为前者多了个fetch,它采用了迫切左外连接,而后者仅仅是左外连接,这样前者返回的就是一个对象,而后者返回的却是一个对象数组.
===================================================
命名查询(NamedQuery):
hibernateTemplate.findByNamedQuery("getTopic", userId);
注意:<query>和<sql-query>必须写在<class>的后面,不然dtd会报错误.
<query name="cascadeFile2">
<![CDATA[
   from AlbumFile f left outer join f.folder fd where f.folder.id=?
]]>
</query>


<sql-query name="qryStatic">
        <return alias="t" class="cn.ccb.hrdc.qry.pojo.bo.QueryStaticBO">
            <return-property name="staticId" column="static_id"/>
            <return-property name="group" column="query_group"/>
            <return-property name="name" column="static_name"/>
        </return>

        SELECT t.static_id ,
        t.query_group ,
        t.static_name
        FROM qry_static t
        WHERE t.qry_id = :qry_id order by t.static_id asc
</sql-query>

String sql = "select z.xlr as {zb.xlr} from dd_jzxml_zb z";
//String sql = "select {zb.*} from dd_jzxml_zb zb";

try {
/*初始化,设置session*/
this.setUp();

List list = session.createSQLQuery(sql,"zb",BaseDdjzxmlzbPO.class).list();
/*资源释放*/
this.tearDown();
}
执行的时候,报Caused by: java.sql.SQLException: 列名无效错误,
我把执行的sql打印了出来,是这样的:
select z.xlr as XLR0_ from dd_jzxml_zb z
把这条SQL放到数据库中是可以执行的,
将执行的SQL语句换为注释掉的那一个的话,可以正常执行的,不知道错在那里?

搞明白了,作为载体类zb,他必须在hibernate的映射文件中进行配置,并且在其进行别名转换时,必须把他所有配置过的属性都进行转换,
假如说zb这个类在映射时映射了xlr,mllx这两个字段,在进行别名转换时必须这么写
select z.xlr as {zb.xlr},z.mllx as {zb.mllx} from dd_jzxml_zb z
如果不写全就会报列名无效的错误
===================================================
How can I find the size of a collection without initializing it?
Integer size = (Integer) s.createFilter( collection, "select count(*)" ).uniqueResult();

你可以统计查询结果的数目而不必实际的返回他们:
( (Integer) session.iterate("select count(*) from ....").next() ).intValue();
===================================================
Hibernate的formula
<property name="currencyName" formula="(select cur.name from currency cur where cur.id= currencyID)"/>
currenyId是对象属性(这也是该sql中唯一和对象相关部分,注意formula指定的是sql,不是hql)
1,必须有别名
2,整个sql必须被括号包括
===================================================
from User u where u.name in (:usernameList)
在 Hibernate 中通过这样的方式将值注入到这个参数中:
List list=new ArrayList();
list.add(“jerry”);
list.add(“bluedavy”);
query.setParameterList(“usernameList”,list);
===================================================
每个持久化类都有一个标识属性(实际上,这个类只代表实体,而不是独立的值类型类,后者会被映射称为实体对象中的一个组件).这个属性用来区分持久化对象:如果CatA.getId().equals(CatB.getId())结果为true话,这两个Cat就是相同的.
===================================================
uuid生成器:测试时建议使用,如果使用数据库自动生成的数据类型的键值更好.
===================================================
每个session是一个独立的单元操作.
===================================================
持久化标识(相当于主键),对于托管状态的对象,Hibernate不保证任何持久化标识和java标识的关系.
===================================================
为什么po要继承序列化,应该是hibernate要为它们添加一些属性吧.
===================================================
hibernate实体类中属性不需要声明为public的,hibernate默认使用protected或private的get/set方法对,对属性进行持久化.
===================================================
<proerty update="true" insert="true" ../>update,insert默认为true;表示该属性是否映射数据库某个字段
若false,操作时对应的sql中没属性;
===================================================
cascade值:none,persist,merge,delete,save-udpate,replicate,lock,refresh,以及特别的值delete-orphan和all,并且可以用逗号来合并这些操作,比如cascade="persist,merge,evict"或cascade="all,delete-orphan"
===================================================
当持久化一个实例时,我们通过调用persist(),hibernate会自动把HashSet替换为hibernate自己的set实现,
Cat cat=new Cat();
Set kittens=new HashSet();
kittens.add(cat);
cat.setKittens(kittens);
session.persist(cat);
kittens=cat.getKittens();//这里OK,kittens collection is a Set
(HashSet)cat.getKittens();//Error!!
===================================================
session.save(cat);
session.flush();//force the sql insert
session.refresh(cat);//re-read the state (after the trigger executes);
任何时候都可以使用refresh()方法强制装载对象和它的集合,如果你使用数据库触发器功能来处理对象的某些属性,这个方法就很有用了.
===================================================
分页:
Query q=ses.createQuery("from cat c");
q.setFirstResult(20);
q.setMaxResult(10);
List cats=q.list();
===================================================
如果你确定当前的session没有包含与之具有相同持久性标识的持久实例,使用update().如果想随时合并你的改动而不考虑session的状态,使用merge().换句话说,在一个新的session中通常第一个调用的时update()方法,以便保证重新关联脱管(detached)对象的操作首先被执行.
希望相关联的脱管对象(通过引用'可到达'的脱管对象)的数据也要更新到数据库时(并且也仅仅在这种情况),应用程序需要对该相关联的脱管对象的单独调用update(),当然这些可以自动完成,即通过使用传播性持久化(transitive persistence);
===================================================
SaveOrUpdate()
Hibernate用户曾要求一个既可以自动分配新持久化标识(identifier)保存瞬时(transient)对象,又可更新/重新关联脱管(detached)实例的通用方法.saveOrUpdate()方法实现了这个功能.
以下场景会使用到update()或saveOrUpdate();
程序在第一个session中加载了对象,该对象传到表现层并发生了改动,然后我们调用第二个session的update()方法来持久这些改动;
===================================================
EAGAIN和EINVAL。前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。
===================================================
session clear 用于清空Session缓存,大量插入时可在插入中session.flush();session.clear(); 以免outofmemory

而evict用于清楚缓存中的某个对象session.evict(stu);SessionFactory.evict(Student.class,stu.getid())清除二级缓存
===================================================
组件(Component)映射:组件是把一张表拆成多个类
<class name="eg.Person" table="person">
    <id name="Key" column="pid" type="string">
        <generator class="uuid"/>
    </id>
    <property name="birthday" type="date"/>
    <component name="Name" class="eg.Name"> <!-- class attribute optional -->
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>
    </component>
</class>
人员(Person)表中将包括pid, birthday, initial, first和 last等字段。
===================================================
subClass是把一个类拆成多个表;
每个类分层结构一张表(Table per class hierarchy)
<class name="Payment" table="PAYMENT">
    <id name="id" type="long" column="PAYMENT_ID">
        <generator class="native"/>
    </id>
    <discriminator column="PAYMENT_TYPE" type="string"/>
    <property name="amount" column="AMOUNT"/>
    ...
    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
        <property name="creditCardType" column="CCTYPE"/>
        ...
    </subclass>
    <subclass name="CashPayment" discriminator-value="CASH">
        ...
    </subclass>
    <subclass name="ChequePayment" discriminator-value="CHEQUE">
        ...
    </subclass>
</class>
===================================================
10.4.1.3. 标量(Scalar)结果
查询可在select从句中指定类的属性,甚至可以调用SQL统计(aggregate)函数。 属性或统计结果被认定为"标量(Scalar)"的结果(而不是持久(persistent state)的实体)。

Iterator results = sess.createQuery(
        "select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
        "group by cat.color")
        .list()
        .iterator();
       
while ( results.hasNext() ) {
    Object[] row = (Object[]) results.next();
    Color type = (Color) row[0];
    Date oldest = (Date) row[1];
    Integer count = (Integer) row[2];
    .....
}

分享到:
评论

相关推荐

    韩顺平hibernate笔记

    【hibernate笔记】 在Java世界中,Hibernate是一款强大的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式处理数据。韩顺平老师的hibernate笔记,是针对他视频教程的配套学习资料,...

    hibernate笔记

    `create`表示每次启动时重建表结构,而`update`则是在已存在的表基础上更新。 4. **编写Bean/VO类及其映射文件**:定义实体类并创建对应的映射文件,如`User.hbm.xml`,用以描述实体类与数据库表之间的映射关系。 -...

    hibernate第一天笔记

    《Hibernate入门:第一天笔记详解》 Hibernate,作为Java领域中著名的ORM(Object-Relational Mapping)框架,极大地简化了数据库操作,让开发者可以更加专注于业务逻辑而不是底层的数据访问。本文将基于第一天学习...

    Hibernate全部笔记

    Hibernate 是一款开源的Java平台上的对象关系映射(ORM)框架,它极大地简化了数据库操作,使得开发人员可以使用面向对象的方式来处理数据库事务。本笔记将深入探讨Hibernate的核心概念、配置、实体管理以及高级特性...

    《深入浅出Hibernate》读书笔记

    总之,《深入浅出Hibernate》读书笔记涵盖了实体对象生命周期的转换、实体对象的识别机制以及Hibernate的多级缓存策略,这些都是理解并有效使用Hibernate的关键点。通过深入学习这些概念,开发者能够更好地掌握...

    hibernate API帮助文档 及hibernate学习笔记

    这篇文档和学习笔记将深入介绍Hibernate的核心概念、API用法以及最佳实践。 1. **Hibernate核心概念** - **对象关系映射(ORM)**: Hibernate是ORM的一种实现,它允许开发者使用面向对象的方式来操作数据库,而...

    hibernate课程笔记.doc

    在JDBC(Java Database Connectivity)的基础上,Hibernate 提供了面向对象的编程模型,减少了与数据库交互时的繁琐代码,提高了开发效率。以下是关于Hibernate的一些关键知识点: ### 1. JDBC 的优缺点 **JDBC的...

    Hibernate笔记

    **Hibernate笔记** Hibernate是一款强大的Java持久化框架,它简化了数据库与Java对象之间的交互,使得开发者无需关注底层的SQL语句,而是通过面向对象的方式来操作数据。本笔记将深入探讨Hibernate的核心概念、配置...

    Hibernate入门(上)笔记.pdf.zip

    【Hibernate入门(上)笔记.pdf】 这篇笔记主要涵盖了Hibernate框架的基础知识,它是Java开发中用于对象关系映射(ORM)的热门工具。Hibernate允许开发者用Java对象来操作数据库,消除了传统的JDBC代码,提高了开发...

    Hibernate培训笔记.

    【Hibernate培训笔记】 Hibernate是一个强大的Java对象关系映射(ORM)框架,它简化了数据库与Java应用程序之间的交互。本笔记将深入探讨Hibernate的核心概念、配置、实体管理、查询语言以及事务处理,帮助开发者更...

    Hibernate3.3_学习笔记.doc.zip

    《Hibernate3.3_学习笔记》是一份详细记录了Hibernate3.3版本特性和使用方法的文档,旨在帮助开发者深入理解和应用这一强大的对象关系映射(ORM)框架。Hibernate是Java开发中的一个明星库,它简化了数据库操作,...

    hibernate 学习笔记1

    ### 对象持久化与Hibernate学习笔记 #### 一、对象持久化的概念与重要性 - **定义**: 对象持久化是指将程序中的对象状态存储到持久化存储设备上的过程,以便在程序结束运行后仍然可以保留这些数据。 - **必要性**:...

    JDBC Hibernate学习笔记

    ### JDBC与Hibernate学习笔记 #### 一、JDBC概述 **1.1 ODBC与JDBC的区别** - **ODBC(Open Database Connectivity)**: 开放式数据库连接是一种开放标准的应用程序接口(API),用于实现数据库应用程序与不同...

    hibernate培训笔记.docx

    本篇笔记将深入探讨Hibernate的历史、标准、核心概念以及其在软件设计中的应用。 ### Hibernate简史 Hibernate始于2001年,由Gavin King创建,起初是一个小型的Java项目,旨在简化Java应用程序与数据库之间的交互...

Global site tag (gtag.js) - Google Analytics