idea从数据库创建一个springboot+bootstarp动态导航

标题idea从数据库创建一个springboot+bootstarp动态导航

一,标题idea新建一个项目

1,new一个项目

我们这里添加一个

2,随便取一个项目名字

请添加图片描述

3. 选中lombok支持,写实体类的时候会用到,简化你的set,get方法的代码量

请添加图片描述

4. 选中web支持,可以打包成一个jar包直接运行

请添加图片描述

5. 选中MySql数据库支持driver

	如果你是其他数据库环境,请选中其他支持库![请添加图片描述](https://img-blog.csdnimg.cn/56b7082cac7241d3afd80d5d56b5d64e.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JyYWluamVhbg==,size_16,color_FFFFFF,t_70)

6. 完成创建工程

请添加图片描述

二,导入strapbootcss和js

1,下载strapbootcss和js

1,从https://getbootstrap.com/的download页面下载,这里版本根据需要瞎子,我这里是最新的,下载的是编译过的,
如果需要源码,请下载Source files
请添加图片描述
2,直接导入cdn加速

  <!-- 新 Bootstrap 核心 CSS 文件 -->
    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

这里我们采用第二方法导入CDN上的css,js文件
拷贝到cps项目里面

三.html从数据库读出数据并填入bootstrap格式的导航中

1,新建一个页面index.html在static目录下面

引入jquery支持,要用ajax获取数据.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-control" content="no-cache">
    <meta http-equiv="Cache" content="no-cache">
    <title>Title</title>
    <!-- 新 Bootstrap 核心 CSS 文件 -->
    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

</head>
<body>
<nav class="navbar navbar-default right" role="navigation">
    <div class="container-fluid">
        <div class="navbar-header">
            <a class="navbar-brand active" href="#">固定导航</a>
        </div>
        <div>
            <ul id='menu' class='nav navbar-nav '> </ul>
        </div>
    </div>
</nav>

<div class="main-content">
    <div class="page-content " id="main"></div>
</div>
</div>


<script src="./js/index.js?v=6"></script>
</body>
</html>

2.新建index.js在static/js/目录下

/*普通json 转成树形json*/
function listToTree(list, pid) {
    var ret = [];//一个存放结果的临时数组
    for (var i in list) {
        if (list[i].parent_id == pid) {//如果当前项的父id等于要查找的父id,进行递归
            list[i].children = listToTree(list, list[i].id);
            ret.push(list[i]);//把当前项保存到临时数组中
        }
    }
    return ret;//递归结束后返回结果
}

var tree;
$(function () {
    $.ajax({
        type: "get",  //请求方式
        url: './nav/list', //加载本地json数据
        dataType: "json",   //请求类型
        success: function (result) {
            var menuData = eval(result);
            tree = listToTree(menuData, 0);//调用函数,传入要转换的普通json和树中顶级元素的pid\
            tree.sort()
            var showMenu = $("#menu");  //获取ul(父节点)的位置
            showTreeFirst(tree, showMenu);
            showTree(tree);
        }
    })
})


/*根据处理过的树形json数据生成一级菜单*/
function showTreeFirst(data,parent) {
    var dataLength = data.length;
    if (dataLength < 7) {//最多生成五个菜单,其余隐藏
        // console.log("dataLength < 6")
        for (var i = 0; i < dataLength; i++) {
            if (data[i].children.length) {//如果有子集
                var html = ' <li class="dropdown"> ' +
                    '<a href="#" data-toggle="dropdown" id="' + data[i].id+ '" data-submenu="" > ' + data[i].nav_name + '<strong class="caret"></strong> </a>' +
                    ' <ul class="dropdown-menu" id="submenu_' + data[i].id + '"></ul> </li>  ';
                console.log(data[i].nav_name);
                parent.append(html);
            } else {
                var html = ' <li> <a href="#" data-toggle="dropdown" data-submenu=""  id="' + data[i].id + '" > ' + data[i].nav_name + ' </a> </li> ';
                parent.append(html);
            }
        }
    } else {//最多生成五个菜单,其余隐藏

        /* 先成前五个菜单*/
        for (var i = 0; i < 5; i++) {
            console.log("data[i].children.length"+data[i].children.length)
            if (data[i].children.length) {//如果有子集
                var html = '  <li class="dropdown">' +
                    ' <a href="#" data-toggle="dropdown"  id="' + data[i].id + '" data-submenu="" > ' + data[i].nav_name + ' </a> ' +
                    '<ul class="dropdown-menu" id="submenu_' + data[i].id + '"></ul> </li>  ';
                parent.append(html);
            } else {
                var html = ' <li> <a href="#" data-toggle="dropdown" data-submenu=""  id="' + data[i].id +'" > ' + data[i].nav_name + ' </a> </li> ';
                parent.append(html);
            }
        }
        /* 生成“更多”按钮*/
        var html = ' <li class="dropdown"> <a href="#" data-toggle="dropdown" data-submenu=""   id="' + data[i].id
            + '" menunav_name="' + data[i].nav_name+'">更多<strong class="caret"></strong> </a> ' +
            '<ul class="dropdown-menu" id="moreDropdownMenu"> </ul> </li>';
            parent.append(html);

        /* 生成“更多”按钮下的其他一级隐藏菜单*/
        for (var i = 5; i < dataLength; i++) {
            if (data[i].children.length) {//如果有子集
                var html = ' <li class="dropdown-submenu"> <a  id="'+ data[i].id +'" >' + data[i].nav_name + '</a> ' + '<ul class="dropdown-menu" id="submenu_' + data[i].id + '"> </ul>'
                $("#moreDropdownMenu").append(html);
            } else {
                var html = '<li><a id="'+data[i].id+'"  >' + data[i].nav_name + '</a> </li>'
                $("#moreDropdownMenu").append(html);
            }
        }

    }


}

/*根据处理过的树形json数据递归生成一级菜单以外的其他菜单*/
function showTree(data) {
    for (var i = 0; i < data.length; i++) {
        if (data[i].children.length) {//如果有子集
            /* 先判断父节点是否存在*/
            if ($("#submenu_" + data[i].parent_id).size() == 0) {
                showTree(data[i].children);//递归调用子集
            } else {
                var html = '<li class="dropdown-submenu">' +
                    ' <a id="'+data[i].id+'" >' + data[i].nav_name + '</a>' +
                    '<ul class="dropdown-menu" id="submenu_'+data[i].id+'"> </ul>'
                $("#submenu_"+data[i].parent_id).append(html);
                showTree(data[i].children);//递归调用子集
            }

        } else {//没有子集直接显示
            var html = '<li><a  id="'+data[i].id+'">'+data[i].nav_name+'</a> </li>'
            $("#submenu_" + data[i].parent_id).append(html);
        }
    }
}


四.从数据库读出数据.

1.修改pom.xml文件,插入支持库

为了防止大家漏掉某个包,我直接把现在的pom文件贴上来.
数据库连接使用了druid+mybatis

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.jean</groupId>
    <artifactId>cps</artifactId>
    <version>1.0</version>
    <name>cps</name>
    <packaging>jar</packaging>
    <description>Company display</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- alibaba的druid数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-maven-plugin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.5.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
        <!-- 解决dto,do,vo转换问题 -->
        <dependency>
            <groupId>net.sf.dozer</groupId>
            <artifactId>dozer</artifactId>
            <version>5.5.1</version>
        </dependency>

    </dependencies>
<repositories>
        <repository>
            <id>alimaven</id>
            <name>Maven Aliyun Mirror</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/central</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
</repositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.5.3</version>
            </plugin>
        </plugins>
    </build>

</project>

2.修改项目配置文件application.yml,如果没有,新建一个.

所在目录如下
请添加图片描述

server:
  port: 80


spring:
  resources:
    static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/templates/,classpath:/mapper/,file:static/
  datasource:
      name: mysql
      type: com.alibaba.druid.pool.DruidDataSource
        #druid相关配置
      druid:
          #监控统计拦截的filters
          filters: stat
          driver-class-name: com.mysql.jdbc.Driver
          #基本属性
          url: jdbc:mysql://192.168.1.5:3306/jinhong?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
          #数据库账号
          username: root
          #数据库密码
          password: 123
          #配置初始化大小/最小/最大
          initial-size: 1
          min-idle: 1
          max-active: 20
          #获取连接等待超时时间
          max-wait: 60000
          #间隔多久进行一次检测,检测需要关闭的空闲连接
          time-between-eviction-runs-millis: 60000
          #一个连接在池中最小生存的时间
          min-evictable-idle-time-millis: 300000
          validation-query: SELECT 'x'
          test-while-idle: true
          test-on-borrow: false
          test-on-return: false
          #打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
          pool-prepared-statements: false
          max-pool-prepared-statement-per-connection-size: 20
  thymeleaf:
            prefix: classpath:/templates/
            check-template-location: true
            suffix: .html
            encoding: UTF-8
            mode: LEGACYHTML5
            cache: false
  aop:
      auto: true
      proxy-target-class: true
  servlet:
      multipart:
        max-file-size: 10MB
        max-request-size: 100MB


mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: cn.jean.model


#pagehelper
pagehelper:
    helperDialect: mysql
    reasonable: true
    supportMethodsArguments: true
    params: count=countSql
    returnPageInfo: check

logging:
  level:
    cn.jean.dao : DEBUG
    cn.jean.controller : DEBUG

swagger:
  show: true

#工作模式
curvar:
  dev: true

3.写程序的model,dao,server,controller层

NavDomain.java

package cn.jean.model;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor

public class NavDomain {
    /**
     * 主键
     */
    private int id;
    /**
     * url
     */
    private String module;
    /**
     * 导航名字
     */
    private String nav_name;
    /**
     * 图标
     */
    private String icon;
    /**
     * 序列
     */
    private String guide;
    /**
     * 父目录
     */
    private int parent_id;
    /**
     * 类别
     */
    private String type;
    /**
     * 类型
     */
    private int sort;
}

NavDao.java,这里有一个mybatis的mapper需要读入,在配置文件里面记得配置

mybatis:
  mapper-locations: classpath:mapper/*.xml					//配置文件,扫描mapper目录下的所有xml
  type-aliases-package: cn.jean.model			//类,扫描cn.jean.model下所有类
package cn.jean.dao;

import cn.jean.model.NavDomain;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;

@Mapper
public interface NavDao{
    /**
     * 添加一条导航记录
     * @param nav
     * @return
     */
    int addNav(NavDomain nav);
    /**
     * 搜索-所有的
     * @return
     */
    List<NavDomain> getAllNav();
    /**
     * 搜索pid符合条件的
     * @param parent_id
     * @return
     */
    List<NavDomain> getNavByPid(@Param("parent_id") Integer parent_id);
}

