??xml version="1.0" encoding="utf-8" standalone="yes"?>一本一道久久a久久精品蜜桃,国产精品视频男人的天堂,久久久久五月天http://www.aygfsteel.com/alinglau36/category/40192.htmlone platform thousands thinkingzh-cnFri, 10 Jul 2009 10:14:08 GMTFri, 10 Jul 2009 10:14:08 GMT60unsaved-valuehttp://www.aygfsteel.com/alinglau36/archive/2009/07/10/286297.htmllaulauFri, 10 Jul 2009 09:38:00 GMThttp://www.aygfsteel.com/alinglau36/archive/2009/07/10/286297.htmlhttp://www.aygfsteel.com/alinglau36/comments/286297.htmlhttp://www.aygfsteel.com/alinglau36/archive/2009/07/10/286297.html#Feedback0http://www.aygfsteel.com/alinglau36/comments/commentRss/286297.htmlhttp://www.aygfsteel.com/alinglau36/services/trackbacks/286297.htmlunsaved-value的。某些情况下(父子表关联保?Q当你在E序中ƈ没有昑ּ的用save或者update一个持久对象,那么Hibernate需要判断被操作的对象究竟是一个已l持久化q的持久对象Q是一个尚未被持久化过的内存(f)时对象。例如:(x)

Java代码
  1. Session session = ...;  
  2. Transaction tx = ...;  
  3.   
  4. Parent parent = (Parent); session.load(Parent.class, id);;  
  5.   
  6. Child child = new Child();;  
  7. child.setParent(parent);;  
  8. child.setName("sun");;  
  9.   
  10. parent.addChild(child);;  
  11. s.update(parent);;  
  12.   
  13. s.flush();;  
  14. tx.commit();;  
  15. s.close();;  


在上例中Q程序ƈ没有昑ּ的session.save(child); 那么Hibernate需要知道childI竟是一个(f)时对象,q是已经在数据库中有的持久对象。如果child是一个新创徏的(f)时对?本例中就是这U? 情况)Q那么Hibernate应该自动产生session.save(child)q样的操作,如果child是已l在数据库中有的持久对象Q那? Hibernate应该自动产生session.update(child)q样的操作?

因此我们需要暗CZ下HibernateQ究竟child对象应该对它自动saveq是update。在上例中,昄我们应该暗示 Hibernate对child自动saveQ而不是自动update。那么Hibernate如何判断I竟对child是saveq是update呢? 它会(x)取一下child的主键属?child.getId() Q这里假设id? java.lang.Integercd的。如果取到的Id值和hbm映射文g中指定的unsave-value相等Q那么Hibernate认ؓ(f) child是新的内存(f)时对象,发送saveQ如果不相等Q那么Hibernate认ؓ(f)child是已l持久过的对象,发送update?

unsaved-value="null" (默认情况Q适用于大多数对象cd主键 Integer/Long/String/...)

