Java 如何使用apche元模型将数据插入csv文件?

Java 如何使用apche元模型将数据插入csv文件?,java,apache-metamodel,Java,Apache Metamodel,我在java项目中工作,我使用apache元模型将数据插入csv文件 代码: 每当我为同一个csv文件调用此方法时,它都会成功插入数据,但会删除旧数据,然后插入新数据,因此每次只插入两行 我想通过多次调用函数插入多个重复行,这意味着新行应该追加,而旧行保持不变 如何实现这一点?将表创建代码移到数据插入方法之外。每次在CSV文件中创建表时,它都会覆盖上一个表及其内容 以下是一种方法: import java.io.File; import org.apache.metamodel.Updateab

我在java项目中工作,我使用apache元模型将数据插入csv文件

代码:

每当我为同一个csv文件调用此方法时,它都会成功插入数据,但会删除旧数据,然后插入新数据,因此每次只插入两行

我想通过多次调用函数插入多个重复行,这意味着新行应该追加,而旧行保持不变


如何实现这一点?

将表创建代码移到数据插入方法之外。每次在CSV文件中创建表时,它都会覆盖上一个表及其内容

以下是一种方法:

import java.io.File;
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.DataContextFactory;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.schema.ColumnType;

public class App {

    public static void main(String[] args) {
        File myFile = new File("c:/tmp/unexisting_file.csv");
        UpdateableDataContext dataContext = DataContextFactory.createCsvDataContext(myFile);
        final Schema schema = dataContext.getDefaultSchema();

        final String tableName = "my_table";
        
        dataContext.executeUpdate(new UpdateScript() {
            @Override
            public void run(UpdateCallback callback) {

                // CREATING A TABLE
                Table table = callback.createTable(schema, tableName)
                        .withColumn("name").ofType(ColumnType.VARCHAR)
                        .withColumn("gender").ofType(ColumnType.CHAR)
                        .withColumn("age").ofType(ColumnType.INTEGER)
                        .execute();
            }
        });

        insertIntoCSVFile(dataContext, tableName);
        insertIntoCSVFile(dataContext, tableName);
    }

    public static void insertIntoCSVFile(final UpdateableDataContext dataContext,
            final String tableName) {

        dataContext.executeUpdate(new UpdateScript() {
            @Override
            public void run(UpdateCallback callback) {

                String schemaName = dataContext.getDefaultSchema().getName();
                Table table = dataContext.getTableByQualifiedLabel(schemaName + "." + tableName);
                      
                // INSERTING SOME ROWS
                callback.insertInto(table).value("name", "John Doe").value("gender", 'M').value("age", 42).execute();
                callback.insertInto(table).value("name", "Jane Doe").value("gender", 'F').value("age", 42).execute();
            }
        });
    }
}
在本例中,main方法负责创建表。然后,该方法调用数据插入方法两次,传入相关的上下文和表名

生成的文件内容包括:

"name","gender","age"
"John Doe","M","42"
"Jane Doe","F","42"
"John Doe","M","42"
"Jane Doe","F","42"
有关更多信息,请参见的语义-具体而言:

使用(新)表结构创建或覆盖CSV文件

更新

在尝试创建(再次)表之前,可以通过检查表是否已存在来防止数据被覆盖

下面是一个简单的示例,展示了该方法:

import java.io.File;
import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.DataContextFactory;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.schema.ColumnType;

public class App {

    public static void main(String[] args) {
        File myFile = new File("c:/tmp/unexisting_file.csv");
        UpdateableDataContext dataContext = DataContextFactory.createCsvDataContext(myFile);
        final Schema schema = dataContext.getDefaultSchema();

        final String tableName = "my_table";
        
        dataContext.executeUpdate(new UpdateScript() {
            @Override
            public void run(UpdateCallback callback) {

                // CREATING A TABLE
                Table table = callback.createTable(schema, tableName)
                        .withColumn("name").ofType(ColumnType.VARCHAR)
                        .withColumn("gender").ofType(ColumnType.CHAR)
                        .withColumn("age").ofType(ColumnType.INTEGER)
                        .execute();
            }
        });

        insertIntoCSVFile(dataContext, tableName);
        insertIntoCSVFile(dataContext, tableName);
    }

