如何实现Java应用程序数据/状态的保存/加载功能?

时间:2019-04-12 04:05:16

标签: java

我有一个表示数据的POJO(普通的Java对象)应用程序。

在运行时,应用程序会根据需要操纵并记住数据。

现在我要实现保存/加载功能。


我不是在问基本文件I / O。

我不是在问ObjectOutputStream是否存在。


我发现的选项如下:

1)JSON / XML / YAML库,例如Gson,Jackson

2)滚动您自己的二进制文件格式,使用“序列化代理”模式将所有内容标记为“可序列化”。

选项1不适合,因为我的数据模型具有循环引用。 Gson导致堆栈溢出。

选项2不适合,因为文件应跨平台,并且独立于JVM;它应该可以在台式机和Android Java上运行。

由于模型的复杂性,属性文件显然也不适合。


请不要攻击我的用例;我的数据模型设计得很好。这个例子可能不是。

我现在将给出需要保存的结构类型的示例代码。

class Application {

    //This College is my top level object. It could correspond to an individual save file.
    College college = new College();

    //I would love to be able to just throw this guy into a file.
    SomeLibrary.writeToFile(college);
    //And read another back.
    College college2 = SomeLibrary.readFromFile(anotherCollege);
}

class College {
    //The trees are implemented recursively, so this is actually just the root of each tree.
    Tree<Course> artCourseTree;
    Tree<Course> engineeringCourseTree;
    Tree<Course> businessCourseTree;

    List<Student> maleStudents;
    List<Student> femaleStudents;
}

class Course {
    //Each course only has 2 students in this example. Ignore.
    Student student1;
    Student student2;

    List<Exam> examsInCourse;
    LocalDate courseStartDate;
    Period duration;
}

class Student {
    String name;
    List<Exam> listOfExamsTaken;
}

class Exam {
    Student studentTakingIt;
    LocalDate dateTaken;
    BigDecimal score;
}

如您所见,在该模型中,考试旨在成为层次结构底部的原子对象。但是,不仅学生和课程都引用了它们,而且它们还引用了学生,并且包含非基本体,例如LocalDate和BigDecimal。通过引用不同课程和学生的不同考试子集,该模型具有一定的意义。

我需要保存关系,这些事物的排列,这些事物的任意数量以及它们所保存的数据。

保存和加载这样的模型有什么希望?

在具有此类约束的情况下,有哪些选项可以在这种模型上实现保存/加载功能?


每个java程序滚动自己的二进制文件格式并创建用于对所有内容进行序列化和反序列化的怪异设备,这真的是行业标准吗?是JSON还是?我在这里想念什么?我是否必须以某种方式仅快照VM?为什么没有为此的标准做法?

1 个答案:

答案 0 :(得分:1)

循环引用是一种常见的用例,可以通过提供@JsonManagedReference@JsonBackReference来处理。查看this这样的答案以获取更多详细信息。另一种选择是实现自定义序列化程序并自己解决循环引用。 Here是相同的示例。

但是,在继续使用文件作为数据库之前,请考虑以下方面

  • 您将必须自己管理并发写入。如果处理不当,可能会导致数据损坏/丢失,因为文件天生就不符合ACID
  • 该解决方案无法扩展,因为文件大小将会增加。序列化和反序列化的时间将成比例增加。
  • 您将无法轻松查询文件中存储的数据。您将始终必须先对数据进行反序列化,然后再对POJO进行查询。

我强烈建议您检查小型,快速,独立,高可靠性,功能齐全的SQL数据库引擎SQLite。