当Hibernate取一下child的IdQ取出来的是null(在上例中肯定取出来的是null)Q和unsaved-value讑֮值相{,发送save(child)

当Hibernate取一下child的idQ取出来的不是nullQ那么和unsaved-value讑֮g相等Q发送update(child)

例如下面的情况:(x)

Java代码
  1. Session session = ...;  
  2. Transaction tx = ...;  
  3.   
  4. Parent parent = (Parent); session.load(Parent.class, id);;  
  5. Child child = (Child); session.load(Child.class, childId);;  
  6.   
  7. child.setParent(parent);;  
  8. child.setName("sun");;  
  9.   
  10. parent.addChild(child);;  
  11. s.update(parent);;  
  12.   
  13. s.flush();;  
  14. tx.commit();;  
  15. s.close();;  


child已经在数据库中有了,是一个持久化的对象,不是新创建的Q因此我们希望Hibernate发送update(child)Q在该例 中,Hibernate取一下child.getId()Q和unsave-value指定的null比对一下,发现不相{,那么发? update(child)?

BTW: parent对象不需要操心,因ؓ(f)E序昑ּ的对parent有load操作和update的操作,不需要Hibernate自己来判断究竟是saveq是update了。我们要注意的只是child对象的操作。另?span class="hilite1">unsaved-value是定义在Childcȝ主键属性中的?

Java代码
  1. <class name="Child" table="child">  
  2. <id column="id" name="id" type="integer" unsaved-value="null">  
  3.   <generator class="identity"/>  
  4. </id>  
  5. ...  
  6. </class>  


如果主键属性不是对象型Q而是基本cdQ如int/long/double/...Q那么你需要指定一个数值型?span class="hilite1">unsaved-valueQ例如:(x)

Java代码
  1. unsaved-null="0"  


在此提醒大家Q很多h以ؓ(f)对主键属性定义ؓ(f)int/longQ比定义为Integer/Longq行效率来得高,认ؓ(f)基本cd不需要进行对象的? 装和解构操作Q因此喜Ƣ把主键定义为int/long的。但实际上,Hibernate内部L把主键{换ؓ(f)对象型进行操作的Q就你定义为int /long型的QHibernate内部也要q行一ơ对象构造操作,q回l你的时候,q要q行解构操作Q效率可能反而低也说不定。因此大家一定要扭{一? 观点Q在Hibernate中,主键属性定义ؓ(f)基本cdQƈ不能够比定义为对象型效率来的高,而且也多了很多麻烦,因此大家使用对象型的 Integer/Long定义主键?

unsaved-value="none"?
unsaved-value="any"

M要用在主键属性不是通过Hibernate生成Q而是E序自己setId()的时候?

在这里多说一句,强烈使用Hibernate的id generatorQ或者你可以自己扩展Hibernate的id generatorQ特别注意不要用有实际含义的字D当做主键来用!例如用户cUserQ很多h喜欢用用L(fng)陆名U做Z键,q是一个很不好的习(fn)惯,? 用户cd其他实体cL兌关系的时候,万一你需要修改用L(fng)陆名Uͼ一改就需要改好几张表中的数据。偶合性太高,而如果你使用无业务意义的id generatorQ那么修改用户名Uͼ只修改user表就行了?

p个问题引甛_来,如果你严格按照这个原则来设计数据库,那么你基本上是用不到手工来setId()的,你用Hibernate的id generatorO(jin)K了。因此你也不需要了解当

unsaved-value="none"?
unsaved-value="any"

I竟有什么含义了。如果你非要用assigned不可Q那么l解释一下:(x)

unsaved-value="none" 的时候,׃不论主键属性ؓ(f)M|都不可能为noneQ因此HibernateL对child对象发送update(child)

unsaved-value="any" 的时候,׃不论主键属性ؓ(f)M|都肯定ؓ(f)anyQ因此HibernateL对child对象发送save(child)

大多数情况下Q你可以避免使用assignedQ只有当你用复合主键的时候不得不手工setId()Q这时候需要你自己考虑I竟怎么讄unsaved-value了,Ҏ(gu)你自q需要来定?

BTW: Gavin King强烈不徏议用composite-idQ强烈徏议用UserType?

因此Q如果你在系l设计的时候,遵@如下原则Q?

1、用Hibernate的id generator来生成无业务意义的主键,不用有业务含义的字D做主键Q不使用assigned?

2、用对象类?String/Integer/Long/...)来做主键Q而不使用基础cd(int/long/...)做主?

3、不使用composite-id来处理复合主键的情况Q而用UserType来处理该U情c?/span>

那么你永q用的是unsaved-value="null" Q不可能用到any/none/..了?

lau 2009-07-10 17:38 发表评论
]]>
many-to-one/one-to-many/many-to-many关系映射http://www.aygfsteel.com/alinglau36/archive/2009/06/11/281493.htmllaulauThu, 11 Jun 2009 07:51:00 GMThttp://www.aygfsteel.com/alinglau36/archive/2009/06/11/281493.htmlhttp://www.aygfsteel.com/alinglau36/comments/281493.htmlhttp://www.aygfsteel.com/alinglau36/archive/2009/06/11/281493.html#Feedback0http://www.aygfsteel.com/alinglau36/comments/commentRss/281493.htmlhttp://www.aygfsteel.com/alinglau36/services/trackbacks/281493.html本文的内容:(x)
介绍NH如何处理对象间many-to-oneQone-to-many和many-to-many的双向映关p(本文主要介绍了映文Ӟ对于cȝ生成可以跟据前两描q的Ҏ(gu)生成Q;

l验教训Q?/strong>

相关cdQ?/strong>Q下面的cd包含一对一Q多对一Q一对多和多对多Q?img src="http://images.cnblogs.com/cnblogs_com/jailu/img3.JPG" border="0" alt="" />
many-to-oneQ?/strong>? q多对一的一U数据模型,它指定many一Ҏ(gu)不能独立存在的,我个为many-to-one是NHB中保证数据有效性的最有用的一U映,通过使用 many-to-one能有效的防治孤儿记录被写入到数据表中。在本文描述的例子中QStudentcdClassescM间是多对一关系Q?br />
通过many-to-one元素,可以定义一U常见的与另一个持久化cȝ兌。这U关pL型是多对一兌。(实际上是一个对象引用。)在映文件中用many-to-one标签描述此种关系Q?
<many-to-one
        
name="propertyName"(1)
        column
="column_name"(2)
        class
="ClassName"(3)
        cascade
="all|none|save-update|delete"(4)
        outer-join
="true|false|auto"(5)
        update
="true|false"(6)
        insert
="true|false"(7)
        property-ref
="propertyNameFromAssociatedClass" (8)
        access
="field|property|ClassName"(9)
        unique
="true|false" (10)
/>

Q.nameQ属性名。指出many一方的cȝ哪个属性和one一方的cd联.
Q.columnQ字D名Q可选)Q指出many一方的cd应的数据表用哪个列和one一方的cd应的数据表关联(两表之间存在外键兌Q;
Q.classQ关联的cȝ名字Q可?- 默认是通过反射得到属性类型)Q?br /> Q.cascadeQ指明哪些操作会(x)从父对象U联到关联的对象Q可选)Q?font face="Courier New">cascade属性允怸列|(x): all, save-update, delete, none. 讄除了none以外的其它g(x)传播特定的操作到兌的(子)对象中?br /> Q.outer-joinQ当讄hibernate.use_outer_join的时候,对这个关联允许外q接抓取Q可?- 默认?autoQ.outer-join参数允许下列三个不同|(x) autoQ用外q接抓取兌Q对象)Q如果被兌的对象没有代?proxy) Q,trueQ一直用外q接来抓取关联)QfalseQ永q不使用外连接来抓取兌Q;
Q.update,insertQ指定对应的字段是否在用?code>UPDATE ??INSERT的SQL语句中包含。如果二者都?code>false,则这是一个纯_的“外源性(derivedQ?#8221;兌Q它的值是通过映射到同一个(或多个)字段的某些其他属性得到的Q或者通过trigger(除法器)Q或者是其他E序Q可?- 默认?trueQ?br /> Q.property- refQ指定关联类的一个属性,q个属性将?x)和本外键相对应。如果没有指定,?x)用对方关联类的主键(可选)Qproperty-ref属性只应该用来? 付老旧的数据库pȝQ可能出现外键指向对方关联表的是个非主键字段Q但是应该是一个惟一关键字)的情c这是一U十分丑陋的关系模型。比如说Q假? ProductcL一个惟一的序列号Q它q不是主键;
Q.accessQNHibernate 用来讉K属性的{略Q可?- 默认?code>propertyQ?br /> Q.uniqueQ允生外键列唯一U束的数据库定义语言QDDLQ(可选)

那么关于Student的映可能是Q?/p>

<many-to-one name="Classes" column="cID" unique ="true"/>

只要在原Student.hbm.xml映射文g中添加many-to-one标签可以了Q?br />
对于Sturentcdd一个属性Classes:Classes

one-to-manyQ?/strong>一对多也是一U常见的数据模型Q在按范式设计的数据库中随处可见。在NHB中通过one-to-many可以非常方便的处理这U模型,同时NHBq提供了U联更新和删除的功能Q以保证数据完整性。在本文描述的例子中QClassescdStudentcL一对多的关p.

Classescȝ映射文gQClasses.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  
<class name="NHibernateTest.Classes,NHibernateTest" table="Classes">
    
<id name="ClassesID" column="ID" type="Int32" unsaved-value="0">
      
<generator class="identity"/>
    
</id>
    
<property name="ClassesName" column="ClassName" type="String" length="50"/>

    
<bag name="StudentList" cascade="all"  inverse="true">
      
<key column="ID" />
      
<one-to-many class="NHibernateTest.Student,NHibernateTest" />
    
</bag>
  
</class>
</hibernate-mapping>

  如映文件所C,one-to-many标签必须包含在标{bag中(个h理解Q多嘛,q一个包装v来~Q?br />         bag标签的name属性指出Address对象用哪个属性和Student对象兌Qinverse属性collection不更新连接(MQ这个属性提高了性能Q具体的情况请参考NHibernate的帮助文档)Q?br /> key标签的column属性指ZAddress对象对应的数据表用哪个字D和Student对象对应的数据表兌
one-to-many标签的class属性指ZAddress和哪个对象关联.

对于Classescd创徏一个StudentList : Student的属性,用来描述与Student对象的关p.

many-to-manyQ?/strong>多对多在数据库中也是常见的数据模型,像用户与l,用户与权限等。多对多关系需要通过一个中间表实现Qelement的就是读取这个中间表中某列的倹{在本文的例子中QStudentcdSubjectcL多对多的关系Q?br />
Student的映可能是Q?/p>

    <bag name="SubjectList" table="r_Student_Subject" inverse="true" cascade="save-update" lazy="false">
      
<key column="StudentID" />
      
<many-to-many class="NHibernateTest.Subject,NHibernateTest" column="ID" outer-join="auto" />
    
</bag>

  在bag标签中,加入了一个table属性,它指定一个实现多对多的中间表

完整的Student.hbm.xml源码如下Q?/p>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  
<class name="NHibernateTest.Student,NHibernateTest" table="Users">
    
<id name="UserID" column="ID" type="Int32" unsaved-value="0">
      
<generator class="identity"/>
    
</id>
    
<property name="UserName" column="UserName" type="String" length="20"/>
    
<property name="Password" column="Password" type="String" length="20"/>

    
<!--StudentcdNativePlacecL一对一的关p?/span>-->
    
<one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />

    
<!--StudentcdClassescL多对一的关p?/span>-->
    
<many-to-one name="Classes" column="cID" unique ="true"/>

    
<!--StudentcdAddresscL一对多的关p?/span>-->
    
<bag name="AddressList" cascade="all"  inverse="true">
      
<key column="ID" />
      
<one-to-many class="NHibernateTest.Address,NHibernateTest" />
    
</bag>

    
<!--StudentcdSubjectcL多对多的关系-->
    
<bag name="SubjectList" table="r_Student_Subject" inverse="true" cascade="save-update" lazy="false">
      
<key column="StudentID" />
      
<many-to-many class="NHibernateTest.Subject,NHibernateTest" column="ID" outer-join="auto" />
    
</bag>
  
</class>
</hibernate-mapping>
Studentcddcd为IList的属性SubjectList表示与类Subject的关p.

׃Student的映关pL较复杂,本文再熬述它的CRUD操作Q具体的操作Ҏ(gu)请参考本文附带的代码Q?

lau 2009-06-11 15:51 发表评论
]]>
վ֩ģ壺 Ƿ| ͨμ| ͬ| ̩| | ͺ| ն| û| °Ͷ| Ϫ| ʯʨ| Ȫ| | | ͭ| | ؼ| ÷| | ϲ| | | | | ij| ƽ| | | ˹| ƶ| | | | ڻ| ˹| Ϸ| ¡| | | ٰ| |