效果图
这几天自己在用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 >
后面的代码就很简单了