zoukankan      html  css  js  c++  java
  • 【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。

  • 相关阅读:
    实现不限层级的Element的NavMenu
    vue_插槽的理解和使用
    vue 动态修改路由参数
    什么是回流,什么是重绘,有什么区别?
    Vue路由获取路由参数
    【前端图表】echarts实现散点图x轴时间轴
    为什么 char 数组比 String 更适合存储密码?
    MySQL 日期时间类型怎么选?千万不要乱用!
    MySQL not exists 真的不走索引么?
    谷歌开源的代码评审规范,值得借鉴!
  • 原文地址:https://www.cnblogs.com/HDK2016/p/7351328.html
Copyright © 2011-2022 走看看