在jsp页面中怎样实现多级分类的显示文章



在jsp页面中怎样实现多级分类的显示文章。

例如:
一级分类1
—该一级分类的二级1
—该一级分类的二级2
—该一级分类的二级3

一级分类2
—该一级分类的二级1
—该一级分类的二级2
—该一级分类的二级3


不是下拉菜单,同时在页面显示分类。
更多 0

一般这种结构都用树来显示, internet上有很多现成的javascript tree.
如果实在想直接用html显示, 那就循环递归输出每一级分类, 不同界别的分类前面加上数量不等(对应level)的空格或其他字符.

可能开始想要描述的不怎么清楚,还有就是childid这个也写错了,应该是他的父级分类,parentid,不是childid的,呵呵。
我自己这样写了一个,但是感觉这样的话,效率要低的多,因为好像要一直查库,每次都要循环一次,如果分类比较多的话,估计就用不了了。

============================================================================
package com.hmilyld.channel;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import com.hmilyld.study.DatabaseBean;

public class ChannelBean {
Connection conn ;
public ChannelBean(){
try {
this.conn=DatabaseBean.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* 查库,得到库中所有分类
*/
public Collection getChannel() throws SQLException{
Collection<Channel> rs = new ArrayList<Channel>();
Statement stm = conn.createStatement();
ResultSet rst = stm.executeQuery(“select * from channel”);
while (rst.next()){
Channel channel = new Channel();
channel.setChannelId(rst.getInt(“id”));
channel.setChannelName(rst.getString(“name”));
channel.setChannelParentId(rst.getInt(“parentid”));
rs.add(channel);
}
conn.close();
return rs;
}

public static void main(String[] args) throws Exception{
ChannelBean channel = new ChannelBean();
Iterator it = channel.getChannel().iterator();
while(it.hasNext()){
Channel chan = (Channel)it.next();
if(chan.getChannelParentId()==0){
int i = chan.getChannelId();
System.out.println(chan.getChannelName()); //打印出最顶级分类
/*
* 打印出顶级分类下的分类,然后调用channelSort
*/
channel.channelSort(it,i);
}
}
}

public void channelSort(Iterator it,int id) throws Exception{
ChannelBean channel = new ChannelBean();
it = channel.getChannel().iterator();
while (it.hasNext()){
Channel chan = (Channel)it.next();
int channelChildId = chan.getChannelParentId();
int channelId = chan.getChannelId();
if(channelChildId==id){
System.out.println(“–”+chan.getChannelName());
/*
* 一直循环调用
*/
channelSort(it,channelId);
}
}
}
}
============================================================================

这样似乎能一直无限分类下去,但是效率好像低的厉害,而且还有一个问题,
就是如果我想按照这种方式显示的话,好像不行。

根目录1
–子目录1
—-子目录11
–子目录2

因为在后面的循环调用的时候,就都按照System.out.println(“–”+chan.getChannelName());
这一句打印出来了,这应该怎么办?

希望高人指点一下,5.1什么都没弄,就整这个东西了,郁闷.- -#

首先你在main方法中调用了getChannel()方法,已经把所有的分类的取到了。这个时候你应该把List保存起来,而不是每次都到数据库中取。


public class ChannelBean {

private Collection<Channel> channelList = null;

public Collection getChannel() throws SQLException {
if(this.channelList==null) {
channelList = new ArrayList<Channel>();
//原来的哪些,不要return
//建议你用我前面回复的那个SQL语句,取得的结果集已经排序过了

conn.close();
}
return channelList;
}

public static void main(String[] args) {
ChannelBean bean = new ChannelBean();
channelBean.printChannel(0, 0);
}

// 打印
// 不按我的SQL语句排序的情况
public void printChannel(int level, int parentId) {
for(Iterator iter=this.getChannel().iterator(); iter.hasNext();) {
Channel channel = (Channel) iter.next();
if(channel.getParentId()==parentId) {
for(int i=0; i<level; i++) {
System.out.print(“-”);
}
System.out.println(channel.getName());
// 递归调用
printChannel(level + 1, channel.getChannelId());
}
}
}
}

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
Nicholas_Lin
关注
Nicholas_Lin
Nicholas_Lin
等级:Blank
#5 得分:0回复于: 2007-05-05 15:22:03
这种方式的时间复杂度是n*n,所以确实效率很低。如果你用了CONNECT BY那句,时间复杂度可以降低,但是要使用堆栈,只要改写printChannel:

public void printChannel(int level, int parentId) {
Stack stack = new Stack();// 我忘记堆栈的实现类是哪个了
int pid = parentId;
for(Iterator iter=this.getChannel().iterator(); iter.hasNext();) {
Channel channel = (Channel) iter.next();
if(channel.getParentId()==pid) {
for(int i=0; i<level; i++) {
System.out.print(“-”);
}
System.out.println(channel.getName());
} else {
while(pid != channel.getParentId() && !stack.isEmpty())
// 当前pid已没有子节点,从stack出栈
pid = ((Integer) stack.pop()).intValue();
level–;
}
}
// 打印
for(int i=0; i<level; i++) {
System.out.print(“-”);
}
System.out.println(channel.getName());
// 把pid入栈,用当前id替换
stack.push(new Integer(pid));
pid = channel.getChannelId();
level++;
}
}

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
Nicholas_Lin
关注
Nicholas_Lin
Nicholas_Lin
等级:Blank
#6 得分:0回复于: 2007-05-05 15:24:23
……不好意思,上面错了……我汗啊汗
public void printChannel(int level, int parentId) {
Stack stack = new Stack();// 我忘记堆栈的实现类是哪个了
int pid = parentId;
for(Iterator iter=this.getChannel().iterator(); iter.hasNext();) {
Channel channel = (Channel) iter.next();
while(pid != channel.getParentId() && !stack.isEmpty())
// 当前pid已没有子节点,从stack出栈
pid = ((Integer) stack.pop()).intValue();
level–;
}
// 打印
for(int i=0; i<level; i++) {
System.out.print(“-”);
}
System.out.println(channel.getName());
// 把pid入栈,用当前id替换
stack.push(new Integer(pid));
pid = channel.getChannelId();
level++;
}
}
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
kaoloveting
关注
kaoloveting
kaoloveting
等级:Blank
#7 得分:0回复于: 2007-05-05 20:28:48
mark
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
hmilyld
关注
hmilyld
hmilyld
等级:Blank
#8 得分:0回复于: 2007-05-09 13:17:38
/**
* 功能:对栏目进行无限级分类
* 数据库表说明:
*   id:自动编号
*   name:栏目名称
*   parentid:所属父级栏目编号,与id相对应
* @author Hmilyld
* @home  http://www.hmilyld.cn
*/
package com.hmilyld.channel;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import com.hmilyld.study.DatabaseBean;

