国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring Boot實現第一次啟動時自動初始化數據庫

這篇具有很好參考價值的文章主要介紹了Spring Boot實現第一次啟動時自動初始化數據庫。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Spring Boot實現第一次啟動時自動初始化數據庫

在現在的后端開發(fā)中,只要是運用聯(lián)系型數據庫,信任SSM架構(Spring Boot + MyBatis)已經成為首選。 不過在咱們第一次運轉或許布置項目的時分,一般要先手動銜接數據庫,履行一個SQL文件以創(chuàng)立數據庫以及數據庫表格完結數據庫的初始化作業(yè),這樣咱們的SSM應用程序才能夠正常作業(yè)。 這樣也對實際布置或許是容器化造成了一些麻煩,必須先手動初始化數據庫再發(fā)動應用程序。 那能不能讓咱們的SSM應用程序第一次發(fā)動時,主動地幫咱們履行SQL文件以完結數據庫初始化作業(yè)呢? 這樣事實上是沒問題的,今日就以Spring Boot + MyBatis為例,運用MySQL作為數據庫,完結上述的數據庫初始化功用。

1,全體思路

咱們能夠編寫一個裝備類,在一個標示了@PostConstruct注解的辦法中編寫初始化數據庫的邏輯,這樣應用程序發(fā)動時,就會履行該辦法協(xié)助咱們完結數據庫的初始化作業(yè)。 那么這個初始化數據庫的邏輯大概是什么呢?能夠總結為如下過程:

  1. 首要測驗銜接用戶裝備的地址,若銜接拋出反常闡明地址中指定的數據庫不存在,需求創(chuàng)立數據庫并初始化數據,不然就不需求初始化,直接退出初始化邏輯
  2. 若要履行初始化,首要從頭拼裝用戶裝備的銜接地址,使得本次銜接不再是銜接至詳細的數據庫,并履行create database句子完結數據庫創(chuàng)立
  3. 創(chuàng)立完結數據庫后,再次運用用戶裝備的銜接地址,這時數據庫創(chuàng)立完結就能夠成功銜接上了!這時再履行SQL文件初始化表格即可

上述邏輯中咱們能夠會有下列的疑問:

  • 第一步中,為什么銜接拋出反常闡明地址中指定的數據庫不存在?
  • 第二步中,什么是 “使得本次銜接不再是銜接至詳細的數據庫”

假定用戶裝備的銜接地址是jdbc:mysql://127.0.0.1:3306/init_demo,信任這個咱們十分熟悉了,它表明:銜接的MySQL地址是127.0.0.1,端口是3306,并且銜接到該MySQL中名為init_demo的數據庫中。 那么假如MySQL中init_demo的庫并不存在,Spring Boot還測驗銜接上述地址的話,就會拋出SQLException反常:

Spring Boot實現第一次啟動時自動初始化數據庫,spring boot,數據庫,后端

所以在這兒能夠將是否拋出SQLException反常作為判別應用程序是否是第一次布置發(fā)動的條件。 好的,已然數據庫不存在,咱們就要創(chuàng)立數據庫,但是上述地址銜接不上啊!怎樣創(chuàng)立呢? 正是由于上述地址中指定了要銜接的詳細數據庫,而數據庫又不存在,才會銜接失利,那能不能銜接時不指定數據庫,僅僅是銜接到MySQL上就行呢?當然能夠,咱們將上述的銜接地址改成:jdbc:mysql://127.0.0.1:3306/,就能夠銜接成功了! 不過一般SSM應用程序中,裝備數據庫地址都是要指定庫名的,因而咱們待會在裝備類編寫初始化數據庫邏輯時,從頭拼裝一下用戶給的裝備銜接地址即可,即把jdbc:mysql://127.0.0.1:3306/init_demo經過代碼處理成jdbc:mysql://127.0.0.1:3306/并主張銜接即可,這便是上述說的第二步。 第二步完結了數據庫的創(chuàng)立,第三步便是完結表格創(chuàng)立了!表格創(chuàng)立就寫在SQL文件里即可,由于數據庫創(chuàng)立好了,咱們在第三步中又能夠從頭運用用戶給的裝備地址jdbc:mysql://127.0.0.1:3306/init_demo再次銜接并履行SQL文件完結初始化了! 上述過程中,咱們將運用JDBC自帶的接口完結數據庫銜接等等,而不是運用MyBatis的SqlSessionFactory,由于咱們第二步需求改動銜接地址。 下面,咱們就來完結一下。

2,詳細完結

首要是在本地或許其它地方樹立好MySQL服務器,這兒就不再贅述怎樣去樹立MySQL了。 我這兒在本地樹立了MySQL服務器,下面經過Spring Boot進行銜接。

(1) 創(chuàng)立應用程序并裝備

首要創(chuàng)立一個Spring Boot應用程序,并集成好MySQL驅動和MyBatis支持,我這兒的依靠如下:

<!-- Spring Web -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>3.0.2</version>
</dependency>
<!-- MySQL銜接支持 -->
<dependency>
	<groupId>com.mysql</groupId>
	<artifactId>mysql-connector-j</artifactId>
	<scope>runtime</scope>
</dependency>
<!-- Hutool有用工具 -->
<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>5.8.16</version>
</dependency>
<!-- Lombok注解 -->
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<scope>provided</scope>
</dependency>
<!-- Spring Boot測試 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>

然后在裝備文件application.yml中加入下列裝備:

# 數據庫裝備
spring:
  datasource:
    url: "jdbc:mysql://127.0.0.1:3306/init_demo?serverTimezone=GMT%2B8"
    username: "swsk33"
    password: "dev-2333"

這便是正常的數據庫銜接裝備,不再過多講述。我這兒運用yaml格局裝備文件,咱們也能夠運用properties格局的裝備文件。

(2) 編寫裝備類完結數據庫的檢測和初始化邏輯

這兒先給出這個裝備類的代碼:

package com.gitee.swsk33.sqlinitdemo.config;
import cn.hutool.core.io.resource.ClassPathResource;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
 * 用于第一次發(fā)動時,初始化數據庫的裝備類
 */
