将动态SQL结果集存储到Java变量以在html中显示的正确方法是什么

时间:2019-08-05 23:58:17

标签: spring-boot spring-data-jpa thymeleaf

我正在使用Spring Boot,Thymeleaf和JPA存储库来检索和显示数据。我创建了一个存储sql语句的表以及一个用于存储该sql语句的列的表。见下文。

create table web_regions (
    id                  bigint             auto_increment
  , name                varchar(255)  not null
  , region_type         varchar(30)   not null
  , sequence_id         int           not null
  , page_id             bigint
  , parent_region_id    bigint
  , source_type         varchar(30)
  , source_table_or_query varchar(4000)
  , created_on          datetime
  , last_updated_on     datetime
  , created_by          bigint
  , last_updated_by     bigint
  , primary key ( id )
  , foreign key ( page_id ) references web_pages ( id )
  , foreign key ( parent_region_id ) references web_regions ( id )
);

create table web_columns (
    id                  bigint                    auto_increment
  , region_id           bigint          not null
  , name                varchar(30)     not null
  , column_type         varchar(30)     not null
  , header              varchar(30)     not null
  , header_alignment    varchar(30)     not null
  , sequence_id         int             not null
  , column_alignment    varchar(30)     not null
  , column_link_url     varchar(255)
  , column_link_text    varchar(30)
  , created_on          datetime
  , last_updated_on     datetime
  , created_by          bigint
  , last_updated_by     bigint
  , primary key ( id )
  , foreign key ( region_id ) references web_regions ( id )
);

示例数据如下所示。

insert into web_regions ( page_id, id, name, region_type, sequence_id, source_type, source_table_or_query ) values ( 3, 4, 'Applications', 'REPORT', 10, 'SQL', 'select id, code, name from web_applications' );
insert into web_columns ( id, region_id, name, column_type, header, header_alignment, sequence_id, column_alignment, column_link_url, column_link_text ) values ( 1, 4, 'ID', 'LINK', 'Id', 'LEFT', 10, 'LEFT', 'f?w=DEMO&p=DEMO:#ID#', '#ID#' );
insert into web_columns ( id, region_id, name, column_type, header, header_alignment, sequence_id, column_alignment, column_link_url, column_link_text ) values ( 2, 4, 'CODE', 'TEXT', 'Code', 'LEFT', 20, 'LEFT', null, null );
insert into web_columns ( id, region_id, name, column_type, header, header_alignment, sequence_id, column_alignment, column_link_url, column_link_text ) values ( 3, 4, 'NAME', 'TEXT', 'Name', 'LEFT', 30, 'LEFT', null, null );

然后对于控制器,我有以下代码来获取数据。我通过web_columns表中的序列ID对列进行排序。我还使用HashMap数组存储每行的列值。

    List<WebRegion> regions = regionRep.findByPageId(page.getId());

    for (WebRegion region : regions) {
        if (region.getSourceType() != null) {
            if (region.getSourceType().equals("SQL")) {

                try {
                    Connection connection = dataSource.getConnection();
                    PreparedStatement statement = connection.prepareStatement(region.getSourceTableOrQuery());
                    ResultSet rs = statement.executeQuery();

                    List<WebColumn> columns = columnRep.findByRegionIdOrderBySequenceIdAsc(region.getId());
                    region.setColumns(columns);

                    List<HashMap<WebColumn, Object>> rows = new ArrayList<>();                      
                    while (rs.next() ) {

                        HashMap<WebColumn, Object> row = new HashMap<>();
                        for (WebColumn column : columns) {
                            WebColumn col = new WebColumn();
                            col.setId(column.getId());
                            col.setName(column.getName());
                            col.setRegionId(column.getRegionId());
                            col.setColumnAlignment(column.getColumnAlignment());
                            col.setColumnLinkText(column.getColumnLinkText());
                            col.setColumnLinkUrl(column.getColumnLinkUrl());
                            col.setColumnType(column.getColumnType());

                            if (column.getColumnType().equals("LINK")) {
                                Pattern pattern = Pattern.compile("#([^#]*)#");
                                Matcher matcher = pattern.matcher(col.getColumnLinkUrl());
                                String columnLinkUrl = col.getColumnLinkUrl();
                                while (matcher.find()) {
                                    String newColumnLinkUrl = columnLinkUrl.replace(String.format("#%s#", matcher.group(1)), rs.getString(matcher.group(1)));
                                    columnLinkUrl = newColumnLinkUrl;
                                }
                                col.setColumnLinkUrl(columnLinkUrl);;
                            }

                            row.put(col, rs.getObject(col.getName()));
                        }
                        rows.add(row);
                    }

                    region.setRows(rows);
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }
        }
    }

我上面的代码存在的问题是行列有时会按顺序互换。尽管标题没问题。

这是我用来显示数据的html代码。

<form th:each="region: ${page.regions}" action="/f" style="width: 100%;">

  <div th:if="${region.regionType == 'REPORT'}" style="padding: 8px; width: 100%;">

    <div th:if="${region.sourceType == 'SQL'}" class="mdc-data-table" style="width: 100%;">

      <div class="mdc-card" style="padding: 16px; width: 100%;">

        <div class="mdc-card__primary">
          <h2 class="mdc-typography mdc-typography--headline6" th:text="${region.name}"></h2>
        </div>

        <table class="mdc-data-table__table" aria-label="${region.name}">
          <thead>
            <tr class="mdc-data-table__header-row">
              <th class="mdc-data-table__header-cell mdc-data-table__header-cell--checkbox" role="columnheader" scope="col">
                <div class="mdc-checkbox mdc-checkbox--selected mdc-data-table__header-row-checkbox">
                  <input type="checkbox" class="mdc-checkbox__native-control" aria-label="Toggle all rows" />
                  <div class="mdc-checkbox__background">
                    <svg class="mdc-checkbox__checkmark" viewbox="0 0 24 24">
                      <path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" /></svg>
                    <div class="mdc-checkbox__mixedmark"></div>
                  </div>
                </div>
              </th>
              <th class="mdc-data-table__header-cell" role="columnheader" scope="col" th:each="column: ${region.columns}"><p th:text="${column.header}">Text</p></th>
            </tr>
          </thead>
          <tbody class="mdc-data-table__content">
            <tr class="mdc-data-table__row" data-row-id="u0" th:each="row: ${region.rows}">
              <td class="mdc-data-table__cell mdc-data-table__cell--checkbox">
                <div class="mdc-checkbox mdc-data-table__row-checkbox">
                  <input type="checkbox" class="mdc-checkbox__native-control" aria-labelledby="r0" />
                  <div class="mdc-checkbox__background">
                    <svg class="mdc-checkbox__checkmark" viewbox="0 0 24 24"><path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" /></svg>
                    <div class="mdc-checkbox__mixedmark"></div>
                  </div>
                </div>
              </td>
              <td class="mdc-data-table__cell" th:each="map: ${row}"><span th:if="${map.key.columnType == 'TEXT'}" th:text="${map.value}">Data</span><span th:if="${map.key.columnType == 'LINK'}"><a th:href="${map.key.columnLinkUrl}" th:text="${map.value}">Data</a></span></td>
              <!-- <td class="mdc-data-table__cell" th:each="map: ${row}" th:if="${map.key.columnType == 'LINK'}"><a th:href="${map.key.columnLinkUrl}" th:text="${map.value}">Data</a></td> -->
              <!-- <td class="mdc-data-table__cell" th:each="map: ${row}" th:if="${map.key.columnType == 'TEXT'}" th:text="${map.value}">Data</td> -->
            </tr>
          </tbody>
        </table>

      </div>

    </div>

  </div>

</form>

<form th:each="region: ${page.regions}" action="/f" style="width: 100%;"> <div th:if="${region.regionType == 'REPORT'}" style="padding: 8px; width: 100%;"> <div th:if="${region.sourceType == 'SQL'}" class="mdc-data-table" style="width: 100%;"> <div class="mdc-card" style="padding: 16px; width: 100%;"> <div class="mdc-card__primary"> <h2 class="mdc-typography mdc-typography--headline6" th:text="${region.name}"></h2> </div> <table class="mdc-data-table__table" aria-label="${region.name}"> <thead> <tr class="mdc-data-table__header-row"> <th class="mdc-data-table__header-cell mdc-data-table__header-cell--checkbox" role="columnheader" scope="col"> <div class="mdc-checkbox mdc-checkbox--selected mdc-data-table__header-row-checkbox"> <input type="checkbox" class="mdc-checkbox__native-control" aria-label="Toggle all rows" /> <div class="mdc-checkbox__background"> <svg class="mdc-checkbox__checkmark" viewbox="0 0 24 24"> <path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" /></svg> <div class="mdc-checkbox__mixedmark"></div> </div> </div> </th> <th class="mdc-data-table__header-cell" role="columnheader" scope="col" th:each="column: ${region.columns}"><p th:text="${column.header}">Text</p></th> </tr> </thead> <tbody class="mdc-data-table__content"> <tr class="mdc-data-table__row" data-row-id="u0" th:each="row: ${region.rows}"> <td class="mdc-data-table__cell mdc-data-table__cell--checkbox"> <div class="mdc-checkbox mdc-data-table__row-checkbox"> <input type="checkbox" class="mdc-checkbox__native-control" aria-labelledby="r0" /> <div class="mdc-checkbox__background"> <svg class="mdc-checkbox__checkmark" viewbox="0 0 24 24"><path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" /></svg> <div class="mdc-checkbox__mixedmark"></div> </div> </div> </td> <td class="mdc-data-table__cell" th:each="map: ${row}"><span th:if="${map.key.columnType == 'TEXT'}" th:text="${map.value}">Data</span><span th:if="${map.key.columnType == 'LINK'}"><a th:href="${map.key.columnLinkUrl}" th:text="${map.value}">Data</a></span></td> <!-- <td class="mdc-data-table__cell" th:each="map: ${row}" th:if="${map.key.columnType == 'LINK'}"><a th:href="${map.key.columnLinkUrl}" th:text="${map.value}">Data</a></td> --> <!-- <td class="mdc-data-table__cell" th:each="map: ${row}" th:if="${map.key.columnType == 'TEXT'}" th:text="${map.value}">Data</td> --> </tr> </tbody> </table> </div> </div> </div> </form>

这是数据显示的屏幕截图。您会看到行中列的顺序不一致。刷新页面时,有时会以正确的顺序显示数据,有时则不然。

Screenshot of table

感谢任何有关如何正确执行此操作的反馈。

0 个答案:

没有答案