1. 程式人生 > >級聯選單(Mysql實現)

級聯選單(Mysql實現)

功能描述

  • 實際上級聯選單可能在很多情況下出現,例如:在設定地址的時候後,由使用者先設定省份,而後再根據省份生出對應的城市資訊.
  • 實現無限極力按選單選擇
  • 例如有使用者自己設定要生成幾級選單

資料庫設計

-- 刪除原有的資料表
DROP TABLE IF EXISTS menu;
-- 建立新的資料表
CREATE TABLE menu(
  mid     INT   AUTO_INCREMENT,
  title   VARCHAR(200),
  fmid  INT,
  CONSTRAINT pk_mid2 PRIMARY KEY(mid),
  CONSTRAINT
fk_fmid FOREIGN KEY(fmid) REFERENCES menu(mid) ON DELETE CASCADE ); -- 測試資料:一級選單 INSERT INTO menu(title)VALUES('家居生活'); INSERT INTO menu(title)VALUES('電腦辦公'); INSERT INTO menu(title)VALUES('糧油'); INSERT INTO menu(title)VALUES('圖書'); INSERT INTO menu(title)VALUES('箱包服飾'); -- 二級選單 INSERT INTO menu(
title,fmid)VALUES('鍋',1); INSERT INTO menu(title,fmid)VALUES('碗',1); INSERT INTO menu(title,fmid)VALUES('瓢',1); INSERT INTO menu(title,fmid)VALUES('拖布',1); INSERT INTO menu(title,fmid)VALUES('遊戲周邊',2); INSERT INTO menu(title,fmid)VALUES('整機',2); INSERT INTO menu(title,fmid)VALUES('數碼配件',2); INSERT INTO
menu(title,fmid)VALUES('糧油',3); INSERT INTO menu(title,fmid)VALUES('零食',3); INSERT INTO menu(title,fmid)VALUES('啤酒飲料',3); INSERT INTO menu(title,fmid)VALUES('計算機圖書',4); INSERT INTO menu(title,fmid)VALUES('Java入門到跑路',4); INSERT INTO menu(title,fmid)VALUES('影視',4); INSERT INTO menu(title,fmid)VALUES('旅行包',5); INSERT INTO menu(title,fmid)VALUES('棉衣',5); INSERT INTO menu(title,fmid)VALUES('睡衣',5); INSERT INTO menu(title,fmid)VALUES('雨衣',5); -- 測試資料,三級選單 INSERT INTO menu(title,fmid) VALUES('不粘鍋',6); INSERT INTO menu(title,fmid) VALUES('平底鍋',6); INSERT INTO menu(title,fmid) VALUES('砂鍋',6); INSERT INTO menu(title,fmid) VALUES('刷鍋',6); INSERT INTO menu(title,fmid) VALUES('不鏽鋼',7); INSERT INTO menu(title,fmid) VALUES('銀碗',7); INSERT INTO menu(title,fmid) VALUES('湯勺',8); INSERT INTO menu(title,fmid) VALUES('木勺',8); INSERT INTO menu(title,fmid) VALUES('普通拖把',9); INSERT INTO menu(title,fmid) VALUES('選裝拖把',9); INSERT INTO menu(title,fmid) VALUES('遊戲',10);
  • 無線級別的選單的處理,關鍵體現在這個父的選單項上,但是雖然資料庫是無限的,但是絕不可能在程式中實現無限.
  • 在這種情況下要想實現資訊的操作,唯一的用法只能夠通過過Ajax非同步處理操作完成.

後臺業務實現

  • 定義Menu,java程式類
package mao.shu.vo;

import java.io.Serializable;

public class Menu implements Serializable {
    private String mid;
    private String title;
    //表示父選單
    private Menu fmenu;

    public String getMid() {
        return mid;
    }

    public void setMid(String mid) {
        this.mid = mid;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Menu getFmenu() {
        return fmenu;
    }

    public void setFmenu(Menu fmenu) {
        this.fmenu = fmenu;
    }
}

  • 定義ImemberDAO.java程式類
package mao.shu.dao;

import mao.shu.vo.Menu;

import java.util.List;

public interface IMenuDAO {
    /**
     * 列出所有1級選單,列出的所有1級選單中fmenu一定為null
     * @return
     */
    public  List<Menu> findAll();

    /**
     *根據父選單id,列出此id下的所有子選單
     * @return
     */
    public List<Menu> findAllSub(String fmid);

}