@Slf4j
@Configuration
public class DatabaseInitialize {
	/**
	 * 讀取銜接地址
	 */
	@Value("${spring.datasource.url}")
	private String url;
	/**
	 * 讀取用戶名
	 */
	@Value("${spring.datasource.username}")
	private String username;
	/**
	 * 讀取暗碼
	 */
	@Value("${spring.datasource.password}")
	private String password;
	/**
	 * 檢測當前銜接的庫是否存在(銜接URL中的數據庫)
	 *
	 * @return 當前銜接的庫是否存在
	 */
	private boolean currentDatabaseExists() {
		// 測驗以裝備文件中的URL樹立銜接
		try {
			Connection connection = DriverManager.getConnection(url, username, password);
			connection.close();
		} catch (SQLException e) {
			// 若銜接拋出反常則闡明銜接URL中指定數據庫不存在
			return false;
		}
		// 正常情況下闡明銜接URL中數據庫存在
		return true;
	}
	/**
	 * 履行SQL腳本
	 *
	 * @param path        SQL腳本文件的路徑
	 * @param isClasspath SQL腳本路徑是否是classpath路徑
	 * @param connection  數據庫銜接目標,經過這個銜接履行腳本
	 */
	private void runSQLScript(String path, boolean isClasspath, Connection connection) {
		try (InputStream sqlFileStream = isClasspath ? new ClassPathResource(path).getStream() : new FileInputStream(path)) {
			BufferedReader sqlFileStreamReader = new BufferedReader(new InputStreamReader(sqlFileStream, StandardCharsets.UTF_8));
			// 創(chuàng)立SQL腳本履行器目標
			ScriptRunner scriptRunner = new ScriptRunner(connection);
			// 運用SQL腳本履行器目標履行腳本
			scriptRunner.runScript(sqlFileStreamReader);
			// 最后關閉文件讀取器
			sqlFileStreamReader.close();
		} catch (Exception e) {
			log.error("讀取文件或許履行腳本失利!");
			e.printStackTrace();
		}
	}
	/**
	 * 履行SQL腳本以創(chuàng)立數據庫
	 */
	private void createDatabase() {
		try {
			// 修正銜接句子,從頭樹立銜接
			// 從頭樹立的銜接不再銜接到指定庫,而是直接銜接到整個MySQL
			// 運用URI類解析并拆解銜接地址,從頭拼裝
			URI databaseURI = new URI(url.replace("jdbc:", ""));
			// 得到銜接地址中的數據庫平臺名(例如mysql)
			String databasePlatform = databaseURI.getScheme();
			// 得到銜接地址和端口
			String hostAndPort = databaseURI.getAuthority();
			// 得到銜接地址中的庫名
			String databaseName = databaseURI.getPath().substring(1);
			// 拼裝新的銜接URL,不銜接至指定庫
			String newURL = "jdbc:" + databasePlatform + "://" + hostAndPort + "/";
			// 從頭樹立銜接
			Connection connection = DriverManager.getConnection(newURL, username, password);
			Statement statement = connection.createStatement();
			// 履行SQL句子創(chuàng)立數據庫
			statement.execute("create database if not exists `" + databaseName + "`");
			// 關閉會話和銜接
			statement.close();
			connection.close();
			log.info("創(chuàng)立數據庫完結!");
		} catch (URISyntaxException e) {
			log.error("數據庫銜接URL格局過錯!");
			throw new RuntimeException(e);
		} catch (SQLException e) {
			log.error("銜接失利!");
			throw new RuntimeException(e);
		}
	}
	/**
	 * 該辦法用于檢測數據庫是否需求初始化,假如是則履行SQL腳本進行初始化操作
	 */
	@PostConstruct
	private void initDatabase() {
		log.info("開端查看數據庫是否需求初始化...");
		// 檢測當前銜接數據庫是否存在
		if (currentDatabaseExists()) {
			log.info("數據庫存在,不需求初始化!");
			return;
		}
		log.warn("數據庫不存在!預備履行初始化過程...");
		// 先創(chuàng)立數據庫
		createDatabase();
		// 然后再次銜接,履行腳本初始化庫中的表格
		try (Connection connection = DriverManager.getConnection(url, username, password)) {
			runSQLScript("/create-table.sql", true, connection);
			log.info("初始化表格完結!");
		} catch (Exception e) {
			log.error("初始化表格時,銜接數據庫失利!");
			e.printStackTrace();
		}
	}
}

上述代碼中,有下列要點:

  • 咱們運用@Value注解讀取了裝備文件中數據庫的銜接信息,包括銜接地址、用戶名和暗碼
  • 上述currentDatabaseExists辦法用于測驗運用裝備的地址進行銜接,假如拋出SQLException反常則判別裝備的地址中,指定的數據庫是不存在的,這兒的代碼主要是完結了上述初始化邏輯中的第一步
  • 上述createDatabase辦法用于從頭拼裝用戶的銜接地址,使其不再是銜接到指定數據庫,然后履行SQL句子完結數據庫的創(chuàng)立,咱們運用Java的URI類解析用戶裝備的銜接地址,便于咱們拆分然后拼裝銜接地址,并獲取用戶要運用的數據庫名,對其進行創(chuàng)立,這兒的代碼完結了上述初始化邏輯中的第二步
  • 上述initDatabase辦法是會被主動履行的,它調用了currentDatabaseExistscreateDatabase辦法,組合起來一切的過程,在其間完結了第一步和第二步后,從頭運用用戶裝備的地址主張銜接并履行SQL腳本以初始化表,這個辦法包括了上述初始化邏輯中的第三步
  • 上述runSQLScript辦法用于銜接數據庫后履行SQL腳本,其間ScriptRunner類是由MyBatis供給的運轉SQL腳本的有用類,其結構函數需求傳入JDBC的數據庫銜接目標Connection目標,然后上述我還設定了形參isClasspath,能夠讓用戶自定義是讀取文件體系中的SQL腳本還是classpath中的SQL腳本

上述的初始化表格腳本坐落工程目錄的src/main/resources/create-table.sql,即classpath中,內容如下:

-- 初始化表格前先刪去
drop table if exists `user`;
-- 創(chuàng)立表格
create table `user`
(
	`id`       int unsigned auto_increment,
	`username` varchar(16) not null,
	`password` varchar(32) not null,
	primary key (`id`)
) engine = InnoDB
  default charset = utf8mb4;

