如何使用内存数据库让 H2 和 SpringBoot 协同工作?
How do I get H2 and SpringBoot to play nice together using the in memory database?
我正在学习关于使用 JUnit 和 Mockito 进行单元测试的教程视频,并且 运行 遇到了一些问题,其中有些东西播放不佳,我正在尝试找出问题所在。本教程使用 H2 创建内存数据库,这是我遇到问题的地方(数据库没有数据)。我创建了一个新项目,其唯一目的是创建相同的数据库,该数据库在一定程度上起作用,然后因没有数据而失败。经过几天的研究,我希望有人能看到我遗漏的一些明显的东西。我正在使用 IntelliJ Idea 21.1.2 作为我的 IDE、Linux Mint OS。 H2 对我来说是新的。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>TestH2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>TestH2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.url=jdbc:h2:mem:item;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1
spring.h2.console.enabled=true
schema.sql
DROP TABLE IF EXISTS ITEM;
CREATE TABLE ITEM (
id INT,
name VARCHAR(255),
price INT,
quantity INT
);
data.sql
INSERT INTO ITEM(id, name, price, quantity)
VALUES
(10001,'Item1',10,20),
(10002,'Item2',5,10),
(10003,'Item3',15,2);
有了上面的内容和我的应用程序文件,项目就构建好了,当我打开 h2-console 时,我得到了预期的结果。
不过。 . .
如果我尝试添加这样的 Item.java 文件(请注意,如果我注释掉 @Entity 行,它会如上所示工作)
package com.example.testh2.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
@Entity
public class Item {
@Id
private int id;
private String name;
private int price;
private int quantity;
@Transient
private int value;
public Item() {
}
public Item(int id, String name, int price, int quantity) {
this.id = id;
this.name = name;
this.price = price;
this.quantity = quantity;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getValue() { return value; }
public void setValue(int value) { this.value = value; }
public String toString() {
return String.format("Item[%d, %s, %d, %d]", id, name, price, quantity);
}
}
那就没有数据了
我猜我漏掉了一些简单的东西,我只是还没有 Google 找到正确的问题。我已经尝试了默认值以及当前的 datasource.url,我已经尝试使用一个文件嵌入 H2(我看到 items.mv.db 文件出现在它应该出现的位置但是控制台没有找到它也没有IntelliJ 数据库工具)。任何帮助将不胜感激。
在 application.properties
文件中,添加此行以关闭冲突的自动架构创建:
spring.jpa.hibernate.ddl-auto=none
您可以在此处阅读更多相关信息:
https://docs.spring.io/spring-boot/docs/1.1.0.M1/reference/html/howto-database-initialization.html
要记住的要点:
- H2 是一个内存数据库。也就是说,如果您重新启动应用程序,现有数据将会丢失。
- 您的依赖项中有 spring 开发工具,当您在应用程序中执行 change/add/modify class/anything 时,它会重新启动应用程序。
根据您的评论:-
However. . .
If I try to add an Item.java file like this (note if I comment out the
@Entity line it works as shown above)
看来您是先通过 H2 控制台添加数据,然后 adding/modifiying class ,
如果您 add/modify class 在插入数据后:spring 开发工具将重新启动您的应用程序并且您的 h2 数据将会丢失。
建议添加实体 class,然后将数据添加到 h2 数据库,并确保在添加数据后不要更改项目中的任何内容。
我正在学习关于使用 JUnit 和 Mockito 进行单元测试的教程视频,并且 运行 遇到了一些问题,其中有些东西播放不佳,我正在尝试找出问题所在。本教程使用 H2 创建内存数据库,这是我遇到问题的地方(数据库没有数据)。我创建了一个新项目,其唯一目的是创建相同的数据库,该数据库在一定程度上起作用,然后因没有数据而失败。经过几天的研究,我希望有人能看到我遗漏的一些明显的东西。我正在使用 IntelliJ Idea 21.1.2 作为我的 IDE、Linux Mint OS。 H2 对我来说是新的。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>TestH2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>TestH2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.url=jdbc:h2:mem:item;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1
spring.h2.console.enabled=true
schema.sql
DROP TABLE IF EXISTS ITEM;
CREATE TABLE ITEM (
id INT,
name VARCHAR(255),
price INT,
quantity INT
);
data.sql
INSERT INTO ITEM(id, name, price, quantity)
VALUES
(10001,'Item1',10,20),
(10002,'Item2',5,10),
(10003,'Item3',15,2);
有了上面的内容和我的应用程序文件,项目就构建好了,当我打开 h2-console 时,我得到了预期的结果。
不过。 . .
如果我尝试添加这样的 Item.java 文件(请注意,如果我注释掉 @Entity 行,它会如上所示工作)
package com.example.testh2.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
@Entity
public class Item {
@Id
private int id;
private String name;
private int price;
private int quantity;
@Transient
private int value;
public Item() {
}
public Item(int id, String name, int price, int quantity) {
this.id = id;
this.name = name;
this.price = price;
this.quantity = quantity;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getValue() { return value; }
public void setValue(int value) { this.value = value; }
public String toString() {
return String.format("Item[%d, %s, %d, %d]", id, name, price, quantity);
}
}
那就没有数据了
我猜我漏掉了一些简单的东西,我只是还没有 Google 找到正确的问题。我已经尝试了默认值以及当前的 datasource.url,我已经尝试使用一个文件嵌入 H2(我看到 items.mv.db 文件出现在它应该出现的位置但是控制台没有找到它也没有IntelliJ 数据库工具)。任何帮助将不胜感激。
在 application.properties
文件中,添加此行以关闭冲突的自动架构创建:
spring.jpa.hibernate.ddl-auto=none
您可以在此处阅读更多相关信息: https://docs.spring.io/spring-boot/docs/1.1.0.M1/reference/html/howto-database-initialization.html
要记住的要点:
- H2 是一个内存数据库。也就是说,如果您重新启动应用程序,现有数据将会丢失。
- 您的依赖项中有 spring 开发工具,当您在应用程序中执行 change/add/modify class/anything 时,它会重新启动应用程序。
根据您的评论:-
However. . .
If I try to add an Item.java file like this (note if I comment out the @Entity line it works as shown above)
看来您是先通过 H2 控制台添加数据,然后 adding/modifiying class , 如果您 add/modify class 在插入数据后:spring 开发工具将重新启动您的应用程序并且您的 h2 数据将会丢失。
建议添加实体 class,然后将数据添加到 h2 数据库,并确保在添加数据后不要更改项目中的任何内容。