专业的编程技术博客社区

网站首页 > 博客文章 正文

在jeesite开源平台上写了一个SQL命令中心的功能

baijin 2024-10-04 13:27:21 博客文章 4 ℃ 0 评论

实现目的

这个SQL命令中心,是因为老项目就有这个页面,主要的功能是根据写出的SQL语句查询数据,并且在查出的数据基础上直接修改更新,还有新增和删除的功能,这么一说跟plsql就一样一样的了;这页面本来是给运维的同事来用,而且他们还会用plsql和Navicat等SQL语言操作工具,领导要求新老版本尽量保持一致,所以只能照猫画虎,把一些功能在jeesite中重写一遍,不过这也算是重新理解一下原生的SQL语言查询的原理,就当是温故知新了!

我写的这版属于简化版,目前版本只有查询一项,可以实现简单和比较复杂的SQL语言查询功能,具体效果如下。

实现效果

简单SQL版:单表查询。

复杂SQL版:多表联查,字段有重复时。

以上查询结果用的jeesite自带的dataGrid,带分页,可以上下页展示。

实现思路

1. 首先是对照了老项目的页面展示,老项目的代码写的非常全面但是比较老,不能直接复制到开源框架中使用,所以决定直接手写类似的功能,把老项目当原型。

2. 目前经常使用Navicat工具,所以也对照着Navicat查询结果展示的样子,来进行实现。

3. 由于操作语句的不确定性,所以在jeesite中没有具体的实体类可以使用,只能使用jdbc方法进行SQL语句的操作,同时在后端整理字头字段,在前端通过循环展示。可以参考之前写的jeesite前后端不分离页面横表转纵表数据展示

实现原理和代码

1. 先创建功能所需的文件夹,手写补全所有文件,可以参考代码生成器生成的代码层级结构。

2. 后端代码实现,将一个整页面拆分为,一个主页面mainPage和多个页签页面tabPage,在主页面只保留查询条件,在页签页面只展示数据和其他操作;后端代码就会分成三部分,第一部分是总页面,第二部分是页签页面,第三部分是页签页面返回数据。
第一部分:

/**
     * @return String
     * @author FredHe
     * @date 2024/6/13 9:22
     * @description SQL命令中心展示页面
     */
    @RequestMapping("/commandCenterMain")
    public String sqlCommandCenterMain(SQLCommandCenter sqlCommandCenter, Model model) {
        model.addAttribute("sqlCommandCenter", sqlCommandCenter);
        return "modules/sqlcenter/sqlcommandcenter/sqlCommandCenterMain";
    }


第二部分:

/**
     * @return String
     * @author FredHe
     * @date 2024/7/4 16:57
     * @description 分页清单页签
     */
    @RequestMapping("/commandCenterPageList")
    public String commandCenterPageList(SQLCommandCenter sqlCommandCenter, Model model) {
        String jsonArrayString = "''";
        // 将数据保存到list中 使用键值对形式保存 并将结果展示到页面
        List<Map<String, Object>> columnList = new ArrayList<>();
        String sql = sqlCommandCenter.getSql();
        if (StringUtils.isNotBlank(sql)) {
            // 查出数据
            try {
                // 加载数据库驱动
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                //throw new Exception("加载数据库驱动有误,请联系管理员!" + e.getMessage());
                return renderResult(Global.FALSE, "加载数据库驱动有误,请联系管理员!" + e.getMessage());
            }
            // 声明数据库连接、预编译语句资源对象
            try {
                Connection connection = DriverManager.getConnection(url, user, password);
                if (sqlCommandCenter.getPageSize() != null) {
                    sql += " and rownum <= ?";
                }
                PreparedStatement preparedStatement = connection.prepareStatement(sql);
                // 设置查询展示条数的参数
                if (sqlCommandCenter.getPageSize() != null) {
                    preparedStatement.setInt(1, sqlCommandCenter.getSize());
                }

                // 执行SQL查询语句,声明ResultSet资源对象
                ResultSet resultSet = preparedStatement.executeQuery();
                try {
                    // 通过resultSet.getMetaData()获取该结果集的ResultSetMetaData对象
                    ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
                    // 获取列数
                    int columnCount = resultSetMetaData.getColumnCount();
                    System.out.println("查询结果一共有:" + columnCount + "列。");
                    int k = 0;
                    for (int i = 1; i <= columnCount; i++) {
                        LinkedHashMap<String, Object> rowDataMap = new LinkedHashMap<>();
                        rowDataMap.put("columnLabel", resultSetMetaData.getColumnLabel(i));
                        if (columnList.contains(rowDataMap)) {
                            rowDataMap.put("columnLabel", resultSetMetaData.getColumnLabel(i) + "(" + (++k) + ")");
                        }
                        columnList.add(rowDataMap);
                    }
                    jsonArrayString = JSON.toJSONString(columnList);
                } catch (SQLException e) {
                    e.printStackTrace();
                    logger.error("当前数据库查询'" + sql + "'有误," + e.getMessage() + "请检查后重试");
                }
            } catch (SQLException e) {
                System.err.println("当前输入的SQL语句'" + sql + "'有误," + e.getMessage() + "请检查后重试");
                logger.error("当前输入的SQL语句'" + sql + "'有误," + e.getMessage() + "请检查后重试");
                //generalLogRecordService.addMrLog02(e,);
            }
        }
        model.addAttribute("columnList", jsonArrayString);
        model.addAttribute("sqlCommandCenter", sqlCommandCenter);
        return "modules/sqlcenter/sqlcommandcenter/sqlCommandCenterPageList";
    }