好的,現在先保證MySQL數據庫中不存在init_demo的庫,發(fā)動程序試試:

Spring Boot實現第一次啟動時自動初始化數據庫,spring boot,數據庫,后端

可見成功地完結了數據庫的檢測、初始化作業(yè),也可見ScriptRunner在履行SQL的時分會在操控臺輸出履行的句子。 現在再從頭發(fā)動一下程序試試:

Spring Boot實現第一次啟動時自動初始化數據庫,spring boot,數據庫,后端

可見第2次發(fā)動時,名為init_demo的數據庫已經存在了,這時就不需求履行初始化邏輯了!

(3) 假如有的Bean初始化時需求拜訪數據庫

假定現在有一個類,在初始化為Bean的時分需求拜訪數據庫,例如:

// 省略package和import
/**
 * 發(fā)動時需求查詢數據庫的Beans
 */
@Slf4j
@Component
public class UserServiceDemo {
	@Autowired
	private UserDAO userDAO;
	@PostConstruct
	private void init() {
		log.info("履行數據庫測試拜訪...");
		userDAO.add(new User(0, "用戶名", "暗碼"));
		List<User> users = userDAO.getAll();
		for (User user : users) {
			System.out.println(user);
		}
	}
}

這個類在被初始化為Bean的時分,就需求拜訪數據庫進行讀寫操作,那問題來了,假如這個類UserServiceDemo在上述數據庫初始化類DatabaseInitialize之前被初始化了怎樣辦呢?這會導致數據庫還沒有被初始化時,UserServiceDemo就去拜訪數據庫,導致初始化失利。 這時,咱們能夠運用@DependsOn注解,這個注解能夠操控UserServiceDemoDatabaseInitialize初始化之后再進行初始化:

@Slf4j
@Component
// 運用@DependsOn注解表明當前類依靠于名為databaseInitialize的Bean
// 這樣能夠使得databaseInitialize這個Bean(咱們的數據庫查看類)先被初始化,并履行完結數據庫初始化后再初始化本類,以順利拜訪數據庫
@DependsOn("databaseInitialize")
public class UserServiceDemo {
	// 省略這個類的內容
}

在這兒咱們在UserServiceDemo上標示了注解@DependsOn,并傳入databaseInitialize作為參數,表明UserServiceDemo這個類是依靠于名(id)為databaseInitialize的Bean的,這樣Spring Boot就會在DatabaseInitialize初始化之后再初始化UserServiceDemo。

標示了@Component等等的類,默認情況下被初始化為Bean的時分,其名稱是其類名的小駝峰方式,例如上述的DatabaseInitialize類,初始化為Bean時姓名默認為databaseInitialize,因而上述@DependsOn注解就傳入databaseInitialize。

現在刪去init_demo庫,再次發(fā)動應用程序:
Spring Boot實現第一次啟動時自動初始化數據庫,spring boot,數據庫,后端

可見在初始化數據庫后,又成功地在發(fā)動時拜訪了數據庫。

3,總結

本文以Spring Boot + Mybatis為例,運用MySQL數據庫,完結了SSM應用程序第一次發(fā)動時主動檢測并完結數據庫初始化的功用,理論上上述方式適用于一切的聯(lián)系型數據庫,咱們稍作修正即可。文章來源地址http://www.zghlxwxcb.cn/news/detail-772820.html

