• 【Hibernate】浅析hibernate中的延迟加载


    1 简介

    在使用一些查询方法时,方法执行了,但是并没有立刻发送SQL语句查询数据库。而是在访问对象的getXxx方法时候才触发SQL执行加载对象数据。这种机制就称为延迟加载。

    2 优点

    延迟加载主要是为后续关联映射提供,避免查找无用的关联数据。
    可以降低数据库操作的并发率,提升内存资源使用率。

    3 使用

    在struts2中,session.load()/query.iterator()和关联映射都使用的这种机制。

    下面笔者使用session.load()方法举例:

    hibernate.cfg.xml 文件

    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
              "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
              "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    
    <!-- Generated by MyEclipse Hibernate Tools.                   -->
    <hibernate-configuration>
        <session-factory>
            <property name="dialect">
                org.hibernate.dialect.MySQLDialect
            </property>
            <property name="connection.url">
                jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8
            </property>
            <property name="connection.username">root</property>
            <property name="connection.password">517839</property>
            <property name="connection.driver_class">
                com.mysql.jdbc.Driver
            </property>
            <property name="show_sql">true</property>
            <property name="format_sql">true</property>
            
            <!-- 加载映射描述信息 -->
            <mapping class="cn.test.bean.User" />
            
        </session-factory>
    </hibernate-configuration>
    hibernate.cfg.xml

    在里面指定了在控制台打印Sql执行日志

    User.java 文件

    package cn.test.bean;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    @Entity
    @Table(name="user")//表示对应的表名
    public class User {
    
        @Id
        @Column(name="uid")
        private int id;
        @Column(name="uname")
        private String name;
        @Column(name="upass")
        private String password;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        
        
        
    }
    User.java

    接下来是测试文件:

    如果我们使用如下的测试代码

    Configuration conf = new Configuration();
    conf.configure("hibernate.cfg.xml");//读取连接参数和映射描述信息
    SessionFactory factory = conf.buildSessionFactory();
    Session session = factory.openSession();
    User user = (User)session.get(User.class,1);
    System.out.println("我在语句发送之后");            
    System.out.println(user.getId()+","+user.getName()+","+user.getPassword());
    session.close();

    可以看到控制台上打印出了信息

    如果把上面的get方法换成 User user = (User)session.load(User.class,1); 

    通过这两次结果的对比可以看出,load方法使用延迟加载。使用load方法获取数据的方式,当程序加载到load方法时,程序并不会真正从数据库中查询语句,只有当查询的结果对象使用getXxx()方法的时候,才会在数据库中查询。

    4 异常:org.hibernate.LazyInitialization:could not initialize proxy -  no Session

    如果使用了延迟加载,并且出现这样的错误,就是很有可能是session关早了。在session关闭后,再调用结果对象的getXxx(),这样从数据库中查询数据就会出错。在MVC开发出,如果想要使用延迟加载(使用session.load()方法或是query.iterator()方法)从数据库中取出数据到页面展现(在页面调用对象的getXxx方法),那么在数据层得到数据对象后,不要关闭session,因为关闭session后,再在页面调用getXxx()方法就会抛出异常。

    要解决这种方法,要么不使用延迟加载,要么就在页面调用了getXxx()方法后,再关闭session。

  • 相关阅读:
    JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码
    JVM 性能调优实战之:一次系统性能瓶颈的寻找过程
    MongoDB之一介绍(MongoDB与MySQL的区别、BSON与JSON的区别)
    spring之:XmlWebApplicationContext作为Spring Web应用的IoC容器,实例化和加载Bean的过程
    SpringBoot自动化配置之四:SpringBoot 之Starter(自动配置)、Command-line runners
    分析诊断工具之一:MYSQL性能查看(多指标)
    Condition-线程通信更高效的方式
    微服务监控之一:Metrics让微服务运行更透明
    游戏后台服务技术选型
    TCP之四:TCP 滑动窗口协议 详解
  • 原文地址:https://www.cnblogs.com/HDK2016/p/7351328.html
Copyright © 2020-2023  润新知