学习hibernate不可绕过的两个问题

来源:互联网 发布:sql 入门到精通 编辑:程序博客网 时间:2024/06/05 13:22

   刚刚学了hibernate,对以下两个问题比较感兴趣,仅仅代表个人的见解,大家多多指教。。。

   第一个问题:

      为什么在写主配置文件(<hibernate-configuration>)时,用的载体是xml,而不是写在了其他载体上?

        答:原因有三:主要原因大家都在用xml来写主配置文件;

       次要原因xml语句优美对称,条理清晰,写语句时会感受到它的潜在提示作用;

        个人观点:如果不用xml这个载体,还有其它更好的载体吗?至少目前我还没找到其他更好的载体。

     第二个问题:

        数据的延迟加载(就是数据从数据库调到内存时,数据不是立即加载到内存里的,而是通过一个代理为中介,等到用到该数据时,且数据库连接还没有关闭,才加载到内存,如果数据库连接关闭则数据就不能赋给代理,进而数据传不到内存中)

        注意:(代理里面仅仅有将要传入内存数据的部分数据,里面存的不是对象数据的完整数据,在用代理时必须对其初始化,否则测试时会报一个“代理没有初始化”的错误)

 

       代码解释如下:

private Record findBy(Serializable book_id, Serializable stu_id)  throws Exception {    // 该方法的功能:根据书的id和学生的id查找学生借书的记录Student stu;try {Session session = HibernateUtil.getSessionFactory().openSession();// 获得一个打开的sessionstu = (Student) session.get(Student.class, stu_id);// 根据stu_id找到对应的学生,此时的stu是一个持久态,session.close();// session关闭,进而数据库关闭,stu变为游离状态,再次使用stu时,再对其的任何操作都与数据库无关了。Set<Record> records = stu.getRecords(); // 获得record集合。/* * 为什么写了这句代码,这个方法在测试的时候会报错,报错的原因有两个,一是执行了stu.getRecords() * 之后,records什么数据也没得到,二是代理(proxy)没有初始化(在这个地方可把stu.getRecords()视为代理)                   */                // 为何records什么数据也没得到?/* * 因为session关闭,又因hibernate默认延迟加载,在还没用到因为延迟而加载的数据时,就把session关了, * 也就是把数据库连接关闭了,进而代理(stu.getRecords())得不到应该得到的数据,那么数据就不可能从数据库里面传到内存中, * 并且程序有一个代理没有初始化的错误。 因此records从stu.getRecords()这个对象里得不到任何数据 */for (Record record : records) {if (book_id.equals(record.getBook().getId()))// 从借书记录里面查与参数id相同的记录。return record;}return null;} catch (Exception e) {throw e;}}




 

延伸一:为什么在持久化状态的对象(stu)才可以Set<Record>  records  =  stu.getRecords() 这样操作,进而records获得一个集合的数据?

如果数据库关闭,要想取得一个集合里面的数据,只能从内存中调,内存中不存在这些数据(比如去年的记录,不可能还在内存中,去年的记录在系统关闭时,已经从内存中消失)

延伸二:如果在内存中没有消失(且不用session使对象变为持久态),怎么调?

数据必须是存在一个集合里面,从该集合中一个一个的拿出来。