拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 使用 Java 从 JSON 文件将数据导入 MongoDB

使用 Java 从 JSON 文件将数据导入 MongoDB

白鹭 - 2022-04-10 2137 0 2

一、简介

由于这些原因,我们将如何从文件中读取并使用 Spring Boot 将数据导入 MongoDB。这可能有助于使用:数据、教程中的新数据或默认插件列表。使用 JSON 来其构造,因此很自然,我们将使用 JSON 来存储文档可导入文件。作为纯粹的,这种策略还具有易于压缩文本的优点。

此外,根据我们的自定义类型如何在必要时验证我们的输入文件。最后,我们将公开一个 API,以便我们学习可以在 Web 应用程序的运行时使用它。

2.依赖

让我们将这些 Spring Boot 依赖项添加到我们的pom.xml中:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

我们还需要一个正在运行的 MongoDB 实例,这需要正确配置的application.properties文件。

3.导入JSON字符串

将 JSON 转换的最简单的方法是首先将 MongoDB 为“ org.bson.Document”对象。这样表示没有特定类型的通用 MongoDB。因此,我们需要担心它的简单类型为我们可能导入的所有对象创建存储库。

采用 JSON 的(来自、资源或策略转换为字符串,保存它们。通常采用)我们执行得更好,因为单独的插入对象与选择对象,并将其数量减少到Document并使用。MongoTemplate

最重要的是,我们会认为我们的输入每个换行符只有一个 JSON 对象这样,我们可以方便地将我们的两个对象封装到我们将创建的对象ImportUtilsImportJsonService。从我们的服务类开始:

@Service
public class ImportJsonService {
@Autowired
private MongoTemplate mongo;
}

,让我们添加一个将JSON行解析为文档的方法:

private List<Document> generateMongoDocs(List<String> lines) {
List<Document> docs = new ArrayList<>();
for (String json : lines) {
docs.add(Document.parse(json));
}
return docs;
}

然后我们添加需要Document插入列表的collection方法。另外,我们可以通过某种情况在操作可能会部分失败。exception cause

private int insertInto(String collection, List<Document> mongoDocs) {
try {
Collection<Document> inserts = mongo.insert(mongoDocs, collection);
return inserts.size();
} catch (DataIntegrityViolationException e) {
if (e.getCause() instanceof MongoBulkWriteException) {
return ((MongoBulkWriteException) e.getCause())
.getWriteResult()
.getInsertedCount();
}
return 0;
}
}

最后,让结合这些方法。这个接受并返回一个文本显示,我们可以读取多少行与成功输入了多少行:

public String importTo(String collection, List<String> jsonLines) {
List<Document> mongoDocs = generateMongoDocs(jsonLines);
int inserts = insertInto(collection, mongoDocs);
return inserts + "/" + jsonLines.size();
}

4. 用例

现在,我们可以准备一些好的处理输入。让我们创建ImportUtils类来帮助我们开始。这些将负责将输入转换为 JSON 行。它只包含初始化方法。让我们从阅读一个简单的示例String

public static List<String> lines(String json) {
String[] split = json.split("[\\r\\n]+");
return Arrays.asList(split);
}

使用换行作为分隔符列表方法,因此我们可以很好地表达 Windows 并转换成多行的行尾。

public static List<String> lines(File file) {
return Files.readAllLines(file.toPath());
}

,我们完成了一个将类路径资源转换为列表的方法:

public static List<String> linesFromResource(String resource) {
Resource input = new ClassPathResource(resource);
Path path = input.getFile().toPath();
return Files.readAllLines(path);
}

4.1。在启动期间使用CLI导入文件

使用中,我们将实现程序参数导入的功能。我们将利用 Spring BootApplicationRunner在时执行此操作,我们可以在应用程序的第一个参数文件中执行此操作的参数来定义导入示例。

