最近一直在用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了

posted on 2015-11-20 11:48  大招无限  阅读(2107)  评论(0编辑  收藏  举报