Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.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 减少hibernate中的数据量,同时仍使用hibernate功能_Java_Mysql_Spring_Spring Boot_Hibernate - Fatal编程技术网

Java 减少hibernate中的数据量,同时仍使用hibernate功能

Java 减少hibernate中的数据量,同时仍使用hibernate功能,java,mysql,spring,spring-boot,hibernate,Java,Mysql,Spring,Spring Boot,Hibernate,假设我有这样一个数据库:(不是实际的数据库,但足以说明问题) Complete和total字段只是isComplete和每个条件(每个任务列表或每个项目)的总任务记录的计数器。它们被重复(数据库去规范化?)以便于获取,因为在每个阶段我都希望包含一个进度计数器 我有这样的实体: // other fields, getter and setters omitted for brevity @Entity @Table(name = "user_info") public c

假设我有这样一个数据库:(不是实际的数据库,但足以说明问题)

Complete和total字段只是isComplete和每个条件(每个任务列表或每个项目)的总任务记录的计数器。它们被重复(数据库去规范化?)以便于获取,因为在每个阶段我都希望包含一个进度计数器

我有这样的实体:

// other fields, getter and setters omitted for brevity

@Entity
@Table(name = "user_info")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    @Column(name = "username")
    private String userName;
    
    @Column(name = "image")
    private String imageUrl;
    
    @ManyToMany
    @JoinTable(name = "project_user",
    joinColumns = @JoinColumn(name="user_id"),
    inverseJoinColumns = @JoinColumn(name="project_id"))
    private Set<Project> projects;
}

@Entity
@Table(name = "project")
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    @Column(name = "name")
    private String name;
    
    @OneToOne
    @JoinColumn(name = "creator_id")
    private User creator;
    
    @Column(name = "image")
    private String imageUrl;
    
    @Column(name = "creation_date")
    private Date createdAt;
    
    @Column(name = "total")
    private int total;
    
    @Column(name = "complete")
    private int complete;
    
    @ManyToMany
    @JoinTable(name = "project_user",
    joinColumns = @JoinColumn(name="project_id"),
    inverseJoinColumns = @JoinColumn(name="user_id"))
    @JsonIgnoreProperties(value = {"projects", "connected", "notifications"})
    private Set<User> members;
    
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "project_id")
    private Set<TaskList> taskLists;
}


@Entity
@Table(name = "task_list")
public class TaskList {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "image")
    private String imageUrl;
    
    @Column(name = "creation_date")
    private Date createdAt;
    
    @Column(name = "complete")
    private int complete;
    
    @Column(name = "total")
    private int total;
    
    @OneToMany
    @JoinColumn(name = "task_list_id")
    private Set<Task> tasks;
}

@Entity
@Table(name = "task")
public class Task {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    @Column(name = "description")
    private String description;
    
    @Column(name = "title")
    private String title;
    
    @ElementCollection
    @CollectionTable(name = "task_images", joinColumns = @JoinColumn(name="task_id"))
    @Column(name = "image")
    private Set<String> imageUrls;
    
    @OneToMany
    @JoinColumn(name = "task_id")
    private Set<TaskMember> handledBy;
    
    @Transient
    private Set<Note> notes;
    
    @Column(name = "complete")
    private boolean complete;
    
    @Column(name = "creation_date")
    private Date createdAt;
    
    @Column(name = "completion_date")
    private Date completeDate;
    
}


@Entity
@Table(name = "task_handler")
public class TaskMember {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    
    @OneToOne
    @JoinColumn(name = "id", referencedColumnName = "user_id")
    private User user;
    
    @Column(name = "assignmentType")
    private String assignmentType; //maybe change to enum?
}

user: {
//fields
projects: [{
             //fields
             tasklist: [{
                         //fields
                         tasks: [{
                                 //fields
                                }]
                       }]
          }]
}
这不仅是一个巨大的响应(包含几乎所有的数据),而且占用了服务器上的大量空间。 我想要的是:

request to sign in:

user: {
//fields
}