NavServer.java 这是个接口类,要写具体的实现impl

package cn.jean.service;

import cn.jean.dto.NavDto;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import java.util.List;

import cn.jean.model.NavDomain;
import org.apache.ibatis.annotations.Param;



public interface NavService {
    /**
     * 搜索-符合条件的
     * @param nav
     * @return
     */
    void addNav(NavDomain nav);
    /**
     * 搜索-所有的
     * @return
     */
    List<NavDomain> getAllNav();
    /**
     * 搜索-符合条件的
     * @param parent_id
     * @return
     */
    List<NavDomain> getNavByPid(@Param("parent_id") Integer parent_id);
    /**
     * 搜索-符合条件的
     * @return
     */
    JSONArray getAllJson();
}

NavServiceImpl.java

package cn.jean.impl;

import cn.jean.dto.NavDto;
import cn.jean.utils.DtoEntityUtil;
import cn.jean.dao.NavDao;
import cn.jean.model.NavDomain;
import cn.jean.service.NavService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static java.util.Comparator.comparing;


@Service
public class NavServiceImpl implements NavService {

    @Autowired
    private NavDao navdao;
    private DtoEntityUtil dtoEntity;

    /**
     * 添加一条导航记录
     * @param nav
     * @return
     */
    @Override
    public void addNav(NavDomain nav) {
        navdao.addNav(nav);
    }
    /**
     * 搜索-所有的
     * @return
     */
    @Override
    public List<NavDomain> getAllNav() {
        List<NavDomain> LNav = navdao.getAllNav();
        return LNav;
    }
    /**
     * 搜索pid符合条件的
     * @param parent_id
     * @return
     */

