一、目标


主要实现目标:
1、定义数据模型 User ,拥有 id 、age 、 name 、passwd 四个属性,
2、创建 /user/add?id={id} 接口实现数据写入到 H2
3、测试 H2 数据的持久化

二、实践

1、数据模型层

创建 domain 文件夹作为数据模型的包

创建一个 User 数据模型,其包含 idnameagepasswd 四个字段。使用 @Id 指定字段 id 为主键,使用 @Table 指定表名为 tb_user

package com.xzbd.jh2.domain;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_user")
public class User {
    @Id
    private Long id;
    private String name;
    private String passwd;
    private Integer age;
}

2、Rerpository 层

应用 ORM 层选用 JPA 框架,JPA 的实现需要创建 Repository 。
创建 repostory 文件夹作为 DAO 层的包
创建 UserRepository 如下:

package com.xzbd.jh2.repostory;

import com.xzbd.jh2.domain.User;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User,Long> {
    
}

3、Service 层

创建 service 文件夹作为业务层的包

创建 UserServiceUserServiceImpl 如下所示:

package com.xzbd.jh2.service;

import com.xzbd.jh2.domain.User;


public interface UserService {
    User add(User user);
}
package com.xzbd.jh2.service;

import com.xzbd.jh2.domain.User;
import com.xzbd.jh2.repostory.UserRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public User add(User user) {
        return userRepository.save(user);
    }
    
}

4、Controller 层

创建 controller 文件夹作为控制层的报名

在控制层下创建 UserController ,代码如下:

package com.xzbd.jh2.controller;

import com.xzbd.jh2.domain.User;
import com.xzbd.jh2.service.UserService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import net.bytebuddy.utility.RandomString;

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/add")
    public User add(Long id) {
        User user = new User();
        user.setId(id);
        user.setAge(12 + Integer.valueOf("" + id));
        user.setName("name-" + id);
        user.setPasswd(id + "" + RandomString.make(5));
        User u = userService.add(user);
        return u;
    }
}

为了测试方便,提供的一个简单的接口 /user/add?id={id} 。该接口可以在浏览器中直接访问,只需要带上简单的id参数。

三、测试

1、运行应用 jh2

启动应用程序,此处使用的是 VS Code ,按 “F5” 即可启动,效果如下。

springboot h2兼容mysql springboot整合h2_h2


从启动日志中可以看出,hibernate 检测到新的数据模型 User 类,并创建了响应的数据表。其生成的创建SQL的语句为:

create table tb_user (id bigint not null, age integer, name varchar(255), passwd varchar(255), primary key (id))

使用的方言为: org.hibernate.dialect.H2Dialect

2、访问接口

访问 http://localhost:8080/user/add?id=1 ,浏览器结果如下图所示。

springboot h2兼容mysql springboot整合h2_java_02


应用日志

springboot h2兼容mysql springboot整合h2_java_03


其中有两句 SQL

Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_, user0_.passwd as passwd4_0_0_ from tb_user user0_ where user0_.id=?
Hibernate: insert into tb_user (age, name, passwd, id) values (?, ?, ?, ?)

讨论问题 insert 语句可以理解,为什么会有 select 语句呢 ?是不是因为调用了 repository 的 save 方法?

再依次访问下面连接,添加 id 为 2 - 5 的 user 数据。
http://localhost:8080/user/add?id=2http://localhost:8080/user/add?id=3http://localhost:8080/user/add?id=4http://localhost:8080/user/add?id=5

3、登录 H2 web 客户端查看数据

登录方式见 【H2实践】之 SpringBoot 整合,登陆后发现 TB_USER 表已经存在。再 SQL 编辑区中输入 SQL SELECT * FROM TB_USER 执行后,效果如下:

springboot h2兼容mysql springboot整合h2_H2_04

四、总结

文章是 SpringBoot 整合 H2 实践的关键部分。采用标准的 MVC 分层模式构建了项目,完成了目标需求设计。结合第三部分测试,验证了 SpringBoot 与 H2 数据库整合成功。