request to endpoint1 with parameter user id

projects: [{
// fields
}]

request to endpoint2 with parameter project id
tasklist: [{
// fields
}]

request to endpoint3 with parameter tasklist id
tasks: [{
// fields
}]

这将使在尽可能使api无状态的情况下更容易更新客户端的任何更改(除了会话和安全性内容之外,我不希望服务器内存中有任何数据)

我知道有一种方法是删除实体,并以纯sql的方式进行操作,但这意味着我失去了hibernate的功能,如级联和数据完整性

我的选择是什么?如果实体关系或数据库设计中存在错误,请告知我。 提前感谢:)

编辑:我不使用任何自定义序列化程序类,只使用基类jackson。用@jsonIgnoreProperty注释属性可以防止对不需要的字段进行序列化,但我认为这不会首先阻止获取它们(这里可能是错误的)

@RestController
公共类Hello控制器{
@自动连线
私人用户服务;
@GetMapping(“/”)
公共列表getAllData(){
//只运行一个基本的“来自用户”查询
List users=userService.findAll();
返回用户;
}
}

显然,我误解了hibernate的工作原理。在对它有了更多的了解和玩弄之后。我相信我终于明白了。事实证明,即使它是相关的,除非请求它,否则它不会获取数据

一个选项是在隐藏属性上使用jsonignore来阻止jackson访问getter(这反过来又不会获取对象),但这意味着我以后无法自定义它

更好的方法是使用DTO


感谢@Thomas的评论显然,我误解了hibernate的工作原理。在对它有了更多的了解和玩弄之后。我相信我终于明白了。事实证明,即使它是相关的,除非请求它,否则它不会获取数据

一个选项是在隐藏属性上使用jsonignore来阻止jackson访问getter(这反过来又不会获取对象),但这意味着我以后无法自定义它

更好的方法是使用DTO


谢谢@Thomas的评论

我想你想向用户展示他的任务,对吗?因此,不要获取
Project
s,而是通过
TaskHandler
和所有这些东西。好吧,提供查询/存储库方法来获取端点所需的数据应该不会太难。你面临什么问题?@M.Prokhorov不,我想向用户展示他的项目。然后,当他单击一个项目时,显示任务列表。单击任务列表将显示任务。(我知道如何处理点击和请求)@Movsac,那么具体的问题是什么?将抓取定义为惰性,并确保序列化程序不会对其进行拉取。如果您还展示了一个序列化代码的示例,那么会更简单。这可能是问题所在:您直接将内部模型(实体)暴露给外部世界(REST客户端)。相反,您可能希望构建另一个模型,例如,使用仅表示该端点所需数据的数据传输对象(使用映射库(如mapstruct)移动数据)或通过提供自定义序列化/反序列化(Jackson实现这一点的一种方法可能是mixin——为每个端点提供具有不同注释的mixin)。我认为您希望向用户显示其任务,对吗?因此,不要获取
Project
s,而是通过
TaskHandler
和所有这些东西。好吧,提供查询/存储库方法来获取端点所需的数据应该不会太难。您面临什么问题?@M.Prokhorov不,我想向用户展示的是他的项目。然后当他单击项目时,显示任务列表。单击任务列表显示任务。(我知道如何处理单击和请求)@Movsac,那么具体的问题是什么呢?将抓取定义为惰性,并确保序列化程序不会对其进行处理。如果您也展示了序列化代码的示例,则会更简单。这可能就是问题所在:您将内部模型(实体)直接暴露给外部世界(REST客户端)。您可能希望改为构建另一个模型,例如,使用仅表示该端点所需数据的数据传输对象(使用映射库(如mapstruct)移动数据)或通过提供自定义序列化/反序列化(Jackson实现这一点的一种方法可能是mixin——为每个端点提供具有不同注释的mixin)。
@RestController
public class HelloController {
    @Autowired
    private UserService userService;

    @GetMapping("/")
    public List<User> getAllData() {
        // just runs a basic "from User" query
        List<User> users = userService.findAll();
        return users;
    }
}