Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java spring数据jpa三向交叉表_Java_Spring Boot_Java 8_Spring Data Jpa - Fatal编程技术网

Java spring数据jpa三向交叉表

Java spring数据jpa三向交叉表,java,spring-boot,java-8,spring-data-jpa,Java,Spring Boot,Java 8,Spring Data Jpa,我将试图说明我很快将要实现的目标。。。 假设我有一个用户表: USER_INFO USER_ID [PK] USER_NAME PASSWORD 为每个用户定义连接的交集表(N:M-manytoman) 连接类型很简单,如下所示: CONNECTION_TYPE CONNECTION_TYPE_ID [PK] CONNECTION_TYPE_NAME [CHECK allowed values are: FRIEND, FAMILY, ...] 在Spring端,我将我的

我将试图说明我很快将要实现的目标。。。 假设我有一个用户表:

USER_INFO
  USER_ID [PK]
  USER_NAME
  PASSWORD
为每个用户定义连接的交集表(N:M-manytoman)

连接类型很简单,如下所示:

CONNECTION_TYPE
  CONNECTION_TYPE_ID [PK]
  CONNECTION_TYPE_NAME [CHECK allowed values are: FRIEND, FAMILY, ...]
在Spring端,我将我的用户实体定义为:

@Entity
@Table(name = "USER_INFO")
public class User implements Serializable {
  @Id
  @NotNull
  @Column(name = "USER_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer userId;

  @Column(name = "USER_NAME)
  private String userName;

  @Column(name = "PASSWORD)
  private char[] password;

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "CONNECTION_INFO",
             joinColumns = { @JoinColumn(name = "USER_A_ID") },
             inverseJoinColumns = { @JoinColumn(name = "USER_B_ID") })
  private List<User> connections;

  // ctor, getters, setters, toString, ...
}
现在,我的问题是,如何根据Connection.Types仅获取给定用户的特定连接?例如,我只想找朋友,或者只想找家人,我想你明白我的意思了。这张三向交叉表让我头疼

@澄清: 我想要的是在我的用户实体上定义的一个@ManyToMany关系,它恰好有额外的列。我知道在这种情况下,会有类似的解决方案。在我的例子中,这个额外的列是第三个表(USER_INFO(保存用户)、CONNECTION_INFO(保存用户之间的连接N:M+关于连接类型的信息)、CONNECTION_type)的外键(完全不正确):

public interface UserRepository扩展了JpaRepository{
按连接类型列出FindUserFriends(正在搜索好友的用户,第三个表中的字符串连接类型);
}
这就是我想要的。我知道,通过为交集表创建一个实体并打破多对一多和多对一,使用一个普通的额外列很简单,碰巧我有第三个表和一个可能的多对一(1个连接可以有1个关联类型,而一个类型可以链接到任意数量的连接)在具有连接类型表的相交图元上


我希望它能把一切都清理干净。以上只是我从未想象过的一个样本,因为我想让它看起来简单,也许我把它做得太简单了。)。我设法解决了这个问题,但我不确定这是不是正确的方法。总之,我的解决方案。考虑下面3个表:

create table USER_INFO (
  USER_ID int not null primary key,
  USER_NAME varchar(16),
  PASSWORD varchar(64)
);

create table CONNECTION_TYPE (
  CONNECTION_TYPE_ID int not null primary key,
  CONNECTION_TYPE_NAME varchar(16) not null,
  CONNECTION_TYPE_DESCRIPTION varchar(128),
  unique (CONNECTION_TYPE_NAME)
);

create table CONNECTION (
  CONNECTION_ID int not null primary key,
  CONNECTION_TYPE_ID int,
  RELATED_USER_ID int,
  RELATING_USER_ID int,
  foreign key (CONNECTION_TYPE_ID) references CONNECTION_TYPE(CONNECTION_TYPE_ID),
  foreign key (RELATED_USER_ID) references USER_INFO(USER_ID),
  foreign key (RELATING_USER_ID) references USER_INFO(USER_ID)
通过以上3个表,我想提供一个功能,根据连接类型为任何给定用户获取连接。为此,我创建了3个实体,如下所示:

@Entity
@Table(name = "CONNECTION_TYPE")
public class ConnectionType implements Serializable {
  @Id
  @NotNull
  @Column(name = "CONNECTION_TYPE_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer connectionTypeId;

  @NotNull
  @Column(name = "CONNECTION_TYPE_NAME", unique = true)
  private String connectionTypeName;

  @Column(name = "CONNECTION_TYPE_DESCRIPTION")
  private String connectionTypeDescription;

  ...
}
这里没有什么特别有趣的,我省略了构造函数、getter、setter等,从ConnectionType中,我不想为这个类型的所有连接都有一个映射,这样就没有方向了

@Entity
@Table(name = "CONNECTION")
public class Connection implements Serializable {
  @Id
  @NotNull
  @Column(name = "CONNECTION_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer connectionId;

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "CONNECTION_TYPE_ID", referencedColumnName = "CONNECTION_TYPE_ID")
  private ConnectionType connectionType;

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "RELATED_USER_ID", referencedColumnName = "USER_ID")
  private User relatedUser;

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "RELATING_USER_ID", referencedColumnName = "USER_ID")
  private User relatingUser;

  ...
}
如果没有其他人,至少对我来说,这个更有趣。这将是我的交集表实体。使用的ConnectionType具有单向映射,其中包含多个Connection,因为一个连接可以有一个ConnectionType,而相同的ConnectionType可以重复用于任意数量的连接。 其他2个用户映射我肯定搞糟了,但在此之前,这里是用户实体:

@Entity
@Table(name = "USER_INFO")
public class User implements Serializable {
  @Id
  @NotNull
  @Column(name = "USER_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer userId;

  @NotNull
  @Column(name = "USER_NAME")
  private String userName;

  @NotNull
  @Column(name = "PASSWORD")
  private char[] password;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "relatedUser", cascade = CascadeType.ALL, orphanRemoval = true)
  private List<Connection> connections;
}

这似乎也起作用。同样,不确定这是不是正确的方法,但至少它能起作用。

< P>我设法解决了这个问题,但我不确定这是不是正确的方法。总之,这是我的解决方案。考虑下面3个表:

create table USER_INFO (
  USER_ID int not null primary key,
  USER_NAME varchar(16),
  PASSWORD varchar(64)
);

create table CONNECTION_TYPE (
  CONNECTION_TYPE_ID int not null primary key,
  CONNECTION_TYPE_NAME varchar(16) not null,
  CONNECTION_TYPE_DESCRIPTION varchar(128),
  unique (CONNECTION_TYPE_NAME)
);

create table CONNECTION (
  CONNECTION_ID int not null primary key,
  CONNECTION_TYPE_ID int,
  RELATED_USER_ID int,
  RELATING_USER_ID int,
  foreign key (CONNECTION_TYPE_ID) references CONNECTION_TYPE(CONNECTION_TYPE_ID),
  foreign key (RELATED_USER_ID) references USER_INFO(USER_ID),
  foreign key (RELATING_USER_ID) references USER_INFO(USER_ID)
通过以上3个表,我想提供一个功能,根据连接类型为任何给定用户获取连接。为此,我创建了3个实体,如下所示:

@Entity
@Table(name = "CONNECTION_TYPE")
public class ConnectionType implements Serializable {
  @Id
  @NotNull
  @Column(name = "CONNECTION_TYPE_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer connectionTypeId;

  @NotNull
  @Column(name = "CONNECTION_TYPE_NAME", unique = true)
  private String connectionTypeName;

  @Column(name = "CONNECTION_TYPE_DESCRIPTION")
  private String connectionTypeDescription;

  ...
}
这里没有什么特别有趣的,我省略了构造函数、getter、setter等,从ConnectionType中,我不想为这个类型的所有连接都有一个映射,这样就没有方向了

@Entity
@Table(name = "CONNECTION")
public class Connection implements Serializable {
  @Id
  @NotNull
  @Column(name = "CONNECTION_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer connectionId;

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "CONNECTION_TYPE_ID", referencedColumnName = "CONNECTION_TYPE_ID")
  private ConnectionType connectionType;

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "RELATED_USER_ID", referencedColumnName = "USER_ID")
  private User relatedUser;

  @NotNull
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "RELATING_USER_ID", referencedColumnName = "USER_ID")
  private User relatingUser;

  ...
}
如果没有其他人,至少对我来说,这个更有趣。这将是我的交集表实体。使用的ConnectionType具有单向映射,其中包含多个Connection,因为一个连接可以有一个ConnectionType,而相同的ConnectionType可以重复用于任意数量的连接。 其他2个用户映射我肯定搞糟了,但在此之前,这里是用户实体:

@Entity
@Table(name = "USER_INFO")
public class User implements Serializable {
  @Id
  @NotNull
  @Column(name = "USER_ID")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer userId;

