(1)name:属性名。
(2)column(可选):外键字段的名称。也可以通过嵌套的 <column> 指定。
(3)class(可选 — 默认是通过反射得到的属性类型):被关联的类的名字。
(4)cascade(级联)(可选)表明操作是否从父对象级联到被关联的对象。
(5)fetch(可选 — 默认为 select):在外连接抓取和序列选择抓取两者中选择其一。
(6)update, insert(可选 — 默认为 true)指定对应的字段是否包含在用于 UPDATE 和/或 INSERT的 SQL 语句中。如果二者都是false,则这是一个纯粹的 “外源性(derived)”关联,它的值是通过
映射到同一个(或多个)字段的某些其他属性得到 或者通过 trigger(触发器)、或其他程序生成。
(7)property-ref:(可选)被关联到此外键的类中的对应属性的名字。如果不指定,使用被关联类的主键
(8)access(可选 — 默认为 property):Hibernate 用来访问属性值的策略。
(9)unique(可选):使用 DDL 为外键字段生成一个唯一约束。此外, 这也可以用作 propertyref的目标属性。这使关联同时具有一对一的效果。
(10)not-null(可选):使用 DDL 为外键字段生成一个非空约束。
(11)optimistic-lock(可选 — 默认为 true):指定这个属性在做更新时是否需要获得乐观锁定。换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
(12)lazy(可选 — 默认为 proxy):默认情况下,单点关联是经过代理的。lazy="no-proxy" 指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。lazy="false" 指定此关联总是被预先抓取。
(13)not-found(可选 - 默认为exception):指定如何处理引用缺失行的外键:ignore 会把缺失的行作为一个空关联处理。
(14)entity-name(可选):被关联的类的实体名。
(15)formula(可选):SQL 表达式,用于定义 computed(计算出的)外键值。
one-to-many
通过 one-to-many 元素,可以定义一种常见的与另一个持久化类的一对多关联。
java代码: - <one-to-many
- class="ClassName"(1)
- not-found="ignore|exception"(2)
- entity-name="EntityName"(3)
- />
<one-to-many class="ClassName"(1) not-found="ignore|exception"(2) entity-name="EntityName"(3) />
(1)class(必需):被关联类的名称。
(2)not-found(可选 - 默认为exception):指明若缓存的标示值关联的行缺失,该如何处理:ignore 会把缺失的行作为一个空关联处理。
(3)entity-name(可选):被关联的类的实体名,作为 class 的替代。
注意:<one-to-many> 元素不需要定义任何字段。也不需要指定表名。
还是用示例来看,下面作一个双向一对多的关系示例:
1:新建一个Parent对象和Child对象,Parent对象里面有一个Child对象的集合,Child对象里面有一个对Parent对象的引用,如下:
java代码: - public class Parent{
- private String id;
- private String name;
- private Set children = new HashSet();
- ……
- }
- public class Child {
- private String uuid;
- private String address;
- private String postCode;
- private Parent parent;
- ……
- }
- Parent.hbm.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="cn.javass.h3.parentchild.Parent" table="tbl_parent" dynamic-update="true" dynamic-insert="true" lazy="true">
- <id name="id" column="uuid" type="java.lang.String" unsaved-value="any">
- <generator class="assigned"> </generator>
- </id>
- <property name="name" update="true" insert="true"/>
- <set name="children" inverse="true" cascade="all">
- <key column="tbl_parent_fk"/>
- <one-to-many class="cn.javass.h3.parentchild.Child"/>
- </set>
- </class>
- </hibernate-mapping>
-
- Child.hbm.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="cn.javass.h3.parentchild.Child" table="tbl_child" dynamic-update="true" dynamic-insert="true" lazy="true">
- <id name="uuid" column="uuid" type="java.lang.String" unsaved-value="any">
- <generator class="assigned"> </generator>
- </id>
- <property name="address" update="true" insert="true"/>
- <property name="postCode" update="true" insert="true"/>
- <many-to-one
- name="parent"
- column="tbl_Parent_fk"
- class="cn.javass.h3.parentchild.Parent"
- not-null="true"
- />
- </class>
- </hibernate-mapping>
public class Parent{ private String id; private String name; private Set children = new HashSet(); …… } public class Child { private String uuid; private String address; private String postCode; private Parent parent; …… } Parent.hbm.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.javass.h3.parentchild.Parent" table="tbl_parent" dynamic-update="true" dynamic-insert="true" lazy="true"> <id name="id" column="uuid" type="java.lang.String" unsaved-value="any"> <generator class="assigned"> </generator> </id> <property name="name" update="true" insert="true"/> <set name="children" inverse="true" cascade="all"> <key column="tbl_parent_fk"/> <one-to-many class="cn.javass.h3.parentchild.Child"/> </set> </class> </hibernate-mapping> Child.hbm.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.javass.h3.parentchild.Child" table="tbl_child" dynamic-update="true" dynamic-insert="true" lazy="true"> <id name="uuid" column="uuid" type="java.lang.String" unsaved-value="any"> <generator class="assigned"> </generator> </id> <property name="address" update="true" insert="true"/> <property name="postCode" update="true" insert="true"/> <many-to-one name="parent" column="tbl_Parent_fk" class="cn.javass.h3.parentchild.Parent" not-null="true" /> </class> </hibernate-mapping>
客户端测试TestMR.java文件太长,直接看演示好了。
在这个测试里面分别演示了单独的操作和级联的操作。
inverse:指定由哪一方来维护双方的关联关系,默认是false,也就是双方都维护,主要用在一对多 和 多对多中。
在一对多中使用inverse的时候,通常是在”一”这一端设置inverse=true,他的意思就是由多的那一端去维护关系,非反向端用于把内存中的表示保存到数据库中。如下:
Parent p = new Parent();
Child c = new Child();
c.setParent(p); //维护父子之间关系
p.getChildren().add(c);
ninverse还有一个重要特点就是会优化Sql
ncascade:定义对象的级联关系
all : 所有情况下均进行关联操作
none:所有情况下均不进行关联操作。这是默认值
save-update:在执行save/update/saveOrUpdate时进行关联操作
delete:在执行delete时进行关联操作
简单的示范一下双向的一对一
双向一对一的操作是类似于双向一对多的,只是配置上有一些不同:
1:Parent里面的配置,示例如下:
<one-to-one name= “cc” class= “cn.javass.h3.parentchild.Child” cascade= “all” property-ref= “parent“/>这里的property-ref参照的是Child对象里面的属性。
2:Child里面的配置,不是使用one-to-one,而是仍使用many-to-one,示例如下:
<many-to-one name=“parent” class=“cn.javass.h3.parentchild.Parent” column=“tbl_parent_fk”/>
3:测试程序里面,原来调用集合的地方,变成调用一个Child对象,其他就差不多了,可以测试看看。
Hibernate4的过滤器
Hibernate3 新增了对某个类或者集合使用预先定义的过滤器条件(filter criteria)的功能。过滤器条件相当于定义一个 非常类似于类和各种集合上的“where”属性的约束子句, 但是过滤器条件可以带参数,应用程序可以在运行时决 定是否启用给定的过滤器,以及使用什么样的参数值。过滤器的用法很像数据库视图,只不过是在应用程序中确定使用什么样的参数的。
定义过滤器
要使用过滤器,首先要在相应的映射节点中定义。而定义一个过滤器,要用到位于 <hibernatemapping/>节点之内的 <filter-def/> 节点:
示例如下:
java代码: - <filter-def name="myFilter">
- <filter-param name="myFilterParam" type="string"/>
- </filter-def>
<filter-def name="myFilter"> <filter-param name="myFilterParam" type="string"/> </filter-def>
使用过滤器之配置
定义好之后,就可以在某个类中使用这个过滤器:
java代码: - <class name="myClass" ...>
- ...
- <filter name="myFilter" condition=":myFilterParam=FILTERED_COLUMN"/>
- </class>
<class name="myClass" ...> ... <filter name="myFilter" condition=":myFilterParam=FILTERED_COLUMN"/> </class>
或者也可以在某个集合使用它:
java代码: - <set ...>
- <filter name="myFilter" condition=":myFilterParam=FILTERED_COLUMN"/>
- </set>
<set ...> <filter name="myFilter" condition=":myFilterParam=FILTERED_COLUMN"/> </set>
在同时可以使用多个过滤器。
使用过滤器之程序
在程序中,需要使用session接口中的:enableFilter(String filterName),getEnabledFilter(String filterName),和 disableFilter(String filterName)方法。Session中默认不启用过滤器,必须通过enabledFilter() 方法显式的启用。
示例代码session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");
过滤器示例
在Parent.hbm.xml中定义有如下的过滤器:
java代码: - <filter-def name="myFilter">
- <filter-param name="myFilterParam" type="string"/>
- </filter-def>
- <filter-def name="myFilter2">
- <filter-param name="myFilterParam" type="int"/>
- <filter-param name="myFilterParam2" type="int"/>
- </filter-def>
<filter-def name="myFilter"> <filter-param name="myFilterParam" type="string"/> </filter-def> <filter-def name="myFilter2"> <filter-param name="myFilterParam" type="int"/> <filter-param name="myFilterParam2" type="int"/> </filter-def>
在定义Child集合中使用
java代码: - <set name="children" inverse="true" cascade="all" fetch="select" lazy="false" batch-size="3">
- <key column="tbl_parent_fk"/>
- <one-to-many class="cn.javass.h3.parentchild.Child" />
- <filter name="myFilter"
- condition="address like :myFilterParam"></filter>
- <filter name="myFilter2" condition="uuid >= :myFilterParam and uuid <= :myFilterParam2"></filter>
- </set>
<set name="children" inverse="true" cascade="all" fetch="select" lazy="false" batch-size="3"> <key column="tbl_parent_fk"/> <one-to-many class="cn.javass.h3.parentchild.Child" /> <filter name="myFilter" condition="address like :myFilterParam"></filter> <filter name="myFilter2" condition="uuid >= :myFilterParam and uuid <= :myFilterParam2"></filter> </set>
程序中使用示例
java代码: - s.enableFilter("myFilter").setParameter("myFilterParam", "%1%");
- s.enableFilter("myFilter2").setParameter("myFilterParam", 1)
- .setParameter("myFilterParam2", 3);
- Query q = s.createQuery("select p from Parent as p ");
- System.out.println("p==="+p.getChildren());
-
s.enableFilter("myFilter").setParameter("myFilterParam", "%1%"); s.enableFilter("myFilter2").setParameter("myFilterParam", 1) .setParameter("myFilterParam2", 3); Query q = s.createQuery("select p from Parent as p "); System.out.println("p==="+p.getChildren());