到了這里,關于Spring Boot實現第一次啟動時自動初始化數據庫的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【2023新教程】樹莓派4B開機啟動-樹莓派第一次啟動-樹莓派不使用顯示器啟動-樹莓派從購買到啟動一步一步完全版!

    【2023新教程】樹莓派4B開機啟動-樹莓派第一次啟動-樹莓派不使用顯示器啟動-樹莓派從購買到啟動一步一步完全版!

    閑來無事,在咸魚上買了一個樹莓派4B。買來配件都十分齊全,于是就想著啟動來測試一下。下面是樹莓派無顯示器第一次啟動的全過程,包含安裝系統(tǒng)。 網上的教程大多需要額外使用顯示器、鼠標、鍵盤之類的外設。然而,樹莓派本身就是便捷靈活開發(fā)的代表,在真實開發(fā)

    2024年02月13日
    瀏覽(65)
  • Spring Boot實現在啟動時執(zhí)行一次的功能

    此方法可能是最常用的 可以使用Spring Boot的@PostConstruct注解來實現在啟動時執(zhí)行一次的功能。@PostConstruct注解標記的方法會在Bean初始化完成后自動調用,可以在該方法中執(zhí)行只需要在啟動時執(zhí)行一次的操作。 如果想在生成對象時完成某些初始化操作,而偏偏這些初始化操作又

    2024年02月06日
    瀏覽(21)
  • 第一次使用ThreadPoolTaskExecutor實現線程池的經歷,反復修改了多次代碼才正常使用

    1、前言 ??在一個向第三方平臺推送消息的場景中,為了提高程序的執(zhí)行效率,每次發(fā)送消息,都創(chuàng)建一個新的線程來完成發(fā)送消息的任務,為了提供線程的使用性能,我選擇了ThreadPoolTaskExecutor線程池,結果在使用的過程中,出現了較多的問題,這里記錄一下避免以后再出

    2024年02月08日
    瀏覽(25)
  • 當我第一次通過Kotlin和Compose來實現一個Canvas時, 我收獲了什么?

    自從2019年Google推薦Kotlin為Android開發(fā)的首選語言以來已經經歷了將近四年的時間, Compose的1.0版本也發(fā)布了將近2年的時間, Kotlin+Compose在現階段的Android開發(fā)過程中還遠遠達不到主流的程度. 我們是否應該開始嘗試這個組合? 這個組合有會給我們帶來什么? 對于我來說, 我是個守舊又

    2023年04月27日
    瀏覽(24)
  • docker第一次作業(yè)

    docker第一次作業(yè) 1.安裝docker服務,配置鏡像加速器 ?yum install -y yum-utils device-mapper-persistent-data lvm2 y um-config-manager --add-repo https: //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i \\\'s+download.docker.com+mirrors.aliyun.com/docker-ce+\\\' ?/etc/yum.repos.d/docker-ce.repo yum makecache fast yum -y install docke

    2024年02月12日
    瀏覽(26)
  • 樹莓派第一次開機

    樹莓派第一次開機

    樹莓派由英國的樹莓派基金會發(fā)行,旨在通過發(fā)行這個廉價開源的可隨意破解的微型計算機,推動中小學編程教育,發(fā)行之后很快在全世界的開源創(chuàng)客圈中流行。截止到2018年10月,最新版本的樹莓派主板是3B+,國內某寶上賣230元左右,還有更微型的樹莓派主板Zero,國內某寶賣

    2024年02月13日
    瀏覽(19)
  • 新學期第一次課

    新學期第一次課

    在信息化飛速發(fā)展的今天,大數據技術的應用日益廣泛,其重要性也日益凸顯。對于大數據學院的同學來說,掌握行業(yè)前沿技術是至關重要的。本篇文章將詳細指導同學們如何加入QQ群、云班課,并學會使用思維導圖和CSDN博客。 我們有兩個QQ群,分別是2021計應1班行業(yè)前沿技

    2024年02月10日
    瀏覽(27)
  • 第一次PR經歷

    第一次PR經歷

    ? ? ?

    2024年02月13日
    瀏覽(25)
  • 第一次面試復盤

    這個秋招到目前為止第一次拿到了面試機會,雖然是小公司,但是人家是有官網的!??!很愛!先趕緊復盤一下,因為還有很多筆試沒有復盤。 你們的數學建模解決了什么問題?你覺得你們?yōu)槭裁茨苣玫竭@個成績 說下對java這門語言的了解 它是一種面向對象的編程語言,所以

    2024年01月22日
    瀏覽(27)
  • python 第一次作業(yè)

    python 第一次作業(yè)

    因為筆者有一些 c/c++ 語言的基礎,所以應該學 python 會稍微簡單一些 輸入的時候所有的輸入都是字符串類型,我們需要進行類型轉換 參見資源里面的第三題和第四題,為了方便起見,直接把代碼貼在下面

    2024年03月25日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包