ManyToManyによるMapStructの問題解決





親愛なる読者の皆さん、こんにちは! Springフレームワークを使用してJava Webアプリケーションを開発する人、これらのアプリケーションにコメントして興味がある人。



前の記事「ManyToManyでのスプリングブート問題の解決」



2つのクラス間にManyToManyの双方向の関係があるテストアプリケーションの例を示しました。 この記事では、DTOクラスを使用して休息応答を受信したときのループの問題を解決する例を示します。 コメントの読者は、ループの問題を解決するためにMapStructライブラリを使用することを提案しました。



ドキュメントを確認した後、これは本当に強力なものであり、オブジェクト間でデータを移動するかなり複雑なタスクを解決できると確信しました。 MapStructは、ループの問題も解決します。



この記事では、MapStructライブラリーを使用して、Spring Bootアプリケーションと同じ問題を解決する例を示します。 Githubで入手可能なソースコード



Entity Peopleと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クラスは大幅に簡素化されましたが、マッパーインターフェイスが追加されました。 一般に、任意の方法を使用できますが、単純なケースでは、最初のオプションになります。



議論の参加者全員に感謝します。 あなたのコメントを待っています。



前の記事へのリンク。



Githubのプロジェクトにリンクます。



使用された文献:






All Articles