简介:本文详细介绍SpringBoot2.x整合H2内存数据库实现CRUD操作的全流程,涵盖依赖配置、实体类设计、Repository接口定义及Controller层实现,适合快速搭建测试环境。
H2数据库是一款轻量级的Java关系型数据库,支持内存模式和磁盘模式两种运行方式。其核心优势在于零配置启动和嵌入式集成,尤其适合SpringBoot项目的本地开发与测试场景。内存模式下,数据库生命周期与JVM进程绑定,重启后数据自动清空,这一特性使其成为单元测试、原型开发的理想选择。
| 特性 | 内存模式 | 磁盘模式 |
|---|---|---|
| 数据存储 | JVM堆内存 | 文件系统 |
| 启动速度 | 极快(无需IO) | 较慢(需加载文件) |
| 数据持久性 | 进程终止后丢失 | 永久保存 |
| 适用场景 | 测试、临时数据存储 | 生产环境、长期数据存储 |
<dependencies><!-- Spring Data JPA --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- H2 Database --><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><!-- Lombok(可选) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>
spring:datasource:url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MYSQLdriver-class-name: org.h2.Driverusername: sapassword:h2:console:enabled: truepath: /h2-consolesettings:web-allow-others: truejpa:hibernate:ddl-auto: updateshow-sql: trueproperties:hibernate:format_sql: true
关键参数说明:
DB_CLOSE_DELAY=-1:防止JVM退出时自动关闭数据库MODE=MYSQL:兼容MySQL语法(可选PostgreSQL/Oracle等)ddl-auto: update:自动更新表结构(生产环境慎用)
@Entity@Table(name = "t_user")@Datapublic class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(nullable = false, length = 50)private String username;@Column(nullable = false, length = 100)private String email;@Column(name = "create_time")private LocalDateTime createTime;@PrePersistpublic void prePersist() {this.createTime = LocalDateTime.now();}}
public interface UserRepository extends JpaRepository<User, Long> {// 自定义查询方法List<User> findByUsernameContaining(String keyword);@Query("SELECT u FROM User u WHERE u.email = :email")Optional<User> findByEmail(@Param("email") String email);}
@Service@RequiredArgsConstructorpublic class UserService {private final UserRepository userRepository;public User create(User user) {return userRepository.save(user);}public Optional<User> findById(Long id) {return userRepository.findById(id);}public List<User> findAll() {return userRepository.findAll();}public User update(Long id, User userDetails) {return userRepository.findById(id).map(user -> {user.setUsername(userDetails.getUsername());user.setEmail(userDetails.getEmail());return userRepository.save(user);}).orElseThrow(() -> new RuntimeException("User not found"));}public void delete(Long id) {userRepository.deleteById(id);}}
@RestController@RequestMapping("/api/users")@RequiredArgsConstructorpublic class UserController {private final UserService userService;@PostMappingpublic ResponseEntity<User> create(@RequestBody User user) {User savedUser = userService.create(user);return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);}@GetMapping("/{id}")public ResponseEntity<User> findById(@PathVariable Long id) {return userService.findById(id).map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build());}@GetMappingpublic ResponseEntity<List<User>> findAll() {return ResponseEntity.ok(userService.findAll());}@PutMapping("/{id}")public ResponseEntity<User> update(@PathVariable Long id, @RequestBody User user) {User updatedUser = userService.update(id, user);return ResponseEntity.ok(updatedUser);}@DeleteMapping("/{id}")public ResponseEntity<Void> delete(@PathVariable Long id) {userService.delete(id);return ResponseEntity.noContent().build();}}
启动应用后,访问 http://localhost:8080/h2-console,配置如下:
jdbc
mem:testdbsa
-- 创建表(JPA自动生成时无需手动执行)CREATE TABLE t_user (id BIGINT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,email VARCHAR(100) NOT NULL,create_time TIMESTAMP);-- 插入测试数据INSERT INTO t_user (username, email) VALUES('admin', 'admin@example.com'),('user1', 'user1@example.com');-- 查询数据SELECT * FROM t_user WHERE username LIKE '%ad%';
数据初始化脚本:
src/main/resources下创建data.sql(启动时执行)
INSERT INTO t_user (username, email) VALUES ('test', 'test@example.com');
多环境配置:
# application-dev.ymlspring:datasource:url: jdbcmem:testdb;DB_CLOSE_DELAY=-1
# application-prod.ymlspring:datasource:url: jdbc//localhost:3306/prod_db
H2控制台404错误:
@EnableH2Console注解(SpringBoot2.x默认已启用)spring.h2.console.enabled=true表不存在错误:
spring.jpa.hibernate.ddl-auto配置@Entity注解中文乱码问题:
jdbcmem:testdb;DB_CLOSE_DELAY=-1;MODE=MYSQL;CHARACTER_ENCODING=UTF-8
@Configurationpublic class H2Config {@Beanpublic ServletRegistrationBean<H2ConsoleServlet> h2ConsoleServlet() {return new ServletRegistrationBean<>(new H2ConsoleServlet(), "/h2-console/*");}@Beanpublic WebServerFactoryCustomizer<TomcatServletWebServerFactory> containerCustomizer() {return container -> container.addConnectorCustomizers(connector -> connector.setProperty("relaxedQueryChars", "|[]"));}}
@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/h2-console/**").permitAll().anyRequest().authenticated().and().csrf().disable() // H2控制台需要禁用CSRF.headers().frameOptions().disable(); // 允许H2的iframe}}
通过本文的实践,我们完成了SpringBoot2.x与H2内存数据库的完整集成,实现了:
扩展建议:
application.yml中的datasource配置H2数据库特别适合以下场景:
完整代码示例已上传至GitHub,包含Postman测试集合和详细README文档。读者可克隆仓库后直接运行测试,体验完整的CRUD操作流程。