[JAVA] Mit JPA Spalten verwandter Tabellen abrufen

Wenn Sie in JPA mit Many-to-Many arbeiten, können Sie mit `` @ ManyToMany``` transparent auf verwandte Tabellen zugreifen. In diesem Fall kann nicht auf die Spalten der zugehörigen Tabelle zugegriffen werden. Ich habe jedoch nicht viele zusätzliche Spalten in der zugehörigen Tabelle, daher ist dies kein wirkliches Problem. Ich muss es diesmal tun, also notiere mir, wie es geht.

Für die Methode habe ich auf http://www.codejava.net/frameworks/hibernate/hibernate-many-to-many-association-with-extra-columns-in-join-table-example verwiesen.

Die Beispieltabelle hat einen runden Link. Siehe den Link für das ER-Diagramm jeder Methode.

Vorbereitung

pom.xml

pom.xml


	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
	</parent>
<dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
</dependencies>

Haben Sie einen alternativen Schlüssel in der zugehörigen Tabelle

@Data
@Entity
@Table(name = "USERS")
public class User {
	@Id
	private Long userId;
	private String username;
	private String password;
	private String email;
	
	@OneToMany(mappedBy = "user")
	private Set<UserGroup> userGroups;
}
@Data
@Entity
@Table(name = "USERS_GROUPS")
@EqualsAndHashCode(exclude= {"user", "group"})
public class UserGroup {
	@Id
    private Long id;
	@ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "USER_ID")
    private User user;
	@ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "GROUP_ID")
    private Group group;
	
    private boolean activated;
    private Date registeredDate;
}
@Data
@Entity
@Table(name = "GROUPS")
public class Group {
	@Id
	private Long groupId;
    private String name;
    
    @OneToMany(mappedBy = "group")
    private Set<UserGroup> userGroups;
}

Die zugehörige Tabelle, hier `USERS_GROUPS```, hat eine alternative Schlüsselspalte USERS_GROUPS.ID```. Danach wird jede Eins-zu-Viele-Beziehung durch "@ OneToMany", "@ ManyToOne" definiert.

Unten finden Sie das entsprechende Repository und den Hauptcode zum Überprüfen des Vorgangs.

public interface UserRepository extends CrudRepository<User, Long> {
}
@SpringBootApplication
public class ManyToManyApplication implements CommandLineRunner {
	public static void main(String[] args) throws InterruptedException {
		SpringApplication.run(ManyToManyApplication.class, args).close();
	}

	@Autowired
	UserRepository userRepository;

	@Transactional
	@Override
	public void run(String... args) throws Exception {
		Optional<User> user = userRepository.findById(1L);
		Set<UserGroup> userGroups = user.get().getUserGroups();
		for (UserGroup userGroup : userGroups) {
			System.out.println(userGroup.getRegisteredDate() + " " + userGroup.isActivated());
			System.out.println(userGroup.getGroup().getName());
		}
	}

}

Testdaten.

src/main/resources/data.sql


insert into users(user_id, username, password, email) values (1, 'username', 'pass', '[email protected]');

insert into groups(group_id, name) values (10, 'groupname001');
insert into groups(group_id, name) values (20, 'groupname002');

insert into users_groups(id, user_id, group_id, activated, registered_date) values (100, 1, 10, true, '2018-04-26 12:34:56');
insert into users_groups(id, user_id, group_id, activated, registered_date) values (200, 1, 20, true, '2018-04-25 12:34:56');

Beachten Sie, dass lomboks `@ EqualsAndHashCode (exclude = {" user "," group "})` an die Gegenmaßnahme angehängt ist, da sich der Hash-Code wiederholt.

Zusammengesetzter Primärschlüssel

Dies ist eine Methode, die keinen alternativen Schlüssel erstellt, sondern einen zusammengesetzten Primärschlüssel verwendet.

@Data
@Entity
@Table(name = "USERS")
public class User {
	@Id
	private Long userId;
	private String username;
	private String password;
	private String email;

	@OneToMany(mappedBy = "userGroupId.user", cascade = CascadeType.ALL)
	private Set<UserGroup> userGroups;
}
@Data
@Entity
@Table(name = "USERS_GROUPS")
@AssociationOverrides({
	@AssociationOverride(name="userGroupId.user", joinColumns=@JoinColumn(name="user_id")),
	@AssociationOverride(name="userGroupId.group", joinColumns=@JoinColumn(name="group_id"))
})
public class UserGroup {
	@Id
	private UserGroupId userGroupId;
	
    private boolean activated;
    private Date registeredDate;
}
@Data
@Embeddable
@EqualsAndHashCode(exclude= {"user", "group"})
public class UserGroupId implements Serializable  {
	private static final long serialVersionUID = 1L;
	
	@ManyToOne(cascade = CascadeType.ALL)
    private User user;
	@ManyToOne(cascade = CascadeType.ALL)
    private Group group;
}
@Data
@Entity
@Table(name = "GROUPS")
public class Group {
	@Id
	private Long groupId;
	private String name;

	@OneToMany(mappedBy = "userGroupId.group", cascade = CascadeType.ALL)
	private Set<UserGroup> userGroups;
}

Eine Abfrage, die JOIN FETCH anstelle des Bonus Lazy Fetch enthält.

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
	
	@Query("select u from User u JOIN FETCH u.userGroups ug JOIN FETCH ug.userGroupId.group g")
	Optional<User> find(@Param("id")Long id);
}

Testdaten.

src/main/resources/data.sql


insert into users(user_id, username, password, email) values (1, 'username', 'pass', '[email protected]');

insert into groups(group_id, name) values (10, 'groupname001');
insert into groups(group_id, name) values (20, 'groupname002');

insert into users_groups(user_id, group_id, activated, registered_date) values (1, 10, true, '2018-04-26 12:34:56');
insert into users_groups(user_id, group_id, activated, registered_date) values (1, 20, true, '2018-04-25 12:34:56');

Recommended Posts

Mit JPA Spalten verwandter Tabellen abrufen
Ich habe versucht, mit Spring Data JPA zu beginnen
Beginnen Sie mit Gradle
Beginnen Sie mit Spring Boot
Ausgabe neunundneunzig mit Stream
Erstellen Sie eine Tabelle und fügen Sie Spalten hinzu