我正在使用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>
这是数据显示的屏幕截图。您会看到行中列的顺序不一致。刷新页面时,有时会以正确的顺序显示数据,有时则不然。
感谢任何有关如何正确执行此操作的反馈。