第一次做项目碰到的一个坑之left outer join 左外连接

这段时间在做一个叫“香港自由行”的项目,是一个旅游网站。我负责的模块是景点页面,主要是星级评分、评论、查附件5个景点。功能很简单,做的时候也没啥大问题。

但是,某天,在我提交确认无误提交后,发现另外一人做的上传景点功能一直报500。遂找了那位队友问了一下,原来是他之前改了数据库表的两个字段的类型但是我没更新么,于是删了数据库表更新跑了一下项目……然后问题就这么来了

查询景点评论的时候每条评论都查了四遍= =||| 而且因为用了hibernate的分页查询,每次查10条记录,也导致了部分评论因此没查询到(如下图)

然后我凌乱了QAQ 提交之后没改过代码啊!!怎么突然就出问题……T T

于是开始debug,从Controller一直debug到service层,后来发现执行完dao层的方法后拿到的List里面的数据已经重复了。

当时用的dao层是ken哥写好的,也没去怀疑是dao层出问题了,所以debug了一晚上,改了无数种形式,还是没行。

代码:

Service层:

Scenery scenery = this.getScenery(scenery_id);  
Criterion cirterion = Restrictions.eq("scenery", scenery);  
currentPageSceneryCommentList = sceneryCommentDao.findByPageSize(firstRecord, pageSize, Order.desc("date"), cirterion);

dao层:

@SuppressWarnings("unchecked")
@Override
public List<T> findByPageSize( int first, int pageSize, Order orderType,Criterion... criterions)
{
	Session session = sessionFactory.getCurrentSession();
	Criteria criteria = session.createCriteria(entityClass)
				   .setFirstResult(first)
			  	   .setMaxResults(pageSize);
	if(orderType != null) 
		criteria.addOrder(orderType);
		
	for(Criterion criterion : criterions)
	{
		criteria.add(criterion);
	}	
	return criteria.list();
}

之后实在没办法,于是找华哥T^T……华哥说:“你的那个评论表叫业生重新设计,把那个集合list改为set就不会有这样的问题了。至于dao层那里用list为什么会出错,我暂时也猜不到”

然后找了业生……评论表没改,讨论了很久为什么会这样,这时候,起鹏过来了……问:“什么问题搞了这么久啊?”

结果起鹏一语破的的说:“左外关联,我以前做督导的时候也遇到过这个问题,dao层的方法有问题。”因此评论表关联了其它表,才出现的这种问题……默默地抹一把泪,坑了一晚上居然是dao层出错么!

然后起鹏在dao的方法上加了点东西,曰:“这样就能把重复的去掉”,如下:

Criteria criteria = session.createCriteria(entityClass)
			   .setFirstResult(first)
			   .setMaxResults(pageSize)
			   .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
满心欢喜地刷新页面~结果……

重复的确实去掉了,但是查询的时候仍然有查了……部分评论没有查询到的情况依然存在,每页也显示不到10条评论。


然后又尝试了将

.setMaxResults(pageSize)
这一行放最后,显然是没成功,因为不存在优先级问题。


最后得出的结论是……还是自己拼hql语句算了T.T

dao层:

public List<SceneryComment> findSceneryCommentByPageSize(int firstRecord, int pageSize, String scenery_id)
{
	Session session = sessionFactory.getCurrentSession();
	String hql = "from SceneryComment sc where sc.scenery.scenery_id='"+scenery_id+"'order by sc.date desc";
	Query q = session.createQuery(hql).setFirstResult(firstRecord).setMaxResults(pageSize);
	List<SceneryComment> list = new ArrayList<SceneryComment>();
	list = q.list();
	return list;
}
这么一来问题是解决了,但是……不甘心啊不甘心!捉摸着怎么改dao层或者调个其它的方面不成么?!

第二天下午又尝试了下dao层的其它方法,还真给发现了一个……

service层:

Scenery scenery = this.getScenery(scenery_id);
DetachedCriteria criteria = DetachedCriteria.forClass(SceneryComment.class)
					    .add(Restrictions.eq("scenery", scenery))
					    .setFetchMode("scenery", FetchMode.LAZY)
					    .addOrder(Order.desc("date"));
currentPageSceneryCommentList = sceneryCommentDao.findByCriteria(criteria, firstRecord, pageSize);
dao层:

@SuppressWarnings("unchecked")
@Override
public List<T> findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults)
{
	Session session = sessionFactory.getCurrentSession();		
	Criteria executableCriteria = criteria.getExecutableCriteria(session);
	if (firstResult >= 0) {
		executableCriteria.setFirstResult(firstResult);
	}
	if (maxResults > 0) {
		executableCriteria.setMaxResults(maxResults);
	}
	return executableCriteria.list();
}
关键在于
.setFetchMode("scenery", FetchMode.LAZY)
这一句吧


不过最后提交上去的还是用了自己拼hql语句的方法。

经过这件事,其实觉得还是自己拼sql语句的好。

即使是用hibernate,因为要开启事务,而且hql最终还是要转换成sql,速度上没有原始的sql语句来得快。

在做大作业的时候用的sql,后来暑假学了三大框架,改大作业的时候用了hql,小伙伴们也一众觉得hql没有sql快。


以上只是为了记录一下第一次做项目被坑的经历lol


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值