`

c标签foreach中循环split的值

    博客分类:
  • JSP
阅读更多

最近做项目碰到一个问题,基本业务是这样子的:

有两张表,table1和table2,table2用来记录上传的文件信息如文件名称、文件地址等,table1用来记录文件上传的记录如上传人,上传时间等描述信息,它有一个字段用于保存文件序号(即table2的主键序号),可能是一个也可能是多个,现在需要将文件上传的信息及文件信息以文件为单位展示出来。

 

基本业务挺简单的,但对于习惯了用JSTL展示数据的我来说,处理起来就不那么简单了,以下为处理过程。

 

1、先建立基本数据用于测试

a、先建文件表:table2,

CREATE TABLE [dbo].[table2](
	[field1] [int] IDENTITY(1,1) NOT NULL,
	[field2] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[field3] [varchar](100) COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_table2] PRIMARY KEY CLUSTERED 
(
	[field1] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'主键序号' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'table2', @level2type=N'COLUMN', @level2name=N'field1'

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'文件名称' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'table2', @level2type=N'COLUMN', @level2name=N'field2'

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'文件路径' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'table2', @level2type=N'COLUMN', @level2name=N'field3'

--insert基础数据
INSERT INTO table2(field2,field3) VALUES('测试文件1','D:/temp/test1.pdf')
INSERT INTO table2(field2,field3) VALUES('测试文件2','D:/temp/test2.pdf')
INSERT INTO table2(field2,field3) VALUES('测试文件3','D:/temp/test3.pdf')
INSERT INTO table2(field2,field3) VALUES('测试文件4','D:/temp/test4.pdf')
INSERT INTO table2(field2,field3) VALUES('测试文件5','D:/temp/test5.pdf')
INSERT INTO table2(field2,field3) VALUES('测试文件6','D:/temp/test6.pdf')

b、再建文件上传记录表table1:

CREATE TABLE [dbo].[table1](
	[field1] [int] IDENTITY(1,1) NOT NULL,
	[field2] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,
	[field3] [varchar](100) COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED 
(
	[field1] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'主键序号' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'table1', @level2type=N'COLUMN', @level2name=N'field1'

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'文件序号(即table2的主键序号),多个时以英文半角的逗号分开' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'table1', @level2type=N'COLUMN', @level2name=N'field2'

GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'描述' ,@level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'table1', @level2type=N'COLUMN', @level2name=N'field3'

--insert基础数据
INSERT INTO table1(field2,field3) VALUES('1','描述1')
INSERT INTO table1(field2,field3) VALUES('1,2,3,4','描述2')
INSERT INTO table1(field2,field3) VALUES('5,6,3','描述3')
INSERT INTO table1(field2,field3) VALUES('4,6','描述4')
INSERT INTO table1(field2,field3) VALUES('1,2,3,4,5','描述5')
INSERT INTO table1(field2,field3) VALUES('2','描述6')

 

2、写SQL语句将两个表中的信息弄到一起

select t1.field1 as '主键序号',t1.field3 as '描述',t1.field2 as '文件序号',
--len(t1.field2)-len(replace(t1.field2,',','')):为0时表示有一个文件 为1时表示有2个,依次类推
len(t1.field2)-len(replace(t1.field2,',','')) as '文件数量',
--有超过1个的文件时使用*号将文件名称分开
(case when (len(t1.field2)-len(replace(t1.field2,',','')))>0 then (select '*'+t2.field2 from table2 as t2 where CHARINDEX(','+LTRIM(t2.field1)+',',','+t1.field2+',')>0  for xml path(''))else (select t2.field2 from table2 as t2 where CHARINDEX(','+LTRIM(t2.field1)+',',','+t1.field2+',')>0 ) end) as '文件名称'
from table1 as t1 ; 

结果如下:

 

3、使用java代码进行查询

代码我也不写了,就说一下获取到的结果名称和格式:List<Object[]> fileList

 

4、页面展示:

先进行简单输出

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<table border="1">
<tr>
	<td>主键序号</td>
	<td>描述</td>
	<td>文件序号</td>
	<td>文件数量</td>
	<td>文件名称</td>
</tr>
<c:forEach items="${fileList }" var="file">
	<tr>  
		<td>{file[0]}</td><!--主键序号 -->
		<td>{file[1]}</td><!--描述-->
		<td>{file[2]}</td><!--文件序号-->
		<td>{file[3]}</td><!--文件数量-->
		<td>{file[4]}</td><!--文件名称-->
	</tr>
</c:forEach>
</table>

输出结果与上图相同,这里就不截图了。

 

很明显,这样子的结果是以table1的数据为主,而不是以文件为单位,一个文件一个文件的输出。以上图中的描述2为例子,若以table1为主,那么就是显示那一条记录,若是为文件为单位,应该是4条数据。因此需要根据文件序号或文件名称进行截取,然后再循环,这里需要用到fn标签里边的split函数。修改后的代码如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<table border="1">
<tr>
	<td>主键序号</td>
	<td>描述</td>
	<td>文件序号</td>
<!--	<td>文件数量</td>-->
	<td>文件名称</td>
</tr>
<c:forEach items="${fileList }" var="file">
	<c:choose>
		<c:when test="${file[3]>0 }"><!--file[3]表示文件数量,为0时说明有一个文件,0即有多个文件 -->
	 		<c:set value="${fn:split(file[4], '*') }" var="names" /><!--file[4]表示文件名称,以*号隔开 -->
	 		<c:set value="${fn:split(file[2], ',') }" var="ids" /><!--file[2]表示文件序号,以,号隔开 -->
			<c:forEach items="${names }" var="name" varStatus="indexes"><!--循环文件名称 -->
				<tr>
					<td>{file[0]}</td><!--主键序号 -->
					<td>{file[1]}</td><!--描述-->
					<td>{ids[indexes.index]}</td><!--文件序号-->
<!--				<td>{file[3]}</td>文件数量-->
					<td>{name}</td><!--文件名称-->
				</tr>
			</c:forEach>
		</c:when>
		<c:otherwise><!--说明只有一个,那么直接显示即可 -->
			<tr>
				<td>{file[0]}</td><!--主键序号 -->
				<td>{file[1]}</td><!--描述-->
				<td>{file[2]}</td><!--文件序号-->
<!--			<td>{file[3]}</td>文件数量-->
				<td>{file[4]}</td><!--文件名称-->
			</tr>
		</c:otherwise>
</c:forEach>
</table>

 

有时候会遇到文件名称过长需要截取的情况,处理如下

<c:set value="22" var="wordNum"/> <!---定义变量,用来说明要截取的字数--->
<!--<td>{name}</td>文件名称-->
<!--文件名称-->
<td>
	${fn:substring(name,0,(fn:length(name)>wordNum?wordNum:fn:length(name)))}
	<c:if test="${fn:length(name)>wordNum }">...</c:if>
</td>

最后,祝大家好运!

 

  • 大小: 9 KB
分享到:
评论

相关推荐

    c:forEach标签的使用祥解

    cforEach标签的使用祥解。c:forEach用法的详细介绍。

    超全面javaweb教程28天第11,12天 7 forEach中的循环状态变量

    超全面javaweb教程28天第11,12天_7_forEach中的循环状态变量

    foreach循环

    利用foreach循环显示数组所有元素,对foreach循环进行更深了解

    使用foreach循环

    java中foreach循环的使用方法!

    jstl标签 forEach详解

    jstl forEach标签用法详解,里面介绍地非常详细,有实例说明的。

    JS forEach跳出循环2种实现方法

    假设当我们只需知道某个数组有没有某个属性,如果找到了直接跳出循环,省略掉剩下的循环步骤是较优化的操作,但是for中是可以利用break跳出循环,但break在forEach中无效,那么forEach能不能跳出循环呢?当然是可以...

    C-FOREACH用法

    C-FOREACH用法需要遍历的集合放到items中,然后定义一个temp为每次应用到的集合元素,然后设置起步值及叠加步数

    c:foreach的各种用法

    &lt;c:foreach 中各种标签属性的用法,特别是varStatus的巧用

    js中Array.forEach跳出循环的方法实例.docx

    js中Array.forEach跳出循环的方法实例.docx

    <c:forEach>/jstl-1.2

    为循环控制,它可以将集合(Collection)中的成员循序浏览一遍。运作方式为当条件符合时,就会持续重复执行&lt;c:forEach&gt;的本体内容。 语法 语法1:迭代一集合对象之所有成员 &lt;c:forEach [var="varName"] items=...

    C#中foreach循环对比for循环的优势和劣势

    本文将详细给大家关于C#中foreach循环对比for循环的优势和劣势,下面话不多说了,来一起看看详细的介绍吧。 一、foreach循环的优势 C#支持foreach关键字,foreach在处理集合和数组相对于for存在以下几个优势: 1、...

    <php+mysql>PHP脚本条件判断,foreach循环,以及粘性表单

    &lt;php+mysql&gt;PHP脚本条件判断,foreach循环,以及粘性表单

    使用foreach循环遍历数组的其它例子(附详细步骤).txt

    在每次循环中,我们使用echo语句输出当前元素的值,并在其后面添加一个换行符" "。最后,我们在浏览器中打开fruits.php文件,可以看到页面上显示了每个水果的名称,每个名称占一行。 这个代码的意义在于展示了...

    使用foreach循环遍历数组的用法例子(附详细步骤).txt

    在每次循环中,我们使用echo语句输出当前元素的值,并在其后面添加一个换行符" "。最后,我们在浏览器中打开fruits.php文件,可以看到页面上显示了每个水果的名称,每个名称占一行。 这个代码的意义在于展示了...

    JMETER ForEach循环控制器

    ForEach 循环控制器是比较重要的逻辑控制器,但是一般不会单独使用需跟用户自定义的变量组件一起使用,ForEach 循环控制器从用户定义的变量中读取一系列相关的变量。该控制器下的采样器或控制器都会被执行一次或多...

    Delphi Foreach循环的用法实例.rar

    Delphi Foreach循环的用法实例,演示如何使用For Each生成循环,用赋值于文本框控件中,程序试图使用多种方式生成Foreach,并最终清除它。本示例面向Delphi基础学者,了解Delphi基础知识的一些应用。

    C#在foreach遍历删除集合中元素的三种实现方法

    在foreach中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,从而导致在foreach中删除元素时会抛出异常。 集合已修改;可能无法执行枚举操作。 方法一:采用for循环,并且从尾到头遍历 如果...

    foreach循环实例

    自己写的foreach,绝对可以用。 namespace for_reach循环实例 { class Program { static void Main(string[] args) { int[] a={1,2,3,4,5}; foreach (int x in a)

    php foreach循环中使用引用的问题

    看代码,再做解释复制代码 代码如下:&lt;... 在foreach循环中,当循环结束后,$key和$val变量都不会自动释放掉。值会被保留下来。当foreach使用引用的情况下,会出现如下的情况,需要注意。复制代码

    foreach.js低版本IE数组和HTMLCollection元素集合不兼容forEach循环遍历的处理方法

    低版本IE数组和HTMLCollection元素集合不兼容forEach循环遍历的处理方法 原生JavaScript通过name获取dom元素得到的是 HTMLCollection元素集合 要想循环遍历可以用forEach,但是在低于ie9的版本下不兼容 var list...

Global site tag (gtag.js) - Google Analytics