简体   繁体   中英

Spring Boot JPA how to retrieve data from a ManyToMany table?

I am learning Spring boot. Now I have ManyToMany relationship with a User entity and a Team entity. So an user can have several teams and a team can have several users.

   @Entity
    public class User {
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="id", nullable =false, updatable = false)
        private Long id;
@ManyToMany
    @JoinTable(
            name = "team_have",
            joinColumns = @JoinColumn(name = "id"),
            inverseJoinColumns = @JoinColumn(name = "teamId"))
    List<Team> haveTeams;

This is the Team entity:

@Entity
@Table(name="TEAM")
public class Team {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long teamId;
    @OneToMany(cascade = CascadeType.ALL, mappedBy="team")
    private List<Task> tasks;

This is my repository:

public interface TeamRepository extends CrudRepository<Team, Long>{
    List<Team>findByName(String name);
    
}

How can I find all teams which belonged to one user?

User already have mapped with List<Team> , you need to use UserRepository instead of TeamRepository .

public interface UserRepository extends CrudRepository<User, Long>{
    User findByName(String name);
    
}

Here, you will get one user and that user have all teams which he belongs to. (Assuming username is unique)

OR

If you are having bidirectional Many-to-Many (Team also mapped Lis<User> ) like following

@Entity
@Table(name="TEAM")
public class Team {

    ....
    @ManyToMany(cascade = CascadeType.ALL, mappedBy="haveTeams")
    private List<User> users;

Then you can define query method like following to get all teams for one user,

public interface TeamRepository extends CrudRepository<Team, Long>{
    List<Team> findByUsers(User user);
    
}

The best way to build the connection between them would be to use a bi-directional relationship, like this:

User Entity

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    /* @Column(name = "id", nullable = false, updatable = false) You don't need this, 
    the name is taken from the name of the variable and it cannot be null since you 
    have @GeneratedValue */
    private Long id;

    @ManyToMany(fetch = LAZY, cascade = CascadeType.PERSIST)
    @JoinTable(
        name = "user_team", // I would name this user_team since the user can have many teams, and vice versa
        joinColumns = @JoinColumn(name = "user_id" , referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "team_id",  referencedColumnName = "id"))
     Set<Team> teams = new HashSet<>();
}

Team Entity

@Entity
@Table(name="team")
public class Team {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long teamId;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "team")
    private List<Task> tasks;

    @ManyToMany(mappedBy = "teams", fetch = LAZY, cascade = CascadeType.PERSIST)
    private Set<User> users = new HashSet<>();
}

Team Repo

public interface TeamRepository extends CrudRepository<Team, Long>{
     @Query(value = "SELECT * FROM team t1 INNER JOIN user_team t2 ON t1.id = t2.team_id WHERE t2.user_id = ?1 ")
    List<Team> findAllByUserId(long userId);
}

Example of use:

List<Team> teams = teamRepo.findAllByUserId(1);

A great tutorial: https://attacomsian.com/blog/spring-data-jpa-many-to-many-mapping

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM