您的位置:首页 > 其它

Hibernate中的延迟加载、实体关联单向一对多及双向一对多实体关联

2017-01-08 00:23 495 查看
1、get vs load:
get : 
1. 执行时,立刻查询.
2. 如果找不到指定id的对象, 则返回null.
load : 
1. 执行时,不会立刻查询,  真正要使用实体时(用到非id属性)才会去查询;
2. 如果找不到指定id的对象, 则抛异 常. No row with the given identifier exists: [entity.Student#10]
Hibernate中默认为延迟加载;

------------------------------------------------------------------------------

例如:

Student stu1 = (Student)session.get(entity.Student.class, 1); 
//get方法, 立刻查询student对象,但是不含Clazz对象.
Student stu2 = (Student)session.load(entity.Student.class, 3); 
//load方法. 不会立刻查询student对象,什么时候用到Student什么时候查
stu2.getId(); //没有使用到Student实体的内容, 不会查sql
stu2.getName(); //执行sql  

-------------------------------------------------------------------------------

2、单向一对多实体关联:

【多方的配置文件Student.hbm.xml】

<hibernate-mapping>
    <class name="entity.Student" >
        <id name="id" type="java.lang.Integer">
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String" length="10"></property>
    </class>
</hibernate-mapping> 

【一方的配置文件Clazz.hbm.xml】

<hibernate-mapping>
4000
;

    <class name="entity.Clazz" >

        <id name="id" type="java.lang.Integer">

            <generator class="native"></generator>

        </id>

        <property name="name" type="java.lang.String" length="10"></property>

        <!-- 

        inverse : 翻转,  由哪一方维护关联关系.

         -->

        <bag name="students" >

            <!-- 对应的外键.Student表的外键 -->

            <key column="clazz_id"></key>

            <one-to-many class="entity.Student" />

        </bag>

    </class>

</hibernate-mapping> 

实体类Clazz

public class Clazz {
    private Integer id;
    private String name;
    
    private List<Student> students;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
    
}

实体类Student:

public class Student {
    private Integer id;
    private String name;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
}

------
1450a
-------------------------------------------------------------------------------------------------------------------------------------------

操作类:

//把学生从班级中移出, 解除班级和学生的关系.
        Clazz clazz = (Clazz)session.get(entity.Clazz.class, 1);
        List students = clazz.getStudents();
        Student stu = (Student)session.get(entity.Student.class, 1);
        students.remove(stu);  

---------------------------------------------------------------------------------------------------------------------------------------------------------

3、双向一对多实体关联:

//初始化环境工具类
public class InitEvn {
    public static void main(String[] args) {
        //Hibernate的配置类对象,用于创建SessionFactory.
        Configuration conf = new Configuration().configure();
        
        SchemaExport se = new SchemaExport(conf);
        
        //正向工程  (是否显示脚本, 是否执行脚本)
        se.create(truetrue);
    }
}  

------------------------------------------------------------------------------------------------------------

xml文件的配置:

[Student.hbm.xml]

<hibernate-mapping>
    <class name="entity.Student" >
        <id name="id" type="java.lang.Integer">
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String" length="10"></property>
        
        <many-to-one name="clazz" class="entity.Clazz">
            <column name="clazz_id"></column>
        </many-to-one>
    </class>
</hibernate-mapping>  

[Clazz.hbm.xml]

<hibernate-mapping>
    <class name="entity.Clazz" >
        <id name="id" type="java.lang.Integer">
            <generator class="native"></generator>
        </id>
        <property name="name" type="java.lang.String" length="10"></property>
        <!-- 
             inverse="true"  . 控制权交给了Student来维护两个表的关系.
             一般是由one方,翻转到many方.
             inverse="false",表示双方都可以控制关联. 当代码中设置了双向关联的时候,可能会出现多次update语句.
             
             双向关联的时候,一般都会设置为控制范围到多的一方. 否则会有性能问题..
         -->
        <bag name="students" inverse="true"  >
            <key column="clazz_id"></key>
            <one-to-many class="entity.Student" />
        </bag>
        
    </class>
</hibernate-mapping> 

实体类Clazz:

public class Clazz {
    private Integer id;
    private String name;
    
    private List<Student> students;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
    
}  

实体类Student

public class Student {
    private Integer id;
    private String name;
    
    private Clazz clazz;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Clazz getClazz() {
        return clazz;
    }
    public void setClazz(Clazz clazz) {
        this.clazz = clazz;
    }
    
}

操作类(测试):

public class Test {

    public static void main(String[] args) {

        addTest();

    

    }

    

    static void addTest(){

        Session session = HibernateSessionFactory.getSession();

        Clazz c1 = new Clazz();

        c1.setName("JAVA1");

        

        Student stu1 = new Student();

        Student stu2 = new Student();

        stu1.setName("Zhangsan1");

        stu2.setName("Lisi1");

        

        List students = new ArrayList();

        students.add(stu1);

        students.add(stu2);

        

        //设置班级和学生关联, (双向设置)

        c1.setStudents(students);

        //stu1.setClazz(c1);

        stu2.setClazz(c1); //stu2维护着和班级的关系

        

        /*

         * 如果单独保存班级,不保存学生, 异常!!!

         * 如果单独保存学生,不保存班级,异常!!!

         */

        session.save(c1); 

        session.save(stu1);

        session.save(stu2);

        

        session.beginTransaction();

        session.getTransaction().commit();

        session.close();

    }

    

}  

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: