• Hibernate之load和get的差别


    load和get都会能够起到从数据库中获取持久态数据的作用。可是还有些略微的差别的。


    參考以下的这个样例:

    @Test(expected = IllegalArgumentException.class)
    public void testLazyLoad() throws Exception {
        // 启动
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
    
        User user = (User)session.load(User.class, 100L);  // 不存在的ID
    
        try {
            user.getName();
        } catch (ObjectNotFoundException ex) {
            // 命中数据库发现没有对象即抛出ObjectNotFoundException异常
            throw new IllegalArgumentException("随便抛出一个不可能的异常");
        }
    
        tx.commit();
        session.close();
    }
    
    
    @Test(expected = IllegalArgumentException.class)
    public void testLazyLoad() throws Exception {
        // 启动
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
    
        User user = (User)session.load(User.class, 100L);  // 不存在的ID
    
        Assert.assertTrue(user instanceof HibernateProxy);
    
        user.getId();  // 因为ID是不被延迟载入的属性。因此不会抛出异常
    
        try {
            Hibernate.initialize(user);  // 触发命中数据库
            //user.getName();
        } catch (ObjectNotFoundException ex) {
            // 命中数据库发现没有这个对象抛出ObjectNotFoundException异常
            throw new IllegalArgumentException("异常");
        }
    
        tx.commit();
        session.close();
    }
    1. 在这里能够看出load并没有直接获取数据,而是获取到的代理对象-->HibernateProxy,假设不获取简单类型的属性的时候是不会抛出异常的,可是get不一样。他直接去数据库中取。他得到的是对象本身,假设得不到的话就会返回空值。


    再看一个样例:

    @Test
    public void testGetAndLoadSession() throws Exception {
        // 启动
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
    
        // load在缓存为空的情况下是否会使得载入的对象过一级缓存
        User user1 = (User)session.load(User.class, 1L);  // 存在的ID。此时尽管没有解开Proxy但已经进入缓存
        Assert.assertTrue(user1 instanceof HibernateProxy);
        Hibernate.initialize(user1);  // 解开Proxy。会触发命中数据库操作
        User user3 = (User)session.get(User.class, 1L);
        Assert.assertTrue(user3 instanceof HibernateProxy);  // 即使使用get,但因为缓存中存储的是一个Proxy,所以这里得到的也是Proxy
        Hibernate.initialize(user3);  // 解开Proxy。但不会命中数据库
    
        // 验证在load一个不存在的ID后。不解开然后get
        User user4 = (User)session.load(User.class, 100L);  // 不存在的ID。仍然将Proxy进入缓存
        Assert.assertTrue(user4 instanceof HibernateProxy);
        //Hibernate.initialize(user3);  // 不解开Proxy
        try {
            session.get(User.class, 100L);  // 得到Proxy,命中数据库尝试解开Proxy,因为ID不存在因此抛出异常
            Assert.fail("ID不存在所以会出错。不会运行本条");
        } catch (ObjectNotFoundException ex) {
    
        }
    
        // 清空缓存
        session.clear();
    
        // 验证缓存为空的情况下get是否为Proxy
        User user6 = (User)session.get(User.class, 1L);  // 命中数据库,直接将组装完毕的User实体进入缓存
        Assert.assertTrue(!(user6 instanceof HibernateProxy));
    
        // 验证get从缓存中取出对象
        User user7 = (User)session.get(User.class, 1L);
        Assert.assertTrue(!(user7 instanceof HibernateProxy)); // 缓存中是真实的User对象。get取出的就是真实的User对象
    
        // 验证load是否从一级缓存取数据
        User user8 = (User)session.load(User.class, 1L);
        Assert.assertTrue(!(user8 instanceof HibernateProxy));  // 缓存中是真实的User对象,load取出的也是真实的User对象
    
        tx.commit();
        session.close();
    }

    2. 假设是load方法将对象载入到了缓存其中。那么在get和load的时候得到的都是代理对象,可是假设是get方法将对象载入到了缓存中的时候。那么在get和load的时候得到的是一个实体对象。


  • 相关阅读:
    iOS Runtime 实践(1)
    支付宝接口使用文档说明 支付宝异步通知
    ASP.NET中数据棒图,饼图,柱状图的实现
    ASP.NET运行机制之一般处理程序(ashx)
    ASP.NET的一套笔试题
    ASP.NET页面优化性能提升方法记录
    ASP.NET 大文件上传的简单处理
    ASP.NET输出PNG图片时出现GDI+一般性错误的解决方法
    您可能不知道的ASP.Net小技巧
    cache应用(asp.net 2.0 SQL数据缓存依赖 [SqlCacheDependency ] )
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7248240.html
Copyright © 2020-2023  润新知