Pemecahan Masalah MapStruct dengan ManyToMany



Halo para pembaca! Mereka yang mengembangkan aplikasi Web di Jawa menggunakan kerangka kerja Spring, mereka yang mengomentari aplikasi ini dan hanya tertarik.

Dalam artikel sebelumnya, “Pemecahan Masalah Booting Musim Semi dengan ManyToMany”

Saya memberi contoh aplikasi tes di mana ada hubungan dua arah ManyToMany antara dua kelas. Artikel tersebut memberikan contoh pemecahan masalah looping ketika menerima respon istirahat menggunakan kelas DTO. Pembaca di komentar disarankan menggunakan pustaka MapStruct untuk menyelesaikan masalah perulangan.

Setelah meninjau dokumentasi, saya yakin bahwa ini benar-benar hal yang kuat, dengan mana Anda dapat menyelesaikan tugas yang cukup rumit untuk memindahkan data antar objek. MapStruct juga memecahkan masalah looping.

Pada artikel ini, saya akan memberikan contoh pemecahan masalah yang sama seperti aplikasi Spring Boot menggunakan pustaka MapStruct. Kode Sumber Tersedia di Github

Orang Entitas dan SongPlayers tetap tidak berubah. Getters dan setter diturunkan.

@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; //. . . . . } 

Kami juga membuat antarmuka Repositori untuk kelas People dan 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); } 

Kami juga membuat kelas DTO untuk People dan SongPlayers, yang sekarang tidak terlihat terlalu besar. Getters dan setter saya turunkan.

 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; // . . . . . } 

Untuk menggambarkan aturan untuk mentransfer data dari objek sumber ke objek DTO dan, jika perlu, kembali kita membuat antarmuka mapper untuk setiap kelas yang membutuhkan perlindungan loop. Inilah PeopleMapper dan 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); } 

Di folder Layanan, buat antarmuka dan implementasi kelas layanan, tempat kami meletakkan metode penerimaan data (saya akan memberikannya untuk Orang).

 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; } // . . . . . } 

Pada pengontrol, kami akan menerapkan metode ini sesuai (lagi hanya untuk Orang)

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

Dari solusi masalah looping di atas untuk hubungan ManyToMany, saya dapat mengatakan bahwa opsi dengan kelas DTO dari artikel sebelumnya dan versi dengan pustaka MapStruct dari artikel ini juga berfungsi. Dibandingkan dengan versi sebelumnya, kelas DTO telah sangat disederhanakan, tetapi antarmuka Mapper telah ditambahkan. Secara umum, metode apa pun dapat digunakan, untuk kasus-kasus sederhana saya akan cenderung ke opsi pertama.

Saya berterima kasih kepada semua peserta dalam diskusi. Menunggu komentar Anda.

Tautan ke artikel sebelumnya .

Tautan ke proyek di Github .

Literatur bekas:

  • Felipe Gutierrez Pro Spring Boot
  • Craig Walls Spring beraksi edisi ke-5

Source: https://habr.com/ru/post/id433270/


All Articles