    @Override
    public List<NavDomain> getNavByPid(Integer parent_id) {
        List<NavDomain> Nav = navdao.getNavByPid(parent_id);
        return Nav;
    }

    @Override
     // 获取树结构数据
    public JSONArray getAllJson() {
        JSONArray json = new JSONArray();
        try {
            // 从数据库里获取 List 数据,如果有条件,则根据相应条件获取,总之这里是一个树结构的 list
            List<NavDomain> Navs = navdao.getAllNav();//取出所有数据
            Navs.sort(comparing(NavDomain::getSort));
            // ??? 为什么不是 NavDto 类型?这里 Nav 是 Entity,从数据库获取的数据当前是用 Entity 类型接收啦!
            // 没关系的,可以转DTO
            // 定义一个空数组,用来存放最终的树结构数据
            List<NavDto> result = new ArrayList<>();
            // 第一步遍历获取到的数据,将根节点数据存放 result 里
            for (NavDomain nav: Navs) {
                // 判断是否是根节点,就是 parentId,这里是从 0 开始,如果 parentId 为 0 ,则表示根节点
                if (nav.getParent_id() == 0) {
                    // 这里可以将 entity 转为 DTO 存放
                    // 如果字段不多可以直接使用 set get 方法来存取,就像这样
                    NavDto navDto = new NavDto();
                    navDto = DtoEntityUtil.trans(nav,NavDto.class);
                    // 如果字段太多,超过5个以上,还是建议使用 mapper 方法来转哦,具体如何使用 mapper 将 Entity 转为 DTO 请移步下方链接
                    result.add(navDto);
                }
            }
            // 根节点添加完就需要添加每个节点的子节点了,这里需要调用 递归方法 getChildren();
            // 遍历根节点数据,为其设置子节点集合
            for (NavDto Nav: result) {
                // 获取子节点数据,传入 当前节点 id 和 所有 list
                List<NavDto> childList = getChildren(Nav.getId(), Navs);
                // 将获取到的子节点集合添加到根节点里
                childList.sort(comparing(NavDto::getSort));
                Nav.setChildren(childList);
            }
            // 将一层一层的树结构数据返回吧!
           json.add(result);
        } catch(Exception e) {
            // 这里可以抛个异常
        }
        return json;
    }