public class ChannelBean {
Connection conn;

static Collection<Channel> rs = new ArrayList<Channel>();  //静态Collection,只存在一份rs,不需要每次都对数据库进行查询,提高效率

/*
* 得到Connection连接
*/
public ChannelBean() {
try {
this.conn = DatabaseBean.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
}

/*
* 查库,得到库中所有分类,返回Collection
*/
public Collection getChannel() throws SQLException {
Statement stm = conn.createStatement();
ResultSet rst = stm.executeQuery(“select * from channel”);
while (rst.next()) {
Channel channel = new Channel();
channel.setChannelId(rst.getInt(“id”));
channel.setChannelName(rst.getString(“name”));
channel.setChannelParentId(rst.getInt(“parentid”));
rs.add(channel);
}
conn.close();
return rs;
}

public static void main(String[] args) throws Exception {
ChannelBean channel = new ChannelBean();
channel.getChannel();
Iterator it = ChannelBean.rs.iterator();
while (it.hasNext()) {
Channel chan = (Channel) it.next();
if (chan.getChannelParentId() == 0) {
int i = chan.getChannelId();
System.out.println(chan.getChannelName()); // 打印出最顶级分类
/*
* 打印出顶级分类下的分类,然后调用channelSort,传递栏目名称
*/
ChannelBean.channelSort(it, i ,chan.getChannelName());
}
}
}
/*
* 循环得到分类方法
*/
public static void channelSort(Iterator it, int id ,String name) throws Exception {
it = ChannelBean.rs.iterator();
while (it.hasNext()) {
Channel chan = (Channel) it.next();
int channelChildId = chan.getChannelParentId();
int channelId = chan.getChannelId();
if (channelChildId == id) {
System.out.println(name+”–” + chan.getChannelName());
String na = name+”–”+chan.getChannelName();
/*
* 循环调用获取分类名称
*/
channelSort(it, channelId ,na);
}
}
}
}

又换了下,不过你说那个用堆栈的方式,不是太明白.呵呵.:)
先结贴吧,暂时搞定勒,虽然效率低了点