效果图
这几天自己在用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>可以以此类推 构造更多的动态关联下拉菜单
本文介绍了如何使用SSH框架从数据库动态提取字段,创建无限级关联的下拉菜单。通过Category POJO的自身关联,配合Dao和DaoService,实现了根据父Category ID为null查找各级分类。页面部分利用JSTL标签进行迭代,展示一级分类,并通过JS生成二级分类的选项。
2580

被折叠的 条评论
为什么被折叠?



