【问题标题】:Use XML as database in Java在 Java 中使用 XML 作为数据库
【发布时间】:2011-01-30 12:12:23
【问题描述】:

我想使用 XML 文件作为数据库。我想在哪里存储一个 ID 及其相应的字符串路径。喜欢:

<item>
     <Id>id</Id>
     <Path>path</Path>
</item> 

或类似的。 现在在运行时,名称-值集合将加载存储在 XML 文档中的这些数据,并根据一些数据检查 Id,并将进行相应处理,并更新(即更改相同 Id 的路径)和删除(删除现有项目)该 XML 文件中需要项目。 希望我能让你明白我的想法! 我没有代码可以显示,因为这是概念级别的。我需要的是如何实现这一点,是否有任何我可以阅读的教程或可用的 API 可以做到这一点? 谢谢你。我在 JAVA 中。

【问题讨论】:

  • 如果你需要类似数据库的东西,那么使用数据库。您正在重新发明方轮。
  • 是的,使用mysql这样的数据库而不是XML会更容易,但是XML也可以像这种情况下用作数据库。
  • 可以使用。但你为什么要这样做?有几个一流的 DBMS 可用,所有这些的性能和扩展性都比这(实际上)好一百倍,并且需要您编写更少的代码。更不用说 XML 对于数据库格式来说是一个糟糕的选择(对于 DB 之间的序列化/交换,这很好 - 但不是这样)。
  • basexxml 的一个这样的数据库,恰好写在Java

标签: java xml


【解决方案1】:

另一方面,如果您使用提供 XML 数据库 API 的 XML 数据库系统,则您更接近 XML。喜欢ExistApache Xindice

【讨论】:

    【解决方案2】:

    我认为这对您的应用程序来说实际上是一个好主意 - 这是一个完全不同的讨论。

    我会将其视为三个独立的问题:

    • 从磁盘加载 XML 文件并将其存储在适当的数据结构中(例如 Map&lt;String, String&gt;
    • 适当地操作集合(获取、添加或删除条目)
    • 将 XML 文件保存回磁盘

    您的大部分代码可能不知道您的集合将存储在 XML 中。

    有多种可用于 Java 的 XML API - 内置的 API 使用起来相当痛苦。我不知道最新和最伟大的是什么,但从历史上看,JDOM 已被证明相当简单。

    请注意,您对内存中集合的选择将取决于您的要求 - 例如,排序是否重要?

    【讨论】:

    • 非常感谢您的建议。顺序并不重要。
    【解决方案3】:

    这将严重扩展,因为每当您更改数据时都必须重写整个 XML 文件。想象一下,您有 100000 个条目,并考虑在使用此数据库时您需要做多少工作。

    不过,作为内存中 hashmap 的序列化形式,这是另一回事,因为 HashMap 查找速度非常快。然而,序列化 hashmap 最简单、最快的方法是使用标准库中内置的 XMLSerializer。

    【讨论】:

    • 是否使用 XML 序列化程序类似于内存中索引的随机访问文件?
    • @Xorty,不,它为在另一个 JVM 中重新创建完整的 hashmap 对象创建了一个配方(由字节流组成)。然后可以将所述字节流保存到文件中或发送到其他地方。
    【解决方案4】:

    BaseX 是一个数据库 XML,可以满足您的需求!

    http://basex.org/

    【讨论】:

      【解决方案5】:

      我更喜欢使用Joox,这是一个流畅的 api 来管理 jquery 风格的 dom。没有依赖,可以用maven安装。

      仅仅因为java性能,使用属性比使用元素要好*(来自colages的经验)。

      所以我建议你这样使用你的模型:

      <items>
           <item id="1" path="path"/>
           ...
      </items>
      

      我使用 Joox 为你创建了这个类:

      package test;
      import static org.joox.JOOX.$;
      
      import java.io.ByteArrayInputStream;
      import java.io.File;
      import java.io.IOException;
      import java.io.UnsupportedEncodingException;
      
      import org.apache.commons.io.FileUtils;
      import org.joox.JOOX;
      import org.joox.Match;
      import org.xml.sax.SAXException;
          public class XmlDBTable{
              private Match dbMatch;
              private String xmlBeforeCommit;
              private boolean building;
              private String root;
              private String item;
              private String itemXpathTemplate;
              private File file;
              public void setRoot(String root){
                  this.root=root;
              }
              public void setItemTemplate(String item){
                  this.item=item;
              }
              public void setItemXpathTemplate(String itemXpath){
                  this.itemXpathTemplate=itemXpath;
              }
              public void setFile(String path){
                  file=new File(path);
                  if(file.exists())
                      try {
                          dbMatch=$(file);
                      } catch (SAXException | IOException e) {
                          e.printStackTrace();
                      }
              }
              public Match xml() {
                  Match dbMatch= dbMatch();
                  building=true;
                  return dbMatch;
              }
              public void insertOrUpdate(String keyEqualsValueList){
                  Match dbMatch= dbMatch();
                  String newItem=item;
                  if(keyEqualsValueList.contains(",")) {
                      String[] keyValues=keyEqualsValueList.split(",");
                      for(String keyValue:keyValues) {
                          String key=keyValue.split("=")[0].toUpperCase();
                          String value=keyValue.split("=")[1];
                          newItem=newItem.replace(key,value);
                      }
                  }else {
                      String key=keyEqualsValueList.split("=")[0].toUpperCase();
                      String value=keyEqualsValueList.split("=")[1];
                      newItem=newItem.replace(key,value);
                  }
                  String id=itemId(newItem);
                  String itemXpath=itemXpath(id);
                  Match item=$(dbMatch).xpath(itemXpath);
                  if ($(item).isEmpty()){
                      $(dbMatch).append(newItem);
                  }else{
                      if(keyEqualsValueList.contains(",")) {
                          String[] keyValues=keyEqualsValueList.split(",");
                          for(String keyValue:keyValues) {
                              String key=keyValue.split("=")[0];
                              String value=keyValue.split("=")[1];
                              $(dbMatch).xpath(itemXpath).attr(key,value);
                          }
                      }else {
                          String key=keyEqualsValueList.split("=")[0].toUpperCase();
                          String value=keyEqualsValueList.split("=")[1];
                          $(dbMatch).xpath(itemXpath).attr(key,value);
                      }
                  }
                  building=true;
                  System.out.println("Item id "+id+" added ok");
              }
              public void delete(String id){
                  Match dbMatch= dbMatch();
                  String itemXpath=itemXpath(id);
                  Match item=$(dbMatch).xpath(itemXpath);
                  if (!$(item).isEmpty()){
                      $(dbMatch).xpath(itemXpath).remove();
                      System.out.println("Item id "+id+" deleted ok");
                  }else{
                      System.out.println("The item didn't exist");
                  }
                  building=true;
              }
              private String itemId(String item) {
                  String id=xmlStrToMatch(item, "UTF-8").attr("id");
                  return id;
              }
              private String itemXpath(String id) {
                  String itemXpath=itemXpathTemplate.replace("ID", id);
                  return itemXpath;
              }
              public synchronized boolean commit(){
                  try {
                      FileUtils.writeStringToFile(file,dbMatch().toString(),"UTF-8");
                      building=false;
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
                  return true;
              }
              public boolean rollBack(){
                  dbMatch();
                  dbMatch=xmlStrToMatch(xmlBeforeCommit, "UTF-8");
                  System.out.println("Removed all changes after last commit");
                  building=false;
                  return true;
              }
              private Match dbMatch(){
                  if(dbMatch==null){
                      dbMatch=xmlStrToMatch(root,"UTF-8");
                  }
                  if(!building){
                      if(xmlBeforeCommit!=null){
                          xmlBeforeCommit=dbMatch.toString();
                      }else {
                          xmlBeforeCommit=root;
                      }
                  }
                  return dbMatch;
              }
              private static Match xmlStrToMatch(String xmlString, String encoding){
                  Match match = null;
                  try {
                      match = $(JOOX.builder().parse(new ByteArrayInputStream(xmlString.getBytes(encoding))));
                  } catch (UnsupportedEncodingException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  } catch (SAXException  e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  return match;
              }
          }
      

      要使用它,你可以使用:

      package test;
      
      public class ItemsTable{
          public static void main(String... args){
              XmlDBTable itemsTable= new XmlDBTable();
              itemsTable.setRoot("<items></items>");
              itemsTable.setItemTemplate("<item id=\"ID\" path=\"PATH\"/>");
              itemsTable.setItemXpathTemplate("/items/item[@id='ID']");
              itemsTable.setFile("C:\\users\\jesus\\Downloads\\temp\\itemsTable.xml");
              itemsTable.insertOrUpdate("id=1,path=myPath");
              itemsTable.insertOrUpdate("id=2,path=myPath2");
              itemsTable.delete("2");
              itemsTable.insertOrUpdate("id=3,path=myPath3");
              //save changes
              itemsTable.commit();
              //you can use all power of Joox Methods too to do the same or more
              //Select path from item with id=1
              String path1=itemsTable.xml().xpath("//item[@id='1']").attr("path");
              //print it
              System.out.println(path1);
              //Add subItem id=0 to item with id=1
              itemsTable.xml().xpath("//item[@id='1']").append("<subitem id=\"0\" color=\"black\">Super Subitem</subitem>");
              //print the text of subitem recently added
              String subitem1=itemsTable.xml().xpath("//subitem[@id='0']").text();
              System.out.println(subitem1);
              //save changes
              itemsTable.commit();
              //Add subItem id=1 to item with id=1
              itemsTable.xml().xpath("//item[@id='1']").append("<subitem id=\"1\" color=\"blue\">Super Subitem</subitem>");
              //rollback changes after last commit (subitem id=1 in item id=1 deleted)
              itemsTable.rollBack();
              itemsTable.insertOrUpdate("id=4,path=myPath4");
              //save changes
              itemsTable.commit();
          }
      }
      

      *请注意字符串模板使用大写作为默认值,例如id="身份证" *另一种方法insertOrUpdate 和delete 仅适用于作为列的属性。 *您可以使用Joox方法插入新行,如图所示。

      这是生成的文件:

      <items>
          <item id="1" path="myPath">
              <subitem color="black" id="0">Super Subitem</subitem>
          </item>
          <item id="3" path="myPath3"/>
          <item id="4" path="myPath4"/>
      </items>
      

      这是控制台的输出:

      Item id 2 added ok
      Item id 2 deleted ok
      Item id 3 added ok
      myPath
      Super Subitem
      Removed all changes after last commit
      Item id 4 added ok
      

      我的 Maven 依赖项:

      <dependency>
          <groupId>org.jooq</groupId>
          <artifactId>joox</artifactId>
          <version>1.4.0</version>
      </dependency>
      <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.5</version>
      </dependency>
      

      【讨论】:

        猜你喜欢
        • 2012-01-22
        • 1970-01-01
        • 1970-01-01
        • 2015-12-08
        • 1970-01-01
        • 2012-10-12
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        相关资源
        最近更新 更多