如何与 Spring 和 thymeleaf 创建一对多的关系?

Posted

技术标签:

【中文标题】如何与 Spring 和 thymeleaf 创建一对多的关系?【英文标题】:How can I create a one-to-many relationship with Spring and thymeleaf? 【发布时间】:2020-01-28 22:29:58 【问题描述】:

我想创建一个具有多个“标签”作为集合的“产品”类。所以一个一对多的数据库,而 Product 是“一”,而标签是“多”。

标签将在 html 中定义为输入字段并以空格分隔。例如“tag1 tag2 tag3”。

我现在的问题是:如何从输入字段中检索字符串并将它们作为集合附加到我的产品对象中?

到目前为止我所拥有的:

产品

@Entity
public class Product 
    @Id
    @GeneratedValue
    private int barcode;
    public String name;
    @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
    private Collection<Tag> tags;

...Getter & Setter

标签

@Entity
public class Tag 
    @Id
    private String tagname;
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "barcode", nullable = false)
    private Product product;

...Getter & Setter

ProductsController:我尝试添加 Tag 对象作为测试,但会引发 Tag 表不存在的错误

@PostMapping("/add")
        public String add(@Valid Product product, BindingResult result, Model model) 
            model.addAttribute("responseMessage", result);
            if(!result.hasErrors()) 
//I tried to add a static collection to the product object, but it throws errors
                Collection<Tag> col = new ArrayList<>();
                col.add(new Tag("test"));
                col.add(new Tag("test2"));
                product.setTags(col);

                productRepository.save(product);
            
            model.addAttribute("products",productRepository.findAll());
            return "products-add";
        

【问题讨论】:

我认为在您的产品类别中。私有 List 标签;它失踪了 我忘记复制了,它就在@Onetomany 注释 public Collection 标签的下方; 【参考方案1】:

因为你有用空格分隔的标签。首先,您需要使用正则表达式制作一个标签字符串数组,如下所示。

String tags = "tag1 tag2 tag3";
String[] tagArr = tags.split("\\s+"); 

现在您需要创建一个存储库,如下所示。

@Repository
public interface TagRepository extends JpaRepository<Tag, Long> 
    Tag findByTagname(String tagname);

为 TagService 创建一个接口。

public interface TagService 
    Tag findByTagname(String tagname);

创建 TagService 类的实现

@Service
public class TagServiceImpl implements TagService

    @Autowired
    private TagRepository tagRepository;

    @Override
    public Tag findByTagname(String tagname) 
        return tagRepository.findByTagname(tagname);
    

现在按名称获取标签已完成。将您的 TagService 自动装配到您的控制器类中

@Autowire
private TagService tagService;

将以下代码添加到您的控制器。

String tags = "tag1 tag2 tag3";
String[] tagArr = tags.split("\\s+"); 

List<Tag> tagList = new ArrayList<Tag>();

for (String tagname : tagArr) 
    Tag tag = tagService.findbyTagname(tagname);
    tagList.add(tag);

现在,当您保存产品类别时。将此标签列表设置到您的它中。

【讨论】:

【参考方案2】:
    您的服务层中必须有一个使用@Service 注释的 ProductService 类。 您必须在 ProductService 类中创建一个带有 @Transactional 注释的方法 您的方法必须读取产品的所有标签并将其转换为您想要的任何集合。 不要在 Controller 中执行此操作。它实际上是做同样事情的坏地方。

【讨论】:

Service层的使用是如何工作的?你有示例代码吗?【参考方案3】:

您可能是第一次运行此程序,并且您的数据库没有名为 Tag 的表。请确保将休眠属性 hibernate.hbm2ddl.auto 设置为“更新”,这将在执行任何数据插入之前首先自动创建所需的表。

对于转换用空格分隔的字符串值标签,只需使用 string.split() 方法,它会为您提供数组,然后将其转换为 List 以在 Product 对象中设置。

【讨论】:

以上是关于如何与 Spring 和 thymeleaf 创建一对多的关系?的主要内容,如果未能解决你的问题,请参考以下文章

我如何将 angularjs 与 spring boot 和 thymeleaf 一起使用?有模板项目吗? [关闭]

Spring MVC:如何在 Thymeleaf 中获取当前 url

如何使用 thymeleaf 和 Spring Boot 以 json 格式显示用户输入数据

Spring Boot、Spring Security 和 Thymeleaf:将 CsrfFilter 应用到带有表单的网站

如何将布局方言添加到spring-boot thymeleaf自动配置文件

使用 Spring Boot 和 Thymeleaf 创建文件下载链接