H2 数据库是一个纯 Java 实现的开源的嵌入式数据库,笔者第一次使用时还是在多年前的一个客户端项目中。 当时就觉得这个数据库很方便,如果你希望你的应用程序能"自带数据库,随处运行”,那么H2是个不错的选择。
H2 的由来
H2 的前身是 HyperSQL(HSQL),后者也是一个类似的嵌入式数据库,H2的作者 Thomas Mueller 一开始就是 HSQL的贡献者。 到后来因为一些未知的原因分成了两个项目分支,H2 大概就是第二代的意思..
有什么特性
一般来说,使用H2 的场景大概会是:
接下来,介绍两种使用方式
<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>
编辑 application.properties:
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)spring.datasource.url=jdbc:h2:file:D:/temp/h2spring.datasource.username=spring.datasource.password=
# The SQL dialect makes Hibernate generate better SQL for the chosen databasespring.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 这个目录。
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
@Repositorypublic interface LogRecordRepository extends JpaRepository<LogRecord, Long> {}
LogRecordInitializer.java
@Servicepublic 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 数据库的典型应用是 在Web项目中做单元测试。
一般,测试的流程为:
在真实的测试代码开发中,有几类问题会造成困扰:
H2作为内存数据库使用则能解决这些问题,本身作为内置数据库并不需要额外的看护成本, 而且在程序退出时,所有数据都能保证完全清除。
<!-- 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>
编辑 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.H2Dialectspring.jpa.hibernate.ddl-auto = update
@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篇" ,期待更多精彩内容^-^