  • 定義MenuDAOImple.java程式類
package mao.shu.dao.imple;

import mao.shu.dao.IMenuDAO;
import mao.shu.vo.Menu;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class MenuDAOImpl implements IMenuDAO {
    private Connection conn;
    private PreparedStatement pstm;
    public MenuDAOImpl(Connection conn){
        this.conn = conn;
    }

    @Override
    public List<Menu> findAll()throws SQLException {
        List<Menu> menus = new ArrayList<Menu>();
        String sql = "SELECT mid,title FROM menu WHILE fmid IS NOLL";
        this.pstm = this.conn.prepareStatement(sql);
        ResultSet rest = this.pstm.executeQuery();
        while(rest.next()){
            Menu vo = new Menu();
            vo.setMid(rest.getString(1));
            vo.setTitle(rest.getString(2));
            menus.add(vo);
        }
        return menus;
    }

    @Override
    public List<Menu> findAllSub(String fmid) throws SQLException{
        List<Menu> menus = new ArrayList<Menu>();
        String sql = "SELECT mid,title FROM menu WHILE fmid=?";
        this.pstm = this.conn.prepareStatement(sql);
        this.pstm.setString(1,fmid);
        ResultSet rest = this.pstm.executeQuery();
        while(rest.next()){
            Menu vo = new Menu();
            vo.setMid(rest.getString(1));
            vo.setTitle(rest.getString(2));
            menus.add(vo);
        }
        return menus;
    }
}

  • 定義DAOFactory.java類,DAO工廠類用於建立DAO介面子類物件
package mao.shu.factory;

import mao.shu.dao.IMemberDAO;
import mao.shu.dao.IMenuDAO;
import mao.shu.dao.imple.MemberDAOImpl;
import mao.shu.dao.imple.MenuDAOImpl;

import java.sql.Connection;

public class DAOFactory {
    public static IMemberDAO newMemberDAO(Connection conn){
        return new MemberDAOImpl(conn);
    }
    public static IMenuDAO getMenuDAO(Connection conn){
        return new MenuDAOImpl(conn);

    }
}

  • 在IMenuService介面中定義兩個方法,也是列出一級選單和二級選單
package mao.shu.service;

import mao.shu.vo.Menu;

import java.util.List;

public interface IMenuService {
    public List<Menu> findAll()throws Exception;
    public List<Menu> findAllSub(String fmid)throws Exception;
}

  • 定義MenuServiceImpl.java類
package mao.shu.service.impl;

import mao.shu.dao.IMenuDAO;
import mao.shu.dbc.DatabaseConnection;
import mao.shu.factory.DAOFactory;
import mao.shu.service.IMenuService;
import mao.shu.vo.Menu;

import java.util.List;

public class MenuServiceImpl implements IMenuService {
    private DatabaseConnection dataConn  = new DatabaseConnection();
    @Override
    public List<Menu> findAll() throws Exception {
        try{
            return DAOFactory.getMenuDAO(dataConn.getConnection()).findAll();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            dataConn.getConnection().close();
        }
        return null;
    }

    @Override
    public List<Menu> findAllSub(String fmid) throws Exception {
        try{
            return DAOFactory.getMenuDAO(dataConn.getConnection()).findAllSub(fmid);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            dataConn.getConnection().close();
        }
        return null;
    }
}

  • 定義ServiceFactory.java程式類
package mao.shu.factory;

import mao.shu.service.IMemberService;
import mao.shu.service.IMenuService;
import mao.shu.service.impl.MemberServiceImpl;
import mao.shu.service.impl.MenuServiceImpl;

public class ServiceFactory {
    public static IMemberService getMemberService(){
        return new MemberServiceImpl();
    }
    public static IMenuService getMenuService(){
        return new MenuServiceImpl();
    }
}

控制層實現

  • 本次的操作將採用全部的一步的通訊形式.所以對於Servlet程式而言,可以將資料裝換為XML格式.
  • 使用DOM4j開發包操作XML
  • 如果最終Servlet生成資料為XML格式,必須將MIME型別設定為xml
  • 再生成xml元素的時候,建議資料都已元素的形式出現
  • 建立MenuServlet.java程式類
package mao.shu.servlet;


import mao.shu.factory.ServiceFactory;
import mao.shu.vo.Menu;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;

@WebServlet("/MenuServlet/*")
public class MenuServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        String uri = req.getRequestURI();
        String status = uri.substring(uri.lastIndexOf("/")+1);
        if(status != null){
            try {
                Method method = this.getClass().getMethod(status,HttpServletRequest.class,HttpServletResponse.class);
                method.invoke(this,req,resp);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
    public void listSub(HttpServletRequest req, HttpServletResponse resp)  {
        resp.setContentType("text/xml");
        int fmid = Integer.parseInt(req.getParameter("fmid"));
        try {
            List<Menu> all = ServiceFactory.getMenuService().findAllSub(fmid);
            Document document = DocumentHelper.createDocument();
            Element menus = document.addElement("menus");
            Iterator<Menu> iterator = all.iterator();
            while(iterator.hasNext()){
                Menu vo = iterator.next();
                Element menu = menus.addElement("menu");
                Element mid = menu.addElement("mid");
                Element title = menu.addElement("title");
                mid.addText(String.valueOf(vo.getMid()));
                title.addText(vo.getTitle());
            }
            OutputFormat outputFormat = OutputFormat.createPrettyPrint();
            outputFormat.setEncoding("utf-8");
            XMLWriter xmlWriter = new XMLWriter(resp.getWriter());
            xmlWriter.write(document);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public void listAll(HttpServletRequest req