hibernate 关联

1.一对多相互映射

public class Coustomer
{
    private Long id;
    private String name;
    private Set<Order> orders;
}
public class Order
{
    private Long id;
    private String orderNumber;
    private Coustomer coustomer;
}
<hibernate-mapping >
        <class name="com.liule.hibernate.Coustomer" table="coustomers">
            <id name="id" column="id" type="long">
                <generator class="increment"></generator> <!--  主键生成方式 -->
            </id>
            <property name="name"  type="string">
                <column name="name" length="50"></column>
            </property>
            
            <set name="orders" cascade="save-update" inverse="true">
                <key column="coustomer_id"></key>
                <one-to-many class="com.liule.hibernate.Order"  />
                
            
            </set>
            
        </class>
</hibernate-mapping>

<set>元素的属性:

  • name:设定待映射的持久化类的属性名
  • cascade:当取值为“save-update”,表示级联保存和更新(表示随着改变,副关联的也跟着改变);“all”(保存、更新、删除)
  • inverse:“true”,表示双向关联,这一端为镜像
  • key:与所关联持久化类对应的表的外键
  • one-to-many:设定所关联的持久化类
<hibernate-mapping >
        <class name="com.liule.hibernate.Order" table="orders">
            <id name="id" column="id" type="long">
                <generator class="increment"></generator> <!--  主键生成方式 -->
            </id>
            
            <property name="orderNumber"  type="string">
                <column name="order_Number" length="15"></column>
            </property>
            
            <many-to-one name="coustomer" class="com.liule.hibernate.Coustomer" column="customer_id" ></many-to-one>
            
        </class>
</hibernate-mapping>
Coustomer coustomer =  new Coustomer();
            coustomer.setName("zhangsan");
            coustomer.setOrders(new HashSet());
        
            Order order1 = new Order();
            order1.setOrderNumber("asda");
            Order order2 = new Order();
            order2.setOrderNumber("asdas");
            Order order3 = new Order();
            order3.setOrderNumber("asdasdfds");
            
            order1.setCoustomer(coustomer);
            order2.setCoustomer(coustomer);
            order3.setCoustomer(coustomer);
            
            coustomer.getOrders().add(order1);
            coustomer.getOrders().add(order2);
            coustomer.getOrders().add(order3);
            
            tx = session.beginTransaction();
            session.save(coustomer);//只保存客户,因为coustomer.hbm.xml里面的属性cascade="save-update",主对象改变,副队长也会改变
            tx.commit();

一对多默认的加载模式为延迟加载(lazy loading),当我们在程序中获取到了一的一方,但不需要多的一方,那么使用延时加载就非常合适。

lazy="true";

Class Lazylnitiallzation Exception(异常)  session关闭后,访问未被初始化的代理与集合。

 

2.一对多自身关联

public class Category
{
    private Long id;
    private String name;
    private Category parentCategory;
    private Set<Category> childCategories;
}
<hibernate-mapping >
        <class name="com.liule.hibernate.Category" table="categories">
            <id name="id" column="id" type="long">
                <generator class="increment"></generator> <!--  主键生成方式 -->
            </id>
            
            <property name="name"  type="string">
                <column name="name" length="50"></column>
            </property>
            
            <set name="childCategories" cascade="all" inverse="true">
                <key column="category_id"></key>
                <one-to-many class="com.liule.hibernate.Category"  />
            </set>
            
            <many-to-one name="parentCategory"  class="com.liule.hibernate.Category"   column="category_id" ></many-to-one>
            
        </class>
</hibernate-mapping>
tx = session.beginTransaction();
            Category category1 = new Category("liu",null,new HashSet<Category>());
            Category category2 = new Category("liu",null,new HashSet<Category>());
            Category category3 = new Category("liu",null,new HashSet<Category>());
            Category category4 = new Category("liu",null,new HashSet<Category>());
            Category category5 = new Category("liu",null,new HashSet<Category>());
            Category category6 = new Category("liu",null,new HashSet<Category>());
            Category category7 = new Category("liu",null,new HashSet<Category>());
            
            category2.setParentCategory(category1);
            category3.setParentCategory(category1);
            
            category1.getChildCategories().add(category2);
            category1.getChildCategories().add(category3);
            
            category4.setParentCategory(category2);
            category5.setParentCategory(category2);
            
            category2.getChildCategories().add(category4);
            category2.getChildCategories().add(category5);
            
            category6.setParentCategory(category3);
            category7.setParentCategory(category3);
            
            category3.getChildCategories().add(category6);
            category3.getChildCategories().add(category7);
            
            session.save(category1);
            tx.commit();

3.域对象在持久化层的三种状态

  • 临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。
  • 持久化状态(persistent):已经被持久化,加入到Session的缓存中
  • 游离状态(detached):已经被持久化,但不再处于session的缓存中。

session的缓存:

  • 当session的save方法持久化(将数据保存到数据库中)一个对象时,对象被加入到session缓存中,以后即便应用程序中的引用变量不再引用该对象,只要session的缓存还没有被清空,该对象仍然处于生命周期中。  session的load方法试图从数据库中加载一个对象时,session先判断缓存中是否存在这个对象,如果在,就不需要在数据库中检索。
  • 清理缓存:按照缓存中对象状态的变化来同步更新数据库。当session清理缓存时,只需要执行update语句。
  • 清理缓存的时间点:调用commit,先清理缓存,再提交事物;调用flush()时

