1+N就是在hibernate中第一次查一个所需要的表的内容,他会把别的相关表的内容也查询一遍。

 

解决办法有三种:

1,设置LAZY。

2,借鉴createCriteria的查询语句,from Topic t left join fetch t.category c,通过join fetch来屏蔽多于查询。

3,将多次查询整成一次查询。给多于表加上BatchSize注解。这种方法并没有解决问题,只是相对来说优化了一点。

 

解决办法3的写法:

package com.bjsxt.hibernate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.annotations.BatchSize;

@Entity
//@BatchSize(size=5)//加上BachtSize注解,如此,一次会查询五条相关内容
public class Category {
    private int id;
    private String name;
    @Id
    @GeneratedValue
    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;
    }
}

 

 

 

测试类:

import java.util.Date;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class HibernateQLTest {
    private static SessionFactory sf;
   
    @BeforeClass
    public static void beforeClass() {
        sf = new AnnotationConfiguration().configure().buildSessionFactory();
    }
    @AfterClass
    public static void afterClass() {
        sf.close();
    }
   
    @Test
    public void testSchemaExport() {
        new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
    }
   
    @Test
    public void testSave() {
        Session session = sf.openSession();
        session.beginTransaction();
       
        for(int i=0; i<10; i++) {
            Category c = new Category();
            c.setName("c" + i);
            Topic t = new Topic();
            t.setCategory(c);
            t.setTitle("t" + i);
            t.setCreateDate(new Date());
            session.save(c);
            session.save(t);
        }
           
        session.getTransaction().commit();
        session.close();
    }
   
    //N+1
    @Test
    public void testQuery1() {
        Session session = sf.openSession();
        session.beginTransaction();
        //List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
        List<Topic> topics = (List<Topic>)session.createQuery("from Topic").list();
                    
       
        for(Topic t : topics) {
            System.out.println(t.getId() + "-" + t.getTitle());
        }
        session.getTransaction().commit();
        session.close();
       
    }
   
    @Test
    public void testQuery2() {
        Session session = sf.openSession();
        session.beginTransaction();
        //List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();//关联关系不设lazy也不会全部查询,因为使用的是关联表方式
        List<Topic> topics = (List<Topic>)session.createQuery("from Topic").list();//关联关系不设lazy会全部查询
                    
       
        for(Topic t : topics) {
            System.out.println(t.getId() + "-" + t.getTitle());
            System.out.println(t.getCategory().getName());
        }
        session.getTransaction().commit();
        session.close();
       
    }
   
    //@BatchSize
    @Test
    public void testQuery3() {
        Session session = sf.openSession();
        session.beginTransaction();
        //List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
        List<Topic> topics = (List<Topic>)session.createQuery("from Topic").list();
       
        for(Topic t : topics) {
            System.out.println(t.getId() + "-" + t.getTitle());
            System.out.println(t.getCategory().getName());
        }
        session.getTransaction().commit();
        session.close();
       
    }
    //join fetch
    @Test
    public void testQuery4() {
        Session session = sf.openSession();
        session.beginTransaction();
        //List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
        List<Topic> topics = (List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list();
       
        for(Topic t : topics) {
            System.out.println(t.getId() + "-" + t.getTitle());
            System.out.println(t.getCategory().getName());
        }
        session.getTransaction().commit();
        session.close();
       
    }
    public static void main(String[] args) {
        beforeClass();
    }
}

hibernate 1 + N 问题解决的更多相关文章

  1. org.hibernate.QueryException: duplicate alias: r hibernate别名重复问题解决

    今天做项目的过程中发现,多表查询的时候如果使用hibernate的DetachedCriteria离线查询方式的时候, 在多表关联的时候我们需要使用别名的方式去实现. 但是代码运行的过程中抛出了下面的 ...

  2. ogn1.MethodFailedException:Method "xxx" failed for object xxx

    问题描述:初学ssh写了个小项目,访问界面出现以下错误 java. lang. NoSuchllethodError: org. hi bernate. SessionF actory. openSe ...

  3. 使用hibernate原生sql查询,结果集全为1的问题解决

    问题如下: String sqlTest ="select summary,summaryno from F_Summary"; List<Map<Object, Ob ...

  4. hibernate 4.3 在使用获取数据获取不到数据库中最新变更的数据问题解决

    hibernate 4.3 在使用获取数据获取不到数据库中最新变更的数据问题解决,应该是因为缓存问题 问题过程和现象: 查询一个数据列表=>数据库中手动update了数据=>刷新页面,数据 ...

  5. hibernate添加数据,默认字段为null的问题解决

    数据库中的一个字段默认为0,但是在用hibernate的添加之后,默认字段竟然不是0,为NULL. 查了一下.发现想要让默认字段生效.需要在*.hbm.xml添加一些参数,如下.(红色部分) dyna ...

  6. mybatis 并发问题解决,参考hibernate

    时候操作同一账户就是典型的样例. 比方A.B操作员同一时候读取一剩余金额为1000元的账户,A操作员为该账户添加100元.B操作员同一时候为该账户减去 50元.A先提交.B后提交. 最后实际账户剩余金 ...

  7. Confluence 6 "net.sf.hibernate.PropertyValueException: not-null" 相关问题解决

    如果你遇到了下面的错误信息,例如: ERROR [Importing data task] [confluence.importexport.impl.ReverseDatabinder] endEl ...

  8. Hibernate 自动创建表bug问题解决

    我在hibernate.cfg.xml配置文件中添加了自动创建表的的属性:(这样当数据库中没有此表是,hibernate就会自动帮我们创建一张表) <property name="hb ...

  9. cloudera-scm-server启动时出现Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Could not open connection问题解决方法(图文详解)

    问题现象 查看 [root@cmbigdata1 cloudera-scm-server]# pwd /var/log/cloudera-scm-server [root@cmbigdata1 clo ...

随机推荐

  1. Python开发基础-Day3-列表、元组和字典

    列表 列表定义:[]内以逗号分隔,按照索引,存放各种数据类型,每个位置代表一个元素 特性: 1.可存放多个值 2.可修改指定索引位置对应的值,可变 3.按照从左到右的顺序定义列表元素,下标从0开始顺序 ...

  2. poj 1681(Gauss 消元)

    Painter's Problem Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5875   Accepted: 2825 ...

  3. 【数据结构】Not so Mobile (6-9)

    [UVA839]Not so Mobile 算法入门经典第6章6-9(P157) 题目大意:输入一个树状天平,根据力矩相等原则判断是否平衡. 试题分析:貌似没有什么难点…… #include<i ...

  4. 【模拟+递归+位运算】POJ1753-Flip Game

    由于数据规模不大,利用爆搜即可.第一次用位运算写的,但是转念一想应该用递归更加快,因为位运算没有剪枝啊(qДq ) [思路] 位运算:时间效率较低(172MS),有些辜负了位运算的初衷.首先将二维数组 ...

  5. CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂

    772002画马尾 题目连接: http://acm.uestc.edu.cn/#/problem/show/1280 Description 众所周知772002很喜欢马尾,所以他决定画几幅马尾送给 ...

  6. CentOS6安装NodeJS(非编译)

    由于编译安装需要各种依赖库,会远远高于生产环境下的默认版本,强行升级会产生很多不必要的问题,所以一般用官网编译好的安装 下载nodejs并安装 wget https://nodejs.org/dist ...

  7. bash中的管道和重定向

    管道 管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,对于 stdandarderror 信息没有直接处理能力.然后,传递给下一 ...

  8. php ob静态缓存

    <?php ob_start(); //打开输出缓冲区 $cacheTime = 864000; //设置缓存页面过期时间 $cacheDir = 'cacheDir'; //设置缓存页面文件目 ...

  9. img转base64的两种方式的比较

    关于图片转base64然后提交后台,项目中一直用的是canvas的toDataUrl方法,但是之前看HTML5 API文档的时候,一直记得好像有个叫fileReader的东西也可以做到.于是过年无事的 ...

  10. 《Go语言实战》笔记之协程同步 sync.WaitGroup

    原文地址(欢迎互换友链): http://www.niu12.com/article/8 sync 包提供同步 goroutine 的功能 <p>文档介绍</p><cod ...