@SpringBootApplication
public class SpringBootJsonConvertFileApplication implements ApplicationRunner {
private static final String RESOURCE_PREFIX = "classpath:";
@Autowired
private ImportJsonService importService;
public static void main(String ... args) {
SpringApplication.run(SpringBootPersistenceApplication.class, args);
}
@Override
public void run(ApplicationArguments args) {
if (args.containsOption("import")) {
String collection = args.getOptionValues("collection")
.get(0);
List<String> sources = args.getOptionValues("import");
for (String source : sources) {
List<String> jsonLines = new ArrayList<>();
if (source.startsWith(RESOURCE_PREFIX)) {
String resource = source.substring(RESOURCE_PREFIX.length());
jsonLines = ImportUtils.linesFromResource(resource);
} else {
jsonLines = ImportUtils.lines(new File(source));
}
String result = importService.importTo(collection, jsonLines);
log.info(source + " - result: " + result);
}
}
}
}

使用getOptionValues()多个文件。我们的类路径或来自我们的系统的文件。我们使用它们的RESOURCE_PREFIX类别。classpath:,而不是从文件系统中读取。之后,它们都将被导入到的collection中。

让我们通过src/main/resources/data.json.log在下创建一个文件来开始使用我们的应用程序:

{"name":"Book A", "genre": "Comedy"}
{"name":"Book B", "genre": "Thriller"}
{"name":"Book C", "genre": "Drama"}

在我们的示例中,将导入两个文件,一个来自类的路径,一个来自文件系统:

java -cp target/spring-boot-persistence-mongodb/WEB-INF/lib/*:target/spring-boot-persistence-mongodb/WEB-INF/classes \
-Djdk.tls.client.protocols=TLSv1.2 \
com.baeldung.SpringBootPersistenceApplication \
--import=classpath:data.json.log \
--import=/tmp/data.json \
--collection=books

4.2.从HTTP POST上传的JSON文件

此外,如果我们将有一个REST参数来上传和导入JSON文件MultipartFile

@RestController
@RequestMapping("/import-json")
public class ImportJsonController {
@Autowired
private ImportJsonService service;
@PostMapping("/file/{collection}")
public String postJsonFile(@RequestPart("parts") MultipartFile jsonStringsFile, @PathVariable String collection) {
List<String> jsonLines = ImportUtils.lines(jsonStringsFile);
return service.importTo(collection, jsonLines);
}
}

现在可以像这样使用 POST 导入文件,“ /tmp/data.json”我们是其中现有的文件:

curl -X POST http://localhost:8082/import-json/file/books -F "[email protected]/tmp/books.json"

4.3.将JSON映射到特定的Java类型

我们一直只使用 JSON,没有任何类型,这是使用 MongoDB 的优势之一。现在我们要验证我们的输入。在这种情况下绑定,让我们通过对我们的服务进行以下更改来添加一个ObjectMapper

private <T> List<Document> generateMongoDocs(List<String> lines, Class<T> type) {
ObjectMapper mapper = new ObjectMapper();
List<Document> docs = new ArrayList<>();
for (String json : lines) {
if (type != null) {
mapper.readValue(json, type);
}
docs.add(Document.parse(json));
}
return docs;
}

这样,如果指定存储type,我们mapper将任意尝试将我们的 JSON 字符串解析为该类型。并且,使用默认配置,如果存在未知的参数,将出现异常参数。这是我们使用存储库的 bean 定义的:

@Document("books")
public class Book {
@Id
private String id;
private String name;
private String genre;
// getters and setters
}

现在,为了使用我们的文档生成器的改进版本,让我们也改变方法:

public String importTo(Class<?> type, List<String> jsonLines) {
List<Document> mongoDocs = generateMongoDocs(jsonLines, type);
String collection = type.getAnnotation(org.springframework.data.mongodb.core.mapping.Document.class)
.value();
int inserts = insertInto(collection, mongoDocs);
return inserts + "/" + jsonLines.size();
}

现在,我们不提交集合的名称,而是提交一个Class。我们假设它有我们在Book中使用的Document注释,因此它可以收集名称。必须,注释和Document具有相同名称的类,我们指定整个包。

5. 落幕

在本文中,我们将文件、资源或字符串划分为 JSON 输入,简单地将它们导入 MongoDB。我们在其中一个功能集中在一个服务类和实用程序类中,以便我们可以在任何地方重用它。我们的示例包括一个 CLI 和一个 REST 选项,以及如何使用它的示例命令。


标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *