sla*_*dan 8 java xml jaxb file-storage
在我的小型独立Java应用程序中,我想存储信息.
我的要求:
因此,我想使用jaxb将所有信息存储在文件系统中的简单XML文件中.我的示例应用程序看起来像这样(将所有代码复制到一个名为Application.java和编译的文件中,没有其他要求!):
@XmlRootElement
class DataStorage {
String emailAddress;
List<String> familyMembers;
// List<Address> addresses;
}
public class Application {
private static JAXBContext jc;
private static File storageLocation = new File("data.xml");
public static void main(String[] args) throws Exception {
jc = JAXBContext.newInstance(DataStorage.class);
DataStorage dataStorage = load();
// the main application will be executed here
// data manipulation like this:
dataStorage.emailAddress = "me@example.com";
dataStorage.familyMembers.add("Mike");
save(dataStorage);
}
protected static DataStorage load() throws JAXBException {
if (storageLocation.exists()) {
StreamSource source = new StreamSource(storageLocation);
return (DataStorage) jc.createUnmarshaller().unmarshal(source);
}
return new DataStorage();
}
protected static void save(DataStorage dataStorage) throws JAXBException {
jc.createMarshaller().marshal(dataStorage, storageLocation);
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能克服这些缺点?
看到你的要求:
我相信基于XML的文件系统是不够的.如果你认为一个适当的关系数据库是一个过度杀伤,你仍然可以去一个H2数据库.这是一个超轻量级的数据库,它可以解决上面的所有这些问题(即使不是很完美,但肯定比手写的XML数据库好得多),并且仍然很容易设置和维护.
您可以将其配置为将更改保留到磁盘,可以配置为作为独立服务器运行并接受多个连接,也可以在嵌入模式下作为应用程序的一部分运行.
关于"如何保存数据"部分:
如果您不想使用任何高级ORM库(如Hibernate或任何其他JPA实现),您仍然可以使用普通的旧JDBC.或者至少有一些Spring-JDBC,它非常轻巧且易于使用.
"你拯救了什么"
H2是关系数据库.所以无论你保存什么,它都会以列的形式出现.但!如果您确实不打算查询数据(既不在其上应用迁移脚本),则可以选择保存已经XML序列化的对象.您可以轻松定义具有ID +"data"varchar列的表,并将xml保存在那里.H2DB中的数据长度没有限制.
注意:在关系数据库中保存XML通常不是一个好主意.我只建议您评估此选项,因为您似乎确信您只需要SQL实现可以提供的某些功能集.
回答你提到的三个问题:
为什么会导致不一致呢?如果您的意思是多个并发编辑会导致不一致,您只需在编辑之前锁定文件即可。最简单的方法是在文件旁边创建一个锁定文件。在开始编辑之前,只需检查锁定文件是否存在。
如果您想让它更具容错性,您还可以对文件设置超时。例如,锁定文件的有效期为 10 分钟。您可以在锁定文件中写入随机生成的 uuid,在保存之前,您可以检查 uuid 是否仍然匹配。
我认为这与第一点相同。
这可以通过使写入原子化或文件不可变来解决。要使其原子化,只需复制文件,然后在副本上进行编辑,而不是直接编辑文件。保存副本后,只需重命名文件即可。但如果您想更安全,您始终可以执行诸如在文件上附加时间戳之类的操作,并且永远不要编辑或删除文件。因此,每次进行编辑时,您都会创建它的副本,并在文件上附加更新的时间戳。对于阅读,您将始终阅读最新的内容。