H2数据库表未找到错误(Spring Boot)
环境
MacOS Big Sur 11.1
STS 4-4.9.0
Spring Boot 2.4.2
Java 11
H2数据库 1.4.200
Maven 4.0.0
当前的情况
H2Database是一种在JVM环境下运行的数据库。
它非常轻量,在Java测试开发中非常方便。
它有两种类型,一种是内嵌类型,在JVM内部设置数据库,另一种是本地类型,将数据库文件存放在指定路径并进行保存。
这次为了将数据持久化,进行了本地型H2的设置。
文件
入口点
package com.example.h2test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import com.example.h2test.domain.Customer;
@SpringBootApplication
public class H2testApplication implements CommandLineRunner {
@Autowired
NamedParameterJdbcTemplate jdbcTemplate;
@Override
public void run(String...strings) throws Exception {
String sql = "SELECT id, firstName, lastName from customers where id = :id";
SqlParameterSource param = new MapSqlParameterSource().addValue("id", 1);
Customer result = jdbcTemplate.queryForObject(sql, param, (rs, rowNum)
-> new Customer(rs.getInt("id"), rs.getString("firstName"), rs.getString("lastName")
));
System.out.println("result: " + result);
}
public static void main(String[] args) {
SpringApplication.run(H2testApplication.class, args);
}
}
在类路径下,有一个名为schema.sql的文件。
CREATE table IF NOT EXISTS customers (
id int primary key auto_increment,
firstName varchar(30),
lastName varchar(30)
);
在application.properties文件中描述用于将H2数据库持久化的配置。
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:file:./target/db/testdb
spring.datasource.username=sa
spring.datasource.password=
然而,在执行之后
java.lang.IllegalStateException: Failed to execute CommandLineRunner
Caused by: org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT id, firstName, lastName from customers where id = ?]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: テーブル "CUSTOMERS" が見つかりません
Table "CUSTOMERS" not found;
发生了上述错误。
这是用来引用datasource.url路径中所写的数据库文件的配置。
如果不存在,那么会在那里创建一个数据库文件。
错误的原因和解决方案
造成無法找到表的原因是因為根本就沒有創建表。
如果Spring boot的類路徑下有一個名為schema.sql的文件,它會自動讀取並創建表,但目前看來似乎沒有被讀取。
原因是因为SQL文件的初始化设置没有进行。
将以下代码追加到application.properties文件中。
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:schema.sql
初始化模式
指定如何初始化H2读取的schema.sql文件。可以选择值为「always」、「embedded」或「never」。初始值为embedded,这表示仅在嵌入式数据库(H2数据库)上运行时执行。由于本次是本地数据库而不是嵌入式数据库,如果初始设置不为「always」,则schema.sql将不会被执行。
模式
指定要读取哪个schema文件。
如果未设置,将读取类路径下的schema.sql文件。
(本次可以省略)
最后的application.properties文件的内容将变成这样。
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:file:./target/db/testdb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:schema.sql
整理
我在参考《はじめてのSpring Boot》的同时处理了h2数据库。
因为在指定文件时没有描述初始化操作,所以让我想是否h2在数年前读取时不需要进行初始化设置呢?
如果有任何错误或建议,请不吝赐教。谢谢。
文献参考
首次使用Spring Boot
Spring Boot的数据库初始化方法
Spring Boot 2.0按类别列出的重要属性列表