zoukankan      html  css  js  c++  java
  • Hibernate综合问题

    n + 1问题

    query.iterate()信息返回迭代查询将开始发表声明:录ID语句

         Hibernate: select student0_.id ascol_0_0_from t_student student0_

    然后有多少条记录,会发出多少条查询语句。

    n + 1问题:n:有n条记录。发出n条查询语句。1 :发出一条查询全部记录ID语句。

    出现n+1的原因:由于iterate(迭代查询)是使用缓存的,第一次查询数据时发出查询语句载入数据并增加到缓存,以后再查询时hibernate会先到ession缓存(一级缓存)中查看数据是否存在。假设存在则直接取出使用,否则发出查询语句进行查询。

                session=HibernateUtils.getSession();
                tx = session.beginTransaction();
              
                /**
                 * 出现N+1问题
                 * 发出查询id列表的sql语句
                 * Hibernate: select student0_.idas col_0_0_ from t_student student0_
                 *
                 * 再依次发出依据id查询Student对象的sql语句
                 * Hibernate: select student0_.idas id1_0_, student0_.name as name1_0_,
                 * student0_.createTime ascreateTime1_0_, student0_.classesid as classesid1_0_
                 * from t_student student0_ wherestudent0_.id=?

    */ Iterator students =session.createQuery("fromStudent").iterate(); while (students.hasNext()){ Student student=(Student)students.next(); System.out.println(student.getName()); } tx.commit();



    先运行query.list()。再运行query.iterate。这样不会出现N+1问题

    由于list操作已经将Student对象放到了一级缓存中,所以再次使用iterate操作的时候

    它首先发出一条查询id列表的sql。再依据id到缓存中取数据。仅仅有在缓存中找不到对应的

    数据时,才会发出sql到数据库中查询

                List students =session.createQuery("from Student").list();
              
                for (Iterator iter =students.iterator();iter.hasNext();){
                    Student student=(Student)iter.next();
                   System.out.println(student.getName());
                }                      System.out.println("---------------------------------------------------------");
                 // 不会出现N+1问题,由于list操作已经将数据增加到一级缓存。
                Iterator iters=session.createQuery("from Student").iterate();
              
                while (iters.hasNext()){
                    Student student=(Student)iters.next();
                   System.out.println(student.getName());
                }


    list 和 iterate不同之处

    a) list取全部

    b) Iterate先取ID,等用到的时候再依据ID来取对象

    c) session中list第二次发出。仍会到数据库查询

    d) iterate第二次,首先找session级缓存

    Session级缓存(一级缓存)

    一级缓存非常短和session的生命周期一致。因此也叫session级缓存或事务级缓存

           

    哪些方法支持一级缓存:

             get()

             load()

             iterate(查询实体对象)

    怎样管理一级缓存:

             session.clear(),session.evict()

    怎样避免一次性大量的实体数据入库导致内存溢出

             先flush,再clear

           

    假设数据量特别大。考虑採用jdbc实现,假设jdbc我们不能满足数据的要求本身就可以被认为是一个特定的导入工具

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    机器学习框架ML.NET学习笔记【5】多元分类之手写数字识别(续)
    机器学习框架ML.NET学习笔记【3】文本特征分析
    机器学习框架ML.NET学习笔记【2】入门之二元分类
    Git项目下载部分文件或文件夹
    一个扫雷游戏和一个自动玩扫雷游戏的程序
    循序渐进学.Net Core Web Api开发系列【16】:应用安全续-加密与解密
    循序渐进学.Net Core Web Api开发系列【15】:应用安全
    循序渐进学.Net Core Web Api开发系列【14】:异常处理
    通过源码学习@functools.lru_cache
    【Python3爬虫】破解时光网登录加密参数并实现模拟登录
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4854353.html
Copyright © 2011-2022 走看看