update()方法:

  • 把对象重新加入session缓存中,把他变成持久化对象
  • 执行update语句。session只有在清理缓存时才会执行update语句。在程序中多次修改对象的属性,在清理缓存时只会执行一次update语句。

get()与load()区别:(查询时,现在session里查找,若无,则在数据库中寻找)

  • get(),返回一个持久化实例,若无,则返回null;返回属性值本身,
  • load(),返回一个持久化实例,若无,则抛出异常;返回代理,session关闭之前,若真正使用属性时,则生成SQL语句

4.一对一

(1)主键关联(主键值相同)

public class IdCard
{
    private String id;
    private int number;
    private Student student;
    public String getId();
}
public class Student
{
    private String id;
    private String name;
    private IdCard idCard;
}
<hibernate-mapping >
        <class name="com.liule.hibernate.IdCard" table="IdCard">
        
            <id name="id" column="id" type="string" >
                <generator class="foreign"> //利用student生成的id,再生成IdCard的id
                    <param name="property">student</param>
                </generator> <!--  主键生成方式 -->
            </id>
            
            <property name="number"  type="int">
                <column name="number" ></column>
            </property>
            
            
            <one-to-one name="Student" class="com.liule.hibernate.Student"  ></one-to-one>
            
        </class>
</hibernate-mapping>
<hibernate-mapping >
        <class name="com.liule.hibernate.Student" table="student">
            <id name="id" column="id" type="string" >
                <generator class="uuid"></generator> <!--  主键生成方式 -->
            </id>
            
            <property name="name"  type="string">
                <column name="name" length="50"></column>
            </property>
            
            <one-to-one name="idCard" class="com.liule.hibernate.IdCard" cascade="all"></one-to-one>
            
            
            
        </class>
</hibernate-mapping>
public class SchemaExportTest
{
    public static void main(String[] args)
    {
        SchemaExport export = new SchemaExport(new Configuration().configure());
        export.create(true,true);
    }
}
Student student1 = new Student();
            
        student1.setName("sad");
            
            
        IdCard idCard1 = new IdCard();
            
        idCard1.setNumber(21212);
            
        student1.setIdCard(idCard1);
        idCard1.setStudent(student1);
        
        Session session = sf.openSession();
        Transaction tx = null;    
        try
        {
            tx = session.beginTransaction();
            session.save(student1);
            
            tx.commit();
        }

(2)外键关联。本质上一对多的蜕化形式。

<many-to-one name="student" class="com.liule.hibernate.Student" column="student—id" unique="true">  <!--只在某一个对象上设置-->

x.cfg.xml

<property name="max_fetch_depth">2</property>  <!--最大抓取的深度,本例是最多查两张表-->

5.多对多

public class Student
{
    private String id;
    private String name;
    private Set<Course> courses;
  
}
public class Course
{
    private String id;
    private String name;
    private Set<Student> students;

}
<hibernate-mapping >
        <class name="com.liule.hibernate.Student" table="student">
            <id name="id" column="id" type="string" >
                <generator class="uuid"></generator> <!--  主键生成方式 -->
            </id>
            
            <property name="name"  type="string">
                <column name="name" length="50"></column>
            </property>
            
            <set name="courses" cascade="save-update" table="student_course" inverse="true">
                <key column="student_id"></key>
                <many-to-many class="com.liule.hibernate.Course" column="course_id" ></many-to-many>
            
            
            </set>
            
            
            
        </class>
</hibernate-mapping>
<hibernate-mapping >
        <class name="com.liule.hibernate.Course" table="course">
            <id name="id" column="id" type="string" >
                <generator class="uuid"></generator> <!--  主键生成方式 -->
            </id>
            
            <property name="name"  type="string">
                <column name="name" length="50"></column>
            </property>
            
            <set name="students" cascade="save-update" table="student_course" >
                <key column="course_id"></key>
                <many-to-many class="com.liule.hibernate.Student" column="student_id" ></many-to-many>
            
            
            </set>
            
            
            
        </class>
</hibernate-mapping>
public static void main(String[] args)
    {
        
//        Student student1 = new Student();    
//        student1.setName("sad");
//        
//        Course course1 = new Course();
//        course1.setName("muise");
//            
//        student1.setCourses(new HashSet<Course>());
//        course1.setStudents(new HashSet<Student>());
//        
//        student1.getCourses().add(course1);
//        
        Session session = sf.openSession();
        Transaction tx = null;    
        try
        {
            tx = session.beginTransaction();
            Student student = (Student) session.get(Student.class,"402881eb513f9c8301513f9c86bb0000");
            Course course = (Course) session.get(Course.class,"402881eb513f9c8301513f9c86ed0001");
            
            student.getCourses().add(course);
            course.getStudents().add(student);
//            session.save(student1);
            
            tx.commit();
        }
        catch(Exception ex)
        {
            if(null != tx)
            {
                tx.rollback();
            }
        }
        finally
        {
            session.close();
        }
        
    }
}

补充:http://www.cnblogs.com/otomedaybreak/archive/2012/01/20/2327695.html

http://www.cnblogs.com/jyh317/p/3691842.html

 

posted on 2015-11-26 01:23  彩屏黑白  阅读(188)  评论(0编辑  收藏  举报

导航