提问者:小点点

用百里香叶迭代视图中的实体属性,Spring Boot JPA


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

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

<代码>

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

到目前为止,我只是找到了一种遍历实体列表的方法,但不是一个实体的属性。


共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
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>

但是请注意,如果您将一个属性添加到< code>MyEntity.class中,它可能会破坏您的表,因此最好对您的字段进行硬编码,例如:

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