效果图
这几天自己在用SSH做项目 来实践前一段实践的学习 在最重要的模块里遇到了两个难题
一个就是实现动态的从数据库里 提取字段 然后产生动态的 关联下拉菜单
令一个就是 用Struts来实现多文件上传 这两个问题折腾了我3天 今天终于搞好了 一看google的搜索栏
下面有好几百条 ^_^ 还好我都找到了有用的信息
第一个问题的解决
首先是Category这个POJO 是自身关联的
hbm如下
<?
xml version="1.0"
?>
<!
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
<
hibernate-mapping
>
<
class
name
="com.ergal.hibernate.Category"
table
="CATEGORIES"
lazy
="true"
>
<
id
name
="id"
type
="long"
column
="ID"
>
<
generator
class
="native"
/>
</
id
>
<
property
name
="name"
type
="string"
>
<
column
name
="NAME"
length
="15"
/>
</
property
>
<
set
name
="childCategories"
cascade
="save-update"
inverse
="true"
>
<
key
column
="CATEGORY_ID"
/>
<
one-to-many
class
="com.ergal.hibernate.Category"
/>
</
set
>
<
many-to-one
name
="parentCategory"
column
="CATEGORY_ID"
class
="com.ergal.hibernate.Category"
/>
</
class
>
</
hibernate-mapping
>
POJO就不列了 主要是Dao和DaoService
先构造一个常用的工具类 用来获取bean
package
com.ergal.hibernate;
import
org.springframework.context.support.AbstractApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public
class
AppContext
...
{ private static AppContext instance; private AbstractApplicationContext appContext; public synchronized static AppContext getInstance() ... { if (instance == null ) ... { instance = new AppContext(); } return instance; } private AppContext() ... { this .appContext = new ClassPathXmlApplicationContext( " beans-config.xml " ); } public AbstractApplicationContext getAppContext() ... { return appContext; } }
Dao的接口
ICategory.java
package
com.ergal.hibernate;
import
java.util.List;
public
interface
ICategory
...
{ public List getOneCatrgoriesByparentCategoryId( long id); public List getSubCatrgoriesByparentCategoryId( long id); public List getSubCatrgoriesBySubCategoryId( long id); public List getCatrgoriesById( long id); }
Dao
package
com.ergal.hibernate;
import
java.util.List;
import
org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public
class
CategoryDao
extends
HibernateDaoSupport
implements
ICategory
...
{ public List getOneCatrgoriesByparentCategoryId( long id) ... { return getHibernateTemplate().find( " from Category as c where c.parentCategory.id= " + null ); } public List getSubCatrgoriesByparentCategoryId( long id) ... { return getHibernateTemplate().find( " from Category as c where c.parentCategory.parentCategory.id= " + null ); } public List getSubCatrgoriesBySubCategoryId( long id) ... { return getHibernateTemplate().find( " from Category as c where c.parentCategory.parentCategory.parentCategory.id= " + null ); } public List getCatrgoriesById( long id) ... { return getHibernateTemplate().find( " from Category as c where c.id= " + id); } }
因为在页面中没有一个数据是静态的 包括最上层的分类也是动态的 因为很可能以后对Category的字段重新设置
这样页面就根本不用修改 全是动态获取的 方法就是查找 父Category 的ID为null 以此类推
页面部分
还没有做进一步的封装 所以有些杂乱
<%
...
@ page language = " java " pageEncoding = " GBK " import = " com.ergal.hibernate.*,java.util.* "
%>
<%
...
@ taglib uri = " /tags/struts-html " prefix = " html "
%>
<%
...
@ taglib uri = " /tags/struts-bean " prefix = " bean "
%>
<%
...
@ taglib uri = " /tags/c.tld " prefix = " c "
%>
<%
...
String path = request.getContextPath(); String basePath = request.getScheme() + " :// " + request.getServerName() + " : " + request.getServerPort() + path + " / " ;
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
<
title
>
My JSP 'addpackage.jsp' starting page
</
title
>
</
head
>
<
body
>
<%
...
List resultone = ((ICategory)AppContext.getInstance().getAppContext().getBean( " categoryDaoProxy " )) .getOneCatrgoriesByparentCategoryId( new Long ( 0 )); int onesize = resultone.size(); Category[] cateone = new Category[onesize]; int ik = 0 ; for (Iterator it = resultone.iterator(); it.hasNext();) { cateone[ik] = (Category)it.next(); ik ++ ; } request.setAttribute( " cateone " , cateone);
%>
<%
...
List resultmusic = ((ICategory)AppContext.getInstance().getAppContext().getBean( " categoryDaoProxy " )) .getSubCatrgoriesByparentCategoryId( new Long ( 1 )); int msize = resultmusic.size(); Category[] catemusic = new Category[msize]; int im = 0 ; for (Iterator it = resultmusic.iterator(); it.hasNext();) { catemusic[im] = ((Category)it.next()); im ++ ; } request.setAttribute( " catemuisc " , catemusic);
%>
<%
...
List resultsub = ((ICategory)AppContext.getInstance().getAppContext().getBean( " categoryDaoProxy " )) .getSubCatrgoriesBySubCategoryId( new Long ( 1 )); int subsize = resultsub.size(); Category[] catesub = new Category[subsize]; int is = 0 ; for (Iterator it = resultsub.iterator(); it.hasNext();) { catesub[ is ] = ((Category)it.next()); is ++ ; } request.setAttribute( " catesub " , catesub);
%>
<
script
type
="text/javascript"
>
...
var onecount; onecount = 0 ; submusic = new Array(); <% for ( int i = 0 ; i < msize; i ++ ) ... { %> submusic[ <%= i %> ] = new Array( " <%=catemusic[i].getName()%> " , " <%=catemusic[i].getId()%> " , " <%=catemusic[i].getParentCategory().getId()%> " ); <% } %> onecount =<%= msize %> ; <!-- 决定select显示的函数 --> function changelocation(locationid) ... { document.myform.level2.length = 0 ; var locationid = locationid; var i; var j = 1 ; var optb = new Option(); optb.text = " 二级分类 " ; document.myform.level2.options[ 0 ] = optb; for (i = 0 ;i < onecount; i ++ ) ... { if (locationid == submusic[i][ 2 ]) ... { var opt = new Option(); opt.text = submusic[i][ 0 ]; opt.value = submusic[i][ 1 ]; document.myform.level2.options[j] = opt; j ++ ; } } } var twocount; twocount = 0 ; subsub = new Array(); <% for ( int i = 0 ; i < subsize; i ++ ) ... { %> subsub[ <%= i %> ] = new Array( " <%=catesub[i].getName()%> " , " <%=catesub[i].getId()%> " , " <%=catesub[i].getParentCategory().getId()%> " ); <% } %> twocount =<%= subsize %> ; <!-- 决定select显示的函数 --> function changelocationsub(locationid) ... { document.myform.level3.length = 0 ; var locationid = locationid; var i; var j = 1 ; var optb = new Option(); optb.text = " 三级分类 " ; document.myform.level3.options[ 0 ] = optb; for (i = 0 ;i < twocount; i ++ ) ... { if (locationid == subsub[i][ 2 ]) ... { var opt = new Option(); opt.text = subsub[i][ 0 ]; opt.value = subsub[i][ 1 ]; document.myform.level3.options[j] = opt; j ++ ; } } }
</
script
>
<
hr
>
<
form
action
="test"
name
="myform"
>
<
select
property
="hh"
name
="level1"
onChange
="changelocation(document.myform.level1.options[document.myform.level1.selectedIndex].value)"
size
="1"
>
<
option
selected value
>
一级分类
</
option
>
<
c:forEach
items
="${cateone}"
var
="item"
>
<
option
value
="<c:out value="
${item.id}"
/>
">
<
c:out
value
="${item.name}"
/></
option
>
</
c:forEach
>
</
select
>
<
select
name
="level2"
onChange
="changelocationsub(document.myform.level2.options[document.myform.level2.selectedIndex].value)"
size
="1"
>
<
option
selected value
>
二级分类
</
option
>
</
select
>
<
select
name
="level3"
>
<
option
selected value
>
三级分类
</
option
>
</
select
><
br
>
</
form
>
</
body
>
</
html
>
用来提取一级的种类 并存在request中
<%
List resultone
=
((ICategory)AppContext.getInstance().getAppContext().getBean(
"
categoryDaoProxy
"
)) .getOneCatrgoriesByparentCategoryId(
new
Long(
0
));
int
onesize
=
resultone.size(); Category[] cateone
=
new
Category[onesize];
int
ik
=
0
;
for
(Iterator it
=
resultone.iterator(); it.hasNext();)
...
{ cateone[ik] = (Category)it.next(); ik ++ ; }
request.setAttribute(
"
cateone
"
, cateone);
%>
然后用JSTL的标签来迭代
<
select
property
="hh"
name
="level1"
onChange
="changelocation(document.myform.level1.options[document.myform.level1.selectedIndex].value)"
size
="1"
>
<
option
selected value
>
一级分类
</
option
>
<
c:forEach
items
="${cateone}"
var
="item"
>
<
option
value
="<c:out value="
${item.id}"
/>
">
<
c:out
value
="${item.name}"
/></
option
>
</
c:forEach
>
</
select
>
同理用在获得2级分类的List后用js来产生第二个option
<
script type
=
"
text/javascript
"
>
var
onecount; onecount
=
0
; submusic
=
new
Array();
<%
for
(
int
i
=
0
; i
<
msize; i
++
)
...
{ %> submusic[ <%= i %> ] = new Array( " <%=catemusic[i].getName()%> " , " <%=catemusic[i].getId()%> " , " <%=catemusic[i].getParentCategory().getId()%> " ); <% }
%>
onecount
=<%=
msize
%>
;
<!--
决定select显示的函数
-->
function
changelocation(locationid)
...
{ document.myform.level2.length = 0 ; var locationid = locationid; var i; var j = 1 ; var optb = new Option(); optb.text = " 二级分类 " ; document.myform.level2.options[ 0 ] = optb; for (i = 0 ;i < onecount; i ++ ) ... { if (locationid == submusic[i][ 2 ]) ... { var opt = new Option(); opt.text = submusic[i][ 0 ]; opt.value = submusic[i][ 1 ]; document.myform.level2.options[j] = opt; j ++ ; } } }
var
twocount; twocount
=
0
; subsub
=
new
Array();
<%
for
(
int
i
=
0
; i
<
subsize; i
++
)
...
{ %> subsub[ <%= i %> ] = new Array( " <%=catesub[i].getName()%> " , " <%=catesub[i].getId()%> " , " <%=catesub[i].getParentCategory().getId()%> " ); <% }
%>
twocount
=<%=
subsize
%>
;
<!--
决定select显示的函数
-->
function
changelocationsub(locationid)
...
{ document.myform.level3.length = 0 ; var locationid = locationid; var i; var j = 1 ; var optb = new Option(); optb.text = " 三级分类 " ; document.myform.level3.options[ 0 ] = optb; for (i = 0 ;i < twocount; i ++ ) ... { if (locationid == subsub[i][ 2 ]) ... { var opt = new Option(); opt.text = subsub[i][ 0 ]; opt.value = subsub[i][ 1 ]; document.myform.level3.options[j] = opt; j ++ ; } } }
</
script
>
后面的代码就很简单了
<
select
name
="level2"
onChange
="changelocationsub(document.myform.level2.options[document.myform.level2.selectedIndex].value)"
size
="1"
>
<
option
selected value
>
二级分类
</
option
>
</
select
>
<
select
name
="level3"
>
<
option
selected value
>
三级分类
</
option
>
</
select
><
br
>
可以以此类推 构造更多的动态关联下拉菜单