• 关于hql一些不常见但好用的技巧(个人总结)


    最近一直在用spring-data-jpa这个东西,感觉方法上注解hql语句已经是很常用的方法了,

    有一些关于hql的经验分享一下:

    一.hql的join

      hql的优势就是直接的关联关系嘛,但是通过hql语句进行join查询的时候,需要注意一些地方:

      hql的join不能像类似sql的join一样,直接join两张表,需要先维护关联关系,在join:

        

    @Entity
    @Table(name = "mq_mark")
    public class MarkModel implements Serializable {
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = -5169585172209348371L;
    
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	public Long id;
    
    	@ManyToOne(fetch = FetchType.EAGER)
    	@JoinColumn(name = "show_id", nullable = false)
    	@Fetch(FetchMode.JOIN)
    	public ShowImage showImage;
    }
    

     然后在进行hql join查询

    @Query("select r from MarkModel t join t.showImage r where t.type= ?1 and t.datamId = ?2  ")
        List<ShowImage> findMarkImages(Integer marktype, Long datamId, Pageable pageable);

    会生成 left join 语句

    二:hql语句的去重

     使用sql去重一般是使用distinc ,但是这种方式是会影响效率的。

     hql的去重推荐使用group by

    @Query("select t.showImage from MarkModel t where t.type= ?1 and t.datamId = ?2  group by t.showImage.id")
        List<ShowImage> findMarkImages(Integer marktype, Long datamId, Pageable pageable);

    看一下其生成的语句:

    select showimage1_.id as id1_25_, showimage1_.create_time as create_t5_25_, showimage1_.image_url as image_ur8_25_, showimage1_.position as positio14_25_ 

    from xxx markmodel0_ inner join mq_showpic showimage1_ on markmodel0_.show_id=showimage1_.id

    cross join mq_showpic showimage2_

    where markmodel0_.show_id=showimage2_.id and markmodel0_.type=? and markmodel0_.datam_id=?

    group by markmodel0_.show_id order by showimage2_.create_time desc limit ?

     这里看到有一个cross join ,看见cross join就说明要生成笛卡尔积,这样会非常大的影响效率,

    经过排查,发现只有order by的时候有用到了showimage2_,所以猜测是order by的问题,看下怎么生成的order by

    Pageable pageable = new PageRequest(page, rows, Direction.DESC, "showImage.createTime");//注意这里的条件
    List<ShowImage> result = this.markDao.findMarkImages(marktype, datamId, pageable);

     这里使用了join的表进行排序,所以才出现了cross join

     将这里改成用主表的createTime进行排序

    Pageable pageable = new PageRequest(page, rows, Direction.DESC, "createTime");

    生成的sql立马就变了:

    select showimage1_.id as id1_25_, showimage1_.create_time as create_t5_25_, showimage1_.image_url as image_ur8_25_, showimage1_.position as positio14_25_ 

    from mq_mark markmodel0_ inner join mq_showpic showimage1_ on markmodel0_.show_id=showimage1_.id

    where markmodel0_.type=? and markmodel0_.datam_id=?

    group by showimage1_.id order by markmodel0_.create_time desc limit ?

    不在有cross join了

  • 相关阅读:
    day19.re正则表达式
    day18.os模块 对系统进行操作
    day17.json模块、时间模块、zipfile模块、tarfile模块
    day16.内置方法与模块
    day15.递归函数
    day14.推导式与生成器
    LeetCode-Permutations II
    LeetCode-Permutations
    LeetCode-Partition List
    LeetCode-Substring with Concatenation of All Words
  • 原文地址:https://www.cnblogs.com/lic309/p/4980281.html
Copyright © 2020-2023  润新知