    public static void insertIntoCSVFile(final UpdateableDataContext dataContext,
            final String tableName) {

        dataContext.executeUpdate(new UpdateScript() {
            @Override
            public void run(UpdateCallback callback) {

                String schemaName = dataContext.getDefaultSchema().getName();
                Table table = dataContext.getTableByQualifiedLabel(schemaName + "." + tableName);
                      
                // INSERTING SOME ROWS
                callback.insertInto(table).value("name", "John Doe").value("gender", 'M').value("age", 42).execute();
                callback.insertInto(table).value("name", "Jane Doe").value("gender", 'F').value("age", 42).execute();
            }
        });
    }
}
首先,更改表名,使其与文件名匹配:

final String tableName = "unexisting_file.csv";
这是因为元模型将其用作CSV文件中表的默认表名。我们可以使用它来检查是否已经创建了表:

if (!tableExists()) {
    createTable();
}
使用上述方法,下面是一个完整的示例:

import org.apache.metamodel.UpdateableDataContext;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.csv.CsvConfiguration;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.util.Resource;
import org.apache.metamodel.util.FileResource;

public class CsvDemo {

    private final String tableName;
    private final UpdateableDataContext dataContext;
    
    public CsvDemo() {
        this.tableName = "example.csv";
        Resource resource = new FileResource("c:/tmp/" + tableName);
        CsvConfiguration configuration = new CsvConfiguration();
        this.dataContext = new CsvDataContext(resource, configuration);
    }
    
    public void doWork() {
        if (!tableExists()) {
            createTable();
        }
        appendData();
    }

    private boolean tableExists() {
        return getTable() != null;
    }
    
    private Table getTable() {
        return dataContext.getDefaultSchema().getTableByName(tableName);
    }

    private void createTable() {
        dataContext.executeUpdate(new UpdateScript() {
            @Override
            public void run(UpdateCallback callback) {
                callback.createTable(dataContext.getDefaultSchema(), tableName)
                        .withColumn("name").ofType(ColumnType.VARCHAR)
                        .withColumn("gender").ofType(ColumnType.CHAR)
                        .withColumn("age").ofType(ColumnType.INTEGER)
                        .execute();
            }
        });
    }
    
    private void appendData() {
        dataContext.executeUpdate(new UpdateScript() {
            final Table table = getTable();
            @Override
            public void run(UpdateCallback callback) {
                callback.insertInto(table).value("name", "John Doe")
                        .value("gender", 'M').value("age", 42).execute();
                callback.insertInto(table).value("name", "Jane Doe")
                        .value("gender", 'F').value("age", 42).execute();
            }
        });
    }

}

现在,您将仅在CSV文件中创建尚不存在的表。如果它确实存在,那么您的附加数据将附加到文件中已有的任何数据。

它正在工作,但当main方法执行时,它将插入4行,如果我再次运行main方法,它将删除旧行并插入新行,那么我如何实现这一点?所以我希望无论何时调用main方法,它都应该在不删除旧行的情况下插入新行。Csv文件正在以appned模式打开,因此每次数据都在发送而不是覆盖。字符串csvFileName=“example.csv”;CSVWriter writer=new-CSVWriter(new-FileWriter(csvFileName,true));String[]record=“David,M,40”。拆分(“,”);writer.writeNext(记录);writer.close();因此,我可以使用apache元模型实现这一点,请建议。我添加了一个示例,说明如何检查表是否已经存在。这会阻止您多次创建表。为了更好地显示新的表检查方法,我对更新后的示例进行了一些清理。获取错误:-java.lang.ClassNotFoundException:au.com.bytecode.opencsv.CSVReader in insert语句in appendData()。