关于hibernate的n+1问题以及解决办法

hibernate的n+1问题已经是一个很常见的问题了。

最近遇到了很多次的n+1问题,总结一下解决办法:

1.ManyToOne中的n+1:

当查询单个的时候,可以使用来进行让其join查询,

觉得manyToOne的n+1问题同样可以使用这种方法,其中FetchMode有三个参数:

public enum FetchMode {
    /**
     * use a select for each individual entity, collection, or join load.
         * 产生n+1的查询,每个都生成一条查询语句
         * n+1条查询
     */
    SELECT,
    /**
     * use an outer join to load the related entities, collections or joins.
         * 使用一条outer join进行查询
         * 1条查询
     */
    JOIN,
    /**
     * use a subselect query to load the additional collections.
         * 使用一条查询list语句进行查询
         * 2条查询
     */
    SUBSELECT
}

2.查询主体为list的时候的查询

上面的办法应该是可以解决n+1,但是在查询主表的列表是竟然发现还是会产生多一条语句的情况,于是经过百般查找,找到了一种通过hql来解决此问题的方法:

@Entity
@Table(name = "xxxx")
public class ShowInfoEntity implements Serializable {
    private static final long serialVersionUID = -5078958740245381213L;

    // id
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    // numapi
    @OneToOne(fetch = FetchType.EAGER, optional = false, mappedBy = "showInfo")
    @Fetch(FetchMode.JOIN)
    private ShowNumber numapi;

首先这个是主表,其中与从表ShowNumber有一个关联关系,此关联关系是定义在从表中的。

看到这个类上有配置@Fetch 其在查询单个ShowInfoEntity时是能完美的起作用的,即是join查询,但是在查询List<ShowInfoEntity>时就没有这么幸运了,

会先查询一个List<ShowInfoEntity>  之后在查询n条numapi,

使用left join语句也不能解决问题,

最后找到了left join fetch:

@Query("select t from ShowInfoEntity t LEFT join fetch t.numapi r  where t.enable =0 and t.accountId in (?1) and t.timeline<?2")
List<ShowInfoEntity> findByFlush(List<Long> toUsersPredicate, Long time, Pageable page);

顺便说一句,hibernate 的hql语句中的join挺麻烦的,需要先配置好关联关系,然后join 主表.从表

列举一下hql中的join连接

1。左外连接 
     左外连接(Left Outer Join)查询出左表对应的复合条件的所有记录

2.左外抓取连接 
     左外抓取连接指定在Hibernate检索数据时,采用抓取的方式,直接将数据加载到与主表对象关联的从表属性中。

3.右外连接 
    HQL中使用关键字right outer join右外连接

4.内连接

  内连接(Inner Join)是指两个表中指定的关键字相等的值才会出现在结果集中的一种查询方式。HQL中使用关键字inner join进行内连接,

5.抓取内连接    

  抓取内连接与内连接不同之处在于其对象的内存状态不一样。HQL中使用inner join fetch进行抓取内连接。

时间: 2024-10-07 17:43:39

关于hibernate的n+1问题以及解决办法的相关文章

hibernate 普通字段延迟加载无效的解决办法

关联对象的延迟加载就不说了,大家都知道. 关于普通字段的延迟加载,尤其是lob字段,若没有延迟加载,对性能影响极大.然而简单的使用 @Basic(fetch = FetchType.LAZY) 注解并没有效果.hibernate对此的解释是Lazy property loading requires buildtime bytecode instrumentation. If your persistent classes are not enhanced, Hibernate will ign

hibernate 无法自动创建表 的解决办法

执行session.save() 时出现异常: org.hibernate.exception.SQLGrammarException: could not execute statement 无法创建表. 解决方法: 1)确定配置: <property name="hibernate.hbm2ddl.auto">update</property> 2)如果是mysql5的话,确定配置: <property name="hibernate.dia

Hibernate不能自动建数据表解决办法

首先自己要注意自己的MYSQL版本,然后设置对应的方言 兼容性模式 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 需要注意的是5.5一下版本可以使用 <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop

Spring定时器调用Hibernate方法无法获得SessionFactory的解决办法

由于在Spring定时器中无法通过注解的方式获取bean,因此需要通过原生的方式获取.获取session的方式如下: WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext(); SessionFactory factory=wac.getBean(SessionFactory.class); Session session=factory.openSession();

使用Hibernate+MySql+native SQL的BUG,以及解决办法

本来是mssql+hibernate+native SQL 应用的很和谐 但是到了把mssql换成mysql,就出了错(同样的数据结构和数据). 查询方法是: [java] view plaincopy String sql = "select id XXX_ID  from t_tab"; List<Map> list = session.createSQLQuery(sql) .setResultTransformer(Transformers.ALIAS_TO_ENT

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session异常解决办法

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session异常解决办法 为什么还会说已经存在相同的session了呢.然后每次将项目重启后第一次编辑的时候问题不会触发,只有当第二次操作的时候才会出现这个问题. 解决办法:关闭session.好好检查操作完成后有没有关闭会话. org.hibernat

在IntelliJ IDEA中添加框架支持时找不到Hibernate的解决办法

问题描述 第一次在Add Frameworks support界面中添加hibernate支持的时候,异常中断,导致没有成功添加. 第二次进入Add Frameworks support窗口时,发现找不到hibernate. 解决办法 打开项目根目录下的spring-mvc-crud.iml文件,搜索hibernate找到这段代码并删除,然后重新添加框架支持即可选择hibernate. <facet type="hibernate" name="Hibernate&qu

SSH项目web.xml文件的常用配置【struts2的过滤器、spring监听器、解决Hibernate延迟加载问题的过滤器、解决中文乱码的过滤器】

配置web.xml(struts2的过滤器.spring监听器.解决Hibernate延迟加载问题的过滤器.解决中文乱码的过滤器) <!-- 解决中文乱码问题 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-c

hibernate开发错误及解决办法

1. Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at net.sf.hibernate.cfg.Configuration.(Configuration.java:95) at cn.yuan.xmlparse.base._BaseRootDAO.initialize(_BaseRootDAO.java:49) at cn.yuan.x