補習系列(18)-springboot H2 迷你數據庫


關於 H2

H2 數據庫是一個純 Java 實現的開源的嵌入式數據庫,筆者第一次使用時還是在多年前的一個客戶端項目中。
當時就覺得這個數據庫很方便,如果你希望你的應用程序能"自帶數據庫,隨處運行”,那么H2是個不錯的選擇。

H2 的由來

H2 的前身是 HyperSQL(HSQL),后者也是一個類似的嵌入式數據庫,H2的作者 Thomas Mueller 一開始就是 HSQL的貢獻者。
到后來因為一些未知的原因分成了兩個項目分支,H2 大概就是第二代的意思..

有什么特性

  • 由於是Java寫的,自帶跨平台能力
  • 小,非常的小,完整的 Jar 包只有1-2M
  • 支持多種模式,包括內存形態、文件形態(持久化)

一般來說,使用H2 的場景大概會是:

  1. 計算資源受限,如嵌入式計算環境中,由於CPU、內存、Disk等限制,要求采用小巧的數據庫存儲方案;
  2. 項目預研,在項目立項之前可能無法立即采購昂貴的數據庫軟件,此時往往可以退而選擇臨時解決方案,利用JDBC協議的通用性在后期完成切換;
  3. 自動化測試,在自動化環境中可能需要大量模擬接口,包括數據存儲接口,此時內存數據庫是不二之選。

接下來,介紹兩種使用方式

一、H2 用作本地數據庫

1. 引入依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>${spring-boot.version}</version>
</dependency>

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
</dependency>

2. 配置文件

編輯 application.properties

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:h2:file:D:/temp/h2
spring.datasource.username=
spring.datasource.password=

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

其中 jdbc:h2:file:D:/temp/h2 將指示H2 啟用本地文件模式,數據庫文件將寫入 D:/temp/h2 這個目錄。

3. 樣例數據

LogRecord.java

@Entity
@Table(name="log_record")
    public class LogRecord {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO )
    private Long id;

    private String level;

    private String message;

    private Date createTime;

LogRepository.java

@Repository
public interface LogRecordRepository extends JpaRepository<LogRecord, Long> {
}

LogRecordInitializer.java

@Service
public class LogRecordInitializer {

    @Autowired
    private LogRecordRepository logRecordRepository;
    private static final Logger logger = LoggerFactory.getLogger(LogRecordInitializer.class);

    @PostConstruct
    void initData(){

        if(logRecordRepository.count() > 0){

            List<LogRecord> logRecords = logRecordRepository.findAll();

            logger.info("read records: {}", JsonUtil.toPrettyJson(logRecords));
            return;
        }
        for(int i=0; i<100; i++){

            LogRecord record = new LogRecord();
            record.setLevel("info");

            record.setMessage("Heartbeat message " + UUID.randomUUID().toString());
            record.setCreateTime(new Date());

            logRecordRepository.save(record);

            logger.info("save record - " + record.getMessage());
        }

    }
}

實現的邏輯大致是,第一次啟動時寫入100條數據,后面每次啟動將數據讀取出來並打印到日志。

執行SpringBoot 啟動程序,發現目錄中生成了h2.mv.db文件,說明寫入成功!

二、H2 用於單元測試

H2 數據庫的典型應用是 在Web項目中做單元測試。

一般,測試的流程為:

  1. 數據初始化
  2. 執行測試
  3. 銷毀數據

在真實的測試代碼開發中,有幾類問題會造成困擾:

  1. 數據庫環境的搭建比較費時費力;
  2. 數據庫的數據難以保持"干凈",一些垃圾數據容易影響測試的成功率

H2作為內存數據庫使用則能解決這些問題,本身作為內置數據庫並不需要額外的看護成本,
而且在程序退出時,所有數據都能保證完全清除。

1. 依賴包

<!-- springboot test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>${spring-boot.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
    <scope>test</scope>
</dependency>

2. 測試配置

編輯 src/test/resources/application.properties

# 數據源連接
spring.datasource.url=jdbc:h2:mem:test
# DDL腳本
spring.datasource.schema=classpath:script/test-schema.sql
# DML腳本
spring.datasource.data=classpath:script/test-data.sql

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto = update

3. 測試代碼

@RunWith(SpringRunner.class)
@SpringBootTest(classes = BootJpa.class)
public class CityViewRepositoryTest {

    @Autowired
    private CityViewRepository cityViewRepository;

    @Test
    public void testGetAll(){

        List<CityView> views = cityViewRepository.findAll();
        System.out.println(JsonUtil.toPrettyJson(views));
    }

}

碼雲同步代碼

小結

本篇介紹了 H2 數據庫常用的兩種使用場景。盡管此前也寫過關於H2 做單元測試的文章,
但除此之外,其作為嵌入式數據庫也是不錯的選擇,從行業趨勢來看,終端計算對於嵌入式DB的需求會越來越多,后面也是比較看好的。
與H2 類似的數據庫還有HSQL、Derby,有興趣的朋友可以研究對比下。

歡迎繼續關注"美碼師的補習系列-springboot篇" ,期待更多精彩內容-


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM