SSH 多表联合查询结果集如何显示在JSP上

本文只是针对SSH框架下总结的,JSP上的显示使用struts标签与jstl标签。

先说解决思路:A类与B类进行联合查询,并且A类与B类还有一对多的关系。查询出来的结果,分别使用两个List接收。然后创建一个中间类C,此类用来接收A类及B类的集合(即List<B>,这样A类与B类在C类中又有了一对多的关系。),将A类的List中的对象set至C类,与之相对应的B类先添加至一个List中,再将List set至C类。最后在页面上的显示就需要使用jstl标签来解决。

效果图如下所示:


上图中由红色标出的即是B类的数据,其他则是A类的数据。可以看到在页面也是呈现了一对多的关系。

要说明的是,B类中保存了A类的id。这样才能这个字段在查询的时候将两张表关联起来。

hql代码:

query = "from CreateContract c,Item i where c.id = i.contract_id"+" order by c.id desc";

结果集:

List list = this.getList(hql,page.getPageSize(), page.getStartRow());
这个结果集怎么来的,不在本文的讨论当中,我们只需关心怎么处理这个结果集list。

根据之前所说的思路,可以先创建两个List.

List<CreateContract> createContracts = new ArrayList<CreateContract>();

		List<Item> items = new ArrayList<Item>();
然后遍历list集合,分别赋值给上述两个List

for(int i = 0;i<list.size();i++){
			Object[] objs = (Object[]) list.get(i);
			createContracts.add((CreateContract)objs[0]);
			items.add((Item)objs[1]);
		}
因为list是两张表的结果集,因此其中的每一个元素都是由两个类组成,所以在接收的时候需要使用Object数组,然后再进行转换。

其实这样还会有一个问题出现,就是createContracts中会有重复的元素。因为CreateContract是一的一方,因此联合查询出来必然会出现重复的数据。如果不加以处理,在最后页面显示的时候会出现如下情况:

这样看起来就会有点不爽了。于是在createContracts那行代码需稍微修改一下:

List<CreateContract> createContracts = SetUniqueList.decorate(new ArrayList<CreateContract>());
SetUniqueList.decorate()可以去掉重复的元素,想了解的朋友可以查看API。

为了能接收上述两个List中的值,我们可以再创建一个中间类TempClass。此类代码如下:

public class TempClass {

	private List<Item> items;
	private CreateContract createContract;

	public List<Item> getItems() {
		return items;
	}
	public void setItems(List<Item> items) {
		this.items = items;
	}
	public CreateContract getCreateContract() {
		return createContract;
	}
	public void setCreateContract(CreateContract createContract) {
		this.createContract = createContract;
	}
}

然后再创建一个用来接收TempClass的List.

List<TempClass> temps = new ArrayList<TempClass>();

接下来我们只需要对上述两个List进行遍历就差不多了。

//第一层for循环,遍历一的一方createContracts
		for(int i = 0;i<createContracts.size();i++){
			//将结果集set至TempClass中,然后在页面上显示出来。
			TempClass tempClass = new TempClass();			
			//从createContracts中获取createContract
			CreateContract createContract = createContracts.get(i);			
			//将createContract存入至tempClass中
			tempClass.setCreateContract(createContract);			
			//用一个list来接收多个与createContract对应的item
			List<Item> its = new ArrayList<Item>();
			//第二层for循环,遍历多的一方items
			for(int j = 0;j<items.size();j++){
				//从items获取item
				Item item = items.get(j);
				//判断createContract中的id是否与item中的contract_id相等。通过这样比较才能取出与createContract相对应的item。
				if(createContract.getId().equals(item.getContract_id())){
					its.add(item);
				}
			}

			tempClass.setItems(its);
			temps.add(tempClass);	
		}
最后将temps放到reqeust中就可以了。

request.setAttribute("list", temps);
这样,在后台中对于多表查询结果集的处理就完成了。最后就是需要在前台显示了。

这个显示理论上有两种方法。一种是,一的一方的所占用的行数根据其所对应的多的一方的行数来决定。另一种则是,在多的一方中用水平线来分割。本人采用的是第二种方法。

JSP页面上的代码如下:

第一个for循环

<c:forEach items="${list}" var="bean" begin="${index}">


因为CreateContract中的数据是存入到TempClass中的了,于是在jstl中是读取对象中的值,而Item中的数据则需要再次循环一遍。因此数据显示代码如下所示:

<c:out value="${bean.createContract.price_terms}" />
		<td>
			<c:forEach items="${bean.items}" var="items" begin="${index2}" varStatus="status">
									
				<c:if test="${status.count != 1}">
					<hr style="height:1px" color="#CCCCCC"/>
				</c:if>

			<font color="red"><c:out value="${items.item}" escapeXml="true" /></font>
			</c:forEach>
		</td>

注意,这个循环是写在td中的,而不是td外面。同时,我在里面也添加了一条水平线,并且第一条水平线不予以显示出来。这样就呈现出多行的效果了。

至此,多表联合查询结果集在JSP页面上显示的问题得到解决。

最后把后台代码统一贴出来,前三行代码可以忽略。

String countHql = this.getSurveyString(itemid,contract_no,create_date,0);
		String hql = this.getSurveyString(itemid,contract_no,create_date,1);
		//返回分页page bean
		Page page = this.getPage(request, countHql);
		//返回显示数据
		List list = this.getList(hql,page.getPageSize(), page.getStartRow());
		
		//创建中间类TempClass的List。
		List<TempClass> temps = new ArrayList<TempClass>();
		
//		//createContract接收create_contract表中的值
		//去掉重复的元素
		List<CreateContract> createContracts = SetUniqueList.decorate(new ArrayList<CreateContract>());
//		//item接收item表中的值
		List<Item> items = new ArrayList<Item>();
		
		System.out.println("一共有:		"+list.size()+"		记录");
		
		for(int i = 0;i<list.size();i++){
			Object[] objs = (Object[]) list.get(i);
			createContracts.add((CreateContract)objs[0]);
			items.add((Item)objs[1]);
		}
		
		System.out.println("=============	"+createContracts.size()+"	=============");
		System.out.println("=============	"+items.size()+"	=============");
		
		//第一层for循环,遍历一的一方createContracts
		for(int i = 0;i<createContracts.size();i++){
			//将结果集set至TempClass中,然后在页面上显示出来。
			TempClass tempClass = new TempClass();			
			//从createContracts中获取createContract
			CreateContract createContract = createContracts.get(i);			
			//将createContract存入至tempClass中
			tempClass.setCreateContract(createContract);			
			//用一个list来接收多个与createContract对应的item
			List<Item> its = new ArrayList<Item>();
			//第二层for循环,遍历多的一方items
			for(int j = 0;j<items.size();j++){
				//从items获取item
				Item item = items.get(j);
				//判断createContract中的id是否与item中的contract_id相等。通过这样比较才能取出与createContract相对应的item。
				if(createContract.getId().equals(item.getContract_id())){
					its.add(item);
				}
			}

			tempClass.setItems(its);
			temps.add(tempClass);	
		}
		
			
		request.setAttribute("page", page);
		request.setAttribute("list", temps);











  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值