Spring 开机无法自动创建数据库(with Jdbc + Mysql)
Spring Boot can't automatically create database (with Jdbc + Mysql)
我试图创建并自动初始化一个名为“spring”的 MySQL 数据库来存储用户和权限,因此我创建了文件 schema.sql 和 data.sql在“资源”文件夹中(参见下面的脚本)。当我 运行 程序时,它抛出一个异常,声明“数据源”bean 无法实例化,因为找不到我试图创建的“spring”数据库!!
PS:当我切换到内存数据库H2时,程序运行良好,
但是当我切换到 MySQL 时,问题如上所述失败。
在我看来,spring boot 试图在为 MySQL.[=17 的情况执行数据库的 SQL 脚本之前创建“dataSource”bean =]
谁能给我解释一下到底发生了什么?
这是涉及数据源 bean 的程序:
package com.javamaster.springsecurityjdbc.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import javax.sql.DataSource;
@Configuration
public class SecurityConfig {
@Bean
public UserDetailsService userDetailsService(DataSource dataSource){
return new JdbcUserDetailsManager(dataSource);
}
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
}
schema.sql
create database spring;
CREATE TABLE IF NOT EXISTS `spring`.`users` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`enabled` INT NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS `spring`.`authorities` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`authority` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
data.sql
INSERT IGNORE INTO `spring`.`authorities` VALUES (NULL, 'tom', 'write');
INSERT IGNORE INTO `spring`.`users` VALUES (NULL, 'tom', '123456', '1');
和application.properties
spring.datasource.url=jdbc:mysql://localhost/spring?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.initialization-mode=always
您最有可能得到:
Failed to obtain JDBC Connection; nested exception is java.sql.SQLSyntaxErrorException: Unknown database 'spring'
或
Failed to execute SQL script statement #1 of URL: create database spring; nested exception is java.sql.SQLException: Can't create database 'spring'; database exists
您需要在脚本之外手动创建数据库:
schema.sql
-- create database spring; <-- remove this line
CREATE TABLE IF NOT EXISTS `spring`.`users` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`enabled` INT NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS `spring`.`authorities` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`authority` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
根据上述例外情况,在第一种情况下,Spring 尝试在 运行 在其上安装任何脚本之前连接到数据库,因此无法找到它并失败。在第二种情况下,它能够连接,但数据库已经创建,因此脚本失败。
我在本地测试了这些并且能够成功 运行 应用程序,一旦删除 create database
部分。两个表均已正确创建和填充。
我试图创建并自动初始化一个名为“spring”的 MySQL 数据库来存储用户和权限,因此我创建了文件 schema.sql 和 data.sql在“资源”文件夹中(参见下面的脚本)。当我 运行 程序时,它抛出一个异常,声明“数据源”bean 无法实例化,因为找不到我试图创建的“spring”数据库!!
PS:当我切换到内存数据库H2时,程序运行良好, 但是当我切换到 MySQL 时,问题如上所述失败。
在我看来,spring boot 试图在为 MySQL.[=17 的情况执行数据库的 SQL 脚本之前创建“dataSource”bean =]
谁能给我解释一下到底发生了什么?
这是涉及数据源 bean 的程序:
package com.javamaster.springsecurityjdbc.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import javax.sql.DataSource;
@Configuration
public class SecurityConfig {
@Bean
public UserDetailsService userDetailsService(DataSource dataSource){
return new JdbcUserDetailsManager(dataSource);
}
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
}
schema.sql
create database spring;
CREATE TABLE IF NOT EXISTS `spring`.`users` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`enabled` INT NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS `spring`.`authorities` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`authority` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
data.sql
INSERT IGNORE INTO `spring`.`authorities` VALUES (NULL, 'tom', 'write');
INSERT IGNORE INTO `spring`.`users` VALUES (NULL, 'tom', '123456', '1');
和application.properties
spring.datasource.url=jdbc:mysql://localhost/spring?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.initialization-mode=always
您最有可能得到:
Failed to obtain JDBC Connection; nested exception is java.sql.SQLSyntaxErrorException: Unknown database 'spring'
或
Failed to execute SQL script statement #1 of URL: create database spring; nested exception is java.sql.SQLException: Can't create database 'spring'; database exists
您需要在脚本之外手动创建数据库:
schema.sql
-- create database spring; <-- remove this line
CREATE TABLE IF NOT EXISTS `spring`.`users` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`enabled` INT NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE IF NOT EXISTS `spring`.`authorities` (
`id` INT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`authority` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`));
根据上述例外情况,在第一种情况下,Spring 尝试在 运行 在其上安装任何脚本之前连接到数据库,因此无法找到它并失败。在第二种情况下,它能够连接,但数据库已经创建,因此脚本失败。
我在本地测试了这些并且能够成功 运行 应用程序,一旦删除 create database
部分。两个表均已正确创建和填充。