【问题标题】:Iterate over Entity attributes in view, Spring Boot JPA with thymeleaf迭代视图中的实体属性,带有百里香叶的 Spring Boot JPA
【发布时间】:2022-01-03 22:04:07
【问题描述】:

我正在使用带有 Thymeleaf 的 Spring Boot JPA,我正在处理一个链接到大约 40 列的表的类(实体),所以我的实体模型类有大约 40 个属性(每个属性都链接到表)。

如果我想在视图中显示(使用 thymeleaf)表的所有列,我是否必须像这样调用视图中的每个属性对其进行硬编码?

<td th:text=${entity.attribute1> </td>} <td th:text=${entity.attribute2> </td>} <td th:text=${entity.attribute3> </td>} <td th:text=${entity.attributeN...> </td>}

或者有没有办法在 Thymeleaf 视图中迭代实体的属性以避免必须按名称调用所有 40 个属性?

到目前为止,我刚刚找到了一种迭代实体列表的方法,而不是一个实体的属性。

【问题讨论】:

    标签: java spring-boot thymeleaf spring-thymeleaf


    【解决方案1】:

    我在 Thymeleaf 中没有遇到过这样的功能,但如果我必须这样做(为实体的每个属性创建一个列),我会在我的 @Controller 中执行类似的操作:

    @GetMapping( "/mypage" )
    public String myPage(Model model) {
        List<MyEntity> myEntities = dao.getList(MyEntity.class);
        List<String> fieldNames = MyEntity.class.getDeclaredFields().stream()
                .map(field -> field.getName()).collect(Collectors.toList());
    
        model.addAttribute("myEntities", myEntities);
        model.addAttribute("fieldNames", fieldNames);
        return "template";
    }
    

    并创建这样的@Service:

    @Service
    public class FieldService {
        public Object getFieldValue( Object root, String fieldName ) {
            try {
                Field field = root.getClass().getDeclaredField( fieldName );
                Method getter = root.getClass().getDeclaredMethod( 
                    (field.getType().equals( boolean.class ) ? "is" : "get") 
                        + field.getName().substring(0, 1).toUpperCase( Locale.ROOT)
                        + field.getName().substring(1)
                );
    
                return getter.invoke(root);
            } catch (Exception e) {
                // log exception
            }
        }
    }
    

    然后在template.html:

    <tr th:each="myEntity : ${myEntities}">
        <td th:each="fieldName : ${fieldNames}" 
            th:text="${@fieldService.getFieldValue(myEntity, fieldName)}"></td>
    </tr>
    

    但请注意,如果您将属性添加到 MyEntity.class,它可能会破坏您的表格,因此以某种方式对您的字段进行硬编码可能会更好,例如像这样:

    List<String> fieldNames = new ArrayList<>(Arrays.asList("attribute1", "attribute2", ...));
    

    【讨论】:

    • 非常感谢!这似乎是一种很好的方法,感谢您以如此清晰的方式表达。还有一个问题,如果我对属性列表进行硬编码,我该如何在 Thymeleaf 中调用它们?像这样的东西? &lt;td th:each="fieldName : ${fieldNames}"} th:text = ${entity.fieldName} 假设我已经对实体进行了循环。
    • 您可以按照我在html 示例中建议的方式进行操作。 .stream()new ArrayList&lt;&gt;(...) 的结果完全相同 - 它创建了 StringList - 例如"attribute1", "attribute2", "attribute3" 等。因此,th:each="fieldName : ${fieldNames}" 为来自 myEntities 列表的每个 myEntity 迭代这些字符串 - 因此,迭代没有差异。
    猜你喜欢
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 2020-05-17
    • 1970-01-01
    • 2019-03-30
    相关资源
    最近更新 更多