    /**
     * 获取子节点数据
     * @param id 父节点 ID
     * @param List<NavDomain> Navs 所有节点集合
     * @return 返回子节点列表
     */
    private List<NavDto> getChildren(Integer id, List<NavDomain> Navs) {
        // 存在子节点数据
        List<NavDto> childList = new ArrayList<>();
        // 遍历所有节点数据
        for (NavDomain nav : Navs) {
            // 如果当前节点 ID 与父节点 ID 一致,表示当前数据是该节点的子节点
            if (nav.getParent_id() == id) {
                NavDto navDto = new NavDto();
                navDto = DtoEntityUtil.trans(nav,NavDto.class);
                // 如果字段太多,超过5个以上,还是建议使用 mapper 方法来转哦,具体如何使用 mapper 将 Entity 转为 DTO 请移步下方链接
                childList.add(navDto);
            }
        }
        // 重点来了,递归调用
        for (NavDto item : childList) {
            // 调用自身方法,依次添加子节点数据
            item.setChildren(getChildren(item.getId(), Navs));
        }
        // 如果当前节点无子节点数据添加空数据,递归退出
        if (childList.size() == 0) {
            return new ArrayList<>();
        }
        // 返回最终的子节点数据
        return childList;
    }

}

NavController.java

package cn.jean.controller;

import cn.jean.service.NavService;
import cn.jean.model.NavDomain;
import com.alibaba.fastjson.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
@RequestMapping(value = "/nav")
public class NavController {
    @Autowired
    private NavService navService;

    @GetMapping("list")
    @ResponseBody
    public List<NavDomain> getAllNav(){
        List<NavDomain> l_nav = navService.getAllNav();
        return l_nav;
    }
    @GetMapping("json")
    @ResponseBody
    public JSONArray getJson(){
        JSONArray json = navService.getAllJson();
        return json;
    }

}

最后效果如图,全部代码和数据库文件,还有mapper文件都已上传到csdn
链接如下
https://download.csdn.net/download/brainjean/21110276

后续

后来发现在网页处理好慢,改为服务器端处理数据,前端只负责显示,项目地址
https://download.csdn.net/download/brainjean/21110748

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值