H2
在开始之前, 先简单介绍一下 H2 是一个轻量型的资料库, 预设是採用记忆体的方式做资料储存, 速度非常快, 整体的 jar 档大约 2.5MB 左右。支援标準的 SQL 语法规範, 与 JDBC API 接口。在 Spring boot (2.7.4) 的官方文档 中也有一些简单的描述与介绍。
Why H2
整体来说, 轻量快速反应, 满符合敏捷精神的, 大团队或小团队都有适合他使用的情境.
在专案草创阶段, 常常会修改 DB Scheam, 三不五时就要alter column
或是 drop column
, 若公司组织规模稍大, 还需要提交给 DBA 去执行这些指令, 有较多的沟通成本。H2 可以在本地快速启动, 可以透过 spring.jpa.hibernate.ddl-auto: update
的特性, 自动更新 schema。若团队採用共用开发资料库, 在一些测试案例或操作的时候, 资料可能会互相污染, 虽然 docker 可以在本地快速建构资料库, 但就需要再额外安装 docker。支援浏览器的 Console 介面, 基本上也不需要特别安装 Database GUI 透过 spring.h2.console.eanbled: true
就能在浏览器做一些 table 的查询。
Spring boot
这边推荐使用 Spring boot initializr 来初始化专案。
专案的 pom.xml
里面的套件依赖描述大概会长这样子。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope></dependency>
专案的 application.properies
我通常习惯改为 application.yml
比较符合我的阅读习惯, 细部说明就写在注解里面了。
spring: # spring datasource configuration 的配置 datasource: driver-class-name: org.h2.Driver username: 'sa' password: url: 'jdbc:h2:mem:my_app' # H2 的 JDBC URL, mem 表示使用记忆体, my_app 是资料库的名称 h2: console: enabled: true # 设定要启用 H2 的 console 可以在浏览器上面查询 table path: '/h2' # 浏览器 console 的 URL 路径 jpa: generate-ddl: false open-in-view: false hibernate: ddl-auto: update # 当 spring boot entity 有修改时, 会自动修改 DB scheam
JPA Entity Sample
来建立一个简单的 JPA Entity 吧
/** * 这边的 @Getter 与 @Setter 是 lombok 的功能, 不採用 @Data 在底下说明 */@Getter@Setter@Entitypublic class ProductEntity implements Serializable { @Id @GeneratedValue private Long id; @Column(nullable = false) private String name; @Column(nullable = false) private BigDecimal price;}
JPA Entity 不应该用 lobmok 的 @Data
主要是 @Data
包含了 @EqualsAndHashCode
与 @ToString
这个功能, 分别会去实作 Java Class 的 equals
, hashCode
, toString
方法。
@Override public boolean equals(Object o) {...}@Override public int hashCode() {...}@Override public String toString() {...}
这会有什么影响呢? 可以思考一下, JPA 的 Entity 本身就有 @Id
field 可以做 equals 的比较了, 真的还需要去覆写 equals(Object o)
这个方法吗?
其二, 当资料库有关联时, 比如说 @OneToMany
时, lombok 因为会自动扫描所有 fields 去产生 hashCode()
与 toString()
而破坏了 lazy loadding 机制, 这不就失去 lazy loadding 的用意了吗?故 非常不建议 在 Entity 使用 lombok 的 @Data
。
最后, 打开浏览器, 登入 http://localhost:8080/h2
就能看到以下画面