开发者社区> 美码师> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

补习系列(18)-springboot H2 迷你数据库

简介: 关于 H2 H2 数据库是一个纯 Java 实现的开源的嵌入式数据库,笔者第一次使用时还是在多年前的一个客户端项目中。当时就觉得这个数据库很方便,如果你希望你的应用程序能"自带数据库,随处运行”,那么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篇" ,期待更多精彩内容^-^

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
SpringBoot2.x入门:使用MyBatis
这篇文章是《SpringBoot2.x入门》专辑的「第8篇」文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8。
27 0
补习系列(15)-springboot 分布式会话原理
[TOC] 一、背景 在 补习系列(3)-springboot 几种scope 一文中,笔者介绍过 Session的部分,如下: 对于服务器而言,Session 通常是存储在本地的,比如Tomcat 默认将Session 存储在内存(ConcurrentHashMap)中。
2364 0
补习系列(6)-SpringBoot 整合Shiro 一指禅
SpringBoot 整合Shiro,基于starter自动装配,老司机提供的最完整实例
4847 0
补习系列(7)-SpringBoot 实现拦截的五种姿势
简介 AOP(面向切面编程)常用于解决系统中的一些耦合问题,是一种编程的模式通过将一些通用逻辑抽取为公共模块,由容器来进行调用,以达到模块间隔离的效果。其还有一个别名,叫面向关注点编程,把系统中的核心业务逻辑称为核心关注点,而一些通用的非核心逻辑划分为横切关注点 AOP常用于... 日志记录你需要为你的Web应用程序实现访问日志记录,却又不想在所有接口中一个个进行打点。
17212 0
补习系列(3)-springboot 中的几种scope
目标 了解HTTP 请求/响应头及常见的属性; 了解如何使用SpringBoot处理头信息 ; 了解如何使用SpringBoot处理Cookie ; 学会如何对 Session 进行读写; 了解如何在不同请求间传递 flash参数 一、Http 头信息 HTTP 头(Header)是一种附加内容,独立于请求内容和响应内容。
5051 0
SpringBoot-07-之数据库JPA(CRUD)
现在来介绍SpringBoot基于jpa对MySQL进行操作。 既然是数据库操作总有点目标和资源吧, 现在来做一个:《万界神兵录》收集一下天下神兵,从剑开始 一.
992 0
SpringBoot-06-之拿到你的图片!
笔者知道这招非常高兴,SpringBoot本身集成TomCat等web服务器, Tomcat用的比较熟,但怎么访问上传进来的文件呢?Root文件夹都没有。
1280 0
SpringBoot-10-之初阶整合篇(下)
先看效果:本小例=SpringBoot+MySql+JAP+JQuery+Vue+animate.css+一个我 结果展示.gif 一、自定义的css样式:static/css/my.
841 0
补习系列(1)-springboot项目基础搭建课
目录 前言 一、基础结构 二、添加代码 三、应用配置 四、日志配置 五、打包部署 小结 前言 springboot 最近火的不行,目前几乎已经是 spring 家族最耀眼的项目了。抛开微服务、技术社区这些推广因素不说,框架本身的确有非常多的优点。
2435 0
+关注
美码师
美码师,老码农一枚,唯美食与技术不能辜负,欢迎交流及打扰!
73
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载