第三部分:

/**
     * @return ModelAndView
     * @author FredHe
     * @date 2024/6/13 16:38
     * @description 调用查询数据 返回到页面
     */
    @RequestMapping("/commandCenterPageListData")
    @ResponseBody
    public Page<Map<String, Object>> commandCenterPageListData(SQLCommandCenter sqlCommandCenter, HttpServletResponse response, HttpServletRequest request) {
        sqlCommandCenter.setPage(new Page<SQLCommandCenter>(request, response));
        Page<Map<String, Object>> sqlCommandCenterPage = (Page<Map<String, Object>>) sqlCommandCenter.getPage();
        // 将数据保存到list中 使用键值对形式保存 并将结果展示到页面
        List<Map<String, Object>> rowDataList = new ArrayList<>();
        String sql = sqlCommandCenter.getSql();
        if (StringUtils.isNotBlank(sql)) {
            // 查出数据
            try {
                // 加载数据库驱动
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                //throw new Exception("加载数据库驱动有误,请联系管理员!" + e.getMessage());
            }
            // 声明数据库连接、预编译语句资源对象
            try {
                Connection connection = DriverManager.getConnection(url, user, password);
                if (sqlCommandCenter.getSize() != null) {
                    sql += " and rownum <= ?";
                }
                PreparedStatement preparedStatement = connection.prepareStatement(sql);
                // 设置查询展示条数的参数
                if (sqlCommandCenter.getSize() != null) {
                    preparedStatement.setInt(1, sqlCommandCenter.getSize());
                }
                // 执行SQL查询语句,声明ResultSet资源对象
                ResultSet resultSet = preparedStatement.executeQuery();
                try {
                    // 通过resultSet.getMetaData()获取该结果集的ResultSetMetaData对象
                    ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
                    // 获取列数
                    int columnCount = resultSetMetaData.getColumnCount();
                    System.out.println("查询结果一共有:" + columnCount + "列。");
                    while (resultSet.next()){
                        Map<String, Object> rowDataMap = new LinkedHashMap<>();
                        int k = 0;
                        for (int i = 1; i <= columnCount; i++) {
                            if (rowDataMap.containsKey(resultSetMetaData.getColumnLabel(i))) {
                                rowDataMap.put(resultSetMetaData.getColumnLabel(i) + "(" + (++k) + ")", resultSet.getString(i));
                            } else {
                                rowDataMap.put(resultSetMetaData.getColumnLabel(i), resultSet.getString(i));
                            }
                        }
                        rowDataList.add(rowDataMap);
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                    logger.error("当前数据库查询'" + sql + "'有误," + e.getMessage() + "请检查后重试");
                }
            } catch (SQLException e) {
                System.err.println("当前输入的SQL语句'" + sql + "'有误," + e.getMessage() + "请检查后重试");
                logger.error("当前输入的SQL语句'" + sql + "'有误," + e.getMessage() + "请检查后重试");
                //generalLogRecordService.addMrLog02(e,);
            }
        }
        if (!rowDataList.isEmpty()){
            sqlCommandCenterPage.setCount(rowDataList.size());
            List<Map<String, Object>> mapList = rowDataList.stream().skip((sqlCommandCenter.getPageNo() - 1) * sqlCommandCenter.getPageSize())
                    .limit(sqlCommandCenter.getPageSize()).collect(Collectors.toList());
            sqlCommandCenterPage.setList(mapList);
        }
        return sqlCommandCenterPage;
    }

3. 前端代码实现,将后台传过来的数据通过别称循环展示出来,使用dataGrid即可。

<% layout('/layouts/default.html', {title: '分页清单', libs: ['layout','dataGrid']}){ %>
<div class="ui-layout-north" id="north">
    <div class="box box-main">
        <div class="box-body">
            <#form:form id="searchForm" model="${sqlCommandCenter}" action="${ctx}/sql/commandCenterPageListData" method="post" class="form-inline"
            data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
                <#form:input type="hidden" path="sql" id="sql" />
                <#form:input type="hidden" path="size" id="size" />
            </#form:form>
            <table id="dataGrid"></table>
            <div id="dataGridPage"></div>
        </div>
    </div>
</div>
<% } %>
<script>
    // 设置新的行
    const columnModel = [];
    var str = ${columnList};
    if (str !='' ){
        for (var i = 0; i <str.length ; i++) {
            columnModel.push({header:'${text("'+str[i].columnLabel+'")}', name:'${text("'+str[i].columnLabel+'")}',  width:100, align:"center"
            },)
        }
    }

    // 初始化DataGrid对象
    $('#dataGrid').dataGrid({
        searchForm: $("#searchForm"),
        columnModel: columnModel,
        showFooter: true, // 是否显示底部合计行
        // 加载成功后执行事件
        ajaxSuccess: function(data){

        }
    });
</script>

实现需要注意的问题

由于数据库没有对应的实体,所以没法用jeesite自带的代码生成工具,大部分页面和实体需要手写,在此需要注意前后端互相映射的代码要保持一致,一旦写错会浪费很多时间。要注意捋清循环与前端的对应。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表