用ManyToMany解决MapStruct问题



亲爱的读者您好! 那些使用Spring框架开发Java Web应用程序的人,对这些应用程序发表评论的人,只是感兴趣。

在上一篇文章“使用ManyToMany解决Spring Boot问题”中

我给出了一个测试应用程序的示例,其中两个类之间存在双向关系ManyToMany。 本文提供了一个示例,该示例使用DTO类接收到休息响应时解决循环问题。 注释中的读者建议使用MapStruct库来解决循环问题

在阅读了文档之后,我坚信这确实是一项功能强大的事情,通过它您可以解决在对象之间移动数据的相当复杂的任务。 MapStruct也解决了循环问题。

在本文中,我将举一个使用MapStruct库解决与Spring Boot应用程序相同的问题的示例。 Github提供的源代码

实体人和SongPlayers保持不变。 吸气剂和二传手降低了。

@Entity public class People { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String human; //      @ManyToOne(cascade = CascadeType.ALL) private RockGroups rockGroups; //     @ManyToMany(mappedBy = "songInstrumentalist",fetch = FetchType.EAGER) private List<SongPlayers> songItems; public People(){} public People(long id, String human){ this.id = id; this.human = human; } //. . . . . } 

 @Entity public class SongPlayers { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String song; //    private String composer; //     private String poet; //    private String album; //   //     @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<People> songInstrumentalist; //. . . . . } 

我们还为People和SongPlayers类创建存储库接口。

 @Repository public interface PeopleRepository extends JpaRepository<People, Long> { @Query("select h from People h where h.human=?1") List<People> searchByHuman(String human); List<People> findPeopleByHuman(String human); } 

 @Repository public interface SongPlayersRepository extends JpaRepository<SongPlayers, Long> { List<SongPlayers> findSongPlayersBySong(String song); List<SongPlayers> findSongPlayersByComposer(String composer); List<SongPlayers> findSongPlayersByPoet(String poet); } 

我们还为People和SongPlayers创建了DTO类,它们现在看起来并不那么庞大。 我降低吸气剂和二传手。

 public class PeopleDTO { private long id; private String human; private RockGroups rockGroups; private List<SongPlayersDTO> songPlayersList; // . . . . . } 

 public class SongPlayersDTO { private long id; private String song; private String composer; private String poet; private String album; // . . . . . } 

为了描述将数据从源对象传输到DTO对象并在必要时返回的规则,我们为需要循环保护的每个类创建了映射器接口。 这是PeopleMapper和SongPlayersMapper

 @Mapper(uses = SongPlayersMapper.class) public interface PeopleMapper { PeopleMapper PEOPLE_MAPPER = Mappers.getMapper(PeopleMapper.class); @Mapping(source = "songItems", target = "songPlayersList") PeopleDTO fromPeople(People people); } 

 @Mapper/*(uses = {PeopleMapper.class})*/ public interface SongPlayersMapper { SongPlayersMapper SONG_PLAYERS_MAPPER = Mappers.getMapper(SongPlayersMapper.class); SongPlayersDTO fromSongPlayers(SongPlayers songPlayers); @InheritInverseConfiguration SongPlayers toSongPlayers(SongPlayersDTO songPlayersDTO); } 

在Service文件夹中,创建服务类的接口和实现,在其中放置接收数据的方法(我将为People提供)。

 public interface PeopleService { List<PeopleDTO> getAllPeople(); PeopleDTO getPeopleById(long id); People addPeople(People people); void delPeople(long id); ResponseEntity<Object> updPeople(People people, long id); List<RockGroups> getByHuman(String human); List<String> getSongByHuman(String human); } 

 @Service("peopleservice") public class PeopleServiceImpl implements PeopleService { @Autowired private PeopleRepository repository; @Override public List<PeopleDTO> getAllPeople() { List<PeopleDTO> peopleDTOList = new ArrayList<>(); List<People> peopleList = repository.findAll(); for (People people : peopleList){ peopleDTOList.add(PeopleMapper.PEOPLE_MAPPER.fromPeople(people)); } return peopleDTOList; } // . . . . . } 

在控制器中,我们将相应地应用这些方法(同样适用于People)

 @RestController @RequestMapping("/people") public class PeopleController { @Autowired private PeopleServiceImpl service; @GetMapping("/all") public List<PeopleDTO> getAllPeople(){ return service.getAllPeople(); } // . . . . . } 

从上面的关于ManyToMany关系的循环问题的解决方案中,我可以说上一篇文章中的DTO类选项和本文中的MapStruct库选项也可以正常工作。 与以前的版本相比,DTO类已大大简化,但已添加了Mapper接口。 通常,可以使用任何方法,对于简单的情况,我倾向于第一种选择。

我感谢所有参加讨论的人。 等待您的评论。

链接到上一篇文章

链接到Github上的项目

二手文献:

  • Felipe Gutierrez Pro春季靴子
  • Craig Walls Spring in Action第5版

Source: https://habr.com/ru/post/zh-CN433270/


All Articles