  @NotNull
  @Column(name = "USER_NAME")
  private String userName;

  @NotNull
  @Column(name = "PASSWORD")
  private char[] password;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "relatedUser", cascade = CascadeType.ALL, orphanRemoval = true)
  private List<Connection> connections;
}

它似乎也能工作。同样,不确定这是否是正确的方法,但至少它能完成任务。

如果它只有固定值,为什么还要添加表?它不是枚举,而是实体。因此,您应该有一个实体,而不是枚举
连接类型。您当前的设置将失败,因为
连接信息
table没有这两列。哇,很好的捕捉…我完全搞砸了命名…我希望我现在能正确地清理它。我没有交集表的实体:)。在第一点上,这里的附加表i必须能够定义新的连接类型。您不能只定义新的连接类型,因为您已经在java代码的枚举中硬编码了它们。因此,它还需要更改代码。如果要将一个实体映射到多个表,则您的
连接
应具有
@Table
和[
@SecondaryTable
])(
)表注释。您的
User`应该有一个
连接
实体列表,而不是
用户
实体列表。然后您可以为特定类型编写查询。这只是一个示例。。。基本上,我想要的是一个多个关系,其中有一个额外的列,恰好是第三个表的外键。然后,在存储库中,我想定义一个函数,比如:findUserConnectionsByConnectionTypeConnectionTypeName,或者类似的函数,如果我正确获取书籍,它会由spring boot自动生成。我不知道你链接我的第二个表是什么,但我90%确定我不需要它。你有3个表和2个实体。因此,您必须添加一个实体,或者为要映射到2个表的1个实体添加额外的映射(
@SecondaryTable
注释)。只需为
用户
实体中的用户列表添加一个
@manytomy
,该实体将不会执行此任务。这必须是一个
连接
的列表,它要么有一个
连接类型
实体链接,要么是两个表的集合。如果它只有一个
@Service
public interface UserService {
    List<User> findAllConnectionsForUserById(Integer userId);
}
@Override
@Transactional
public List<User> findAllConnectionsForUserById(Integer userId) {
    Optional<User> _user = userRepository.findById(userId);
    // omitted exception handling...
    User user = _user.get();
    List<Connection> connections = user.getConnections();

    return connections.strea.map(Connection::getRelatingUser).collect(Collectors.toList());
connections.stream().filter(c -> c.getConnectionType().getConnectionTypeName().equals("FRIEND")).map(Connection::getRelatingUser).collect(Collectors.toList());