Spring Boot 2.1.3 整合 H2Datase 嵌入式数据库

目录

导入 h2DB 依赖

实体类 与 Dao 接口

数据源配置

JPA 持久化配置

浏览器 MVC 访问进行 CRUD

H2 自带控制层访问

Spring Boot 配置 H2 控制台


导入 h2DB 依赖

1、H2 理论知识、手动操作数据的方式,可以参考《H2_Database 概述、下载与安装、及使用入门》,本文介绍使用 Java 应用来操作 H2 数据库

2、Java 使用 H2 数据库非常简单,H2 无需安装 ,直接将 Jar 包导入到项目中即可使用,非常方便。

3、本文环境:JDK 1.8 + Spring Boot 2.1.3 + H2 1.4.198 + Maven 3.5.2 + IDEA 14.

4、pom.xml 文件中导入 h2 依赖,为了操作数据库方便使用 JPA 组件操作数据库:




	org.springframework.boot
	spring-boot-starter-web



	org.springframework.boot
	spring-boot-starter-data-jpa



	com.h2database
	h2
	compile

https://github.com/wangmaoxiong/h2Smil/blob/master/pom.xml

实体类 与 Dao 接口

1、Spring Data JPA 也是基于 ORM 思想,底层是 Hibernate 实现,所以 POJO 与数据库表的映射关系写法与以前写 Hibernate 时基本无异。

2、这里将通过在配置文件设置 ddl‐auto: update ,使用 JPA 根据映射自动建表。

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date;
/**
 * Created by Administrator on 2019/2/27 0027.
 * 电视机实体
 */
@Entity
public class Television {
    @Id//标识为主键
    @GeneratedValue(strategy = GenerationType.AUTO)//指定主键生成的方式,AUTO 指定 H2 数据库主键自动增长
    private Integer tvId;//电视id,主键

    /**
     * 下面没标识的属性都会以默认值和数据库表的字段进行映射对应
     * 如果修改默认值,又不属性的,可以参考:https://blog.csdn.net/wangmx1993328/article/details/82048775
     * 中的 "domain Area" 部分
     */
    private String tvName;//电视名称
    private Float tvPrice;//电视价格
    private Date dateOfProduction;//生产日期

	//提供 getter、setter、toString 方法
}

https://github.com/wangmaoxiong/h2Smil/blob/master/src/main/java/com/wmx/entity/TV.java

import com.wmx.www.entity.Television;
import org.springframework.data.jpa.repository.JpaRepository;
/**
 * Created by Administrator on 2019/2/27 0027.
 * 自己 dao 接口只需要实现 org.springframework.data.jpa.repository.JpaRepository
 * 便可以快捷操作数据库,因为 Spring Data JPA 就是专门用于简化关系型数据操作的
 * 自己的接口上无需再写 @Repository 注解,因为 JpaRepository 中已经设置了
 */
public interface TVRepository extends JpaRepository {
}

数据源配置

spring:
#数据源配置
  datasource:
    username: sa
    password: 123456
	#使用混合模式,默认情况下,H2 只运行一个进程访问,true 表示可以多个进程可以访问同一个数据库
    url: jdbc:h2:~/test;AUTO_SERVER=TRUE
    driver-class-name: org.h2.Driver
username 数据库登录账号。数据库不存在时,h2 会自动新建,此时账号密码自定义即可
password 数据库登录密码。当数据库已经自动创建过,此时账号密码需要保持一致。
url 连接的数据库地址,"jdbc:h2" 表示以 jdbc 方式连接 h2 数据库
url: jdbc:h2:~/test

1)表示连接系统当前登录用户的根目录下的 test 数据库,不存在时默认会新建。"~" 表示系统当前登录用户的根目录。可以使用 System.getProperty("user.home") 查看用户根目录.

2)默认以内嵌模式运行,此时 H2 数据库最多只能有一个连接,比如 Java 应用启动后占了一个 H2 连接后,手动运行 h2-version.jar,想从H2 Console控制台连接是报错的。

url: jdbc:h2:E:\wmx\h2Database\test2;AUTO_SERVER=TRUE 表示连接 E:\wmx\h2Database\test2 数据库,不存在时默认会新建,AUTO_SERVER=TRUE 表示使用混合模式,此时可以支持多个连接。
jdbc:h2:mem:DBName;DB_CLOSE_DELAY=-1 内存运行,数据不会持久化。关闭连接后数据库将被清空,适合测试环境。mem 表示内存。DBName 为数据库名称,可以自定义,如 test。
更多详细配置,可以参考官网附录:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#appendix

1、连接模式与连接设置都是通过 JDBC URL 指定,不熟悉或者忘记的,可以参考 "Database URL Overview"。

2、没有指定其它数据源时,Spring Boot 默认使用 HikariDataSource 数据源,测试运行如下:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@RunWith(SpringRunner.class)
@SpringBootTest
public class H2SmileApplicationTests {

    /**
     * Spring Boot 引用了 JPA 组件,JPA 组件引用了 JDBC,JDBC组件引用了 HikariCP 数据源
     * Spring Boot 默认使用 class com.zaxxer.hikari.HikariDataSource 数据源,
     * 程序员直接 DI 注入然后使用即可
     */
    @Resource
    DataSource dataSource;

    @Test
    public void contextLoads() throws SQLException {
        Connection connection = dataSource.getConnection();//获取连接
        System.out.println("数据源>>>>>>" + dataSource.getClass());
        System.out.println("连接>>>>>>>>>" + connection);
        System.out.println("连接地址>>>>>" + connection.getMetaData().getURL());
        connection.close();//关闭连接
    }
}

3、运行之后,控制台输出如下:

数据源>>>>>>class com.zaxxer.hikari.HikariDataSource
连接>>>>>>>>>HikariProxyConnection@519249777 wrapping conn1: url=jdbc:h2:E:\wmx\h2Database\test2 user=SA
连接地址>>>>>jdbc:h2:E:\wmx\h2Database\test2

JPA 持久化配置

#配置服务器请求端口与上下文路径
server:
  port: 8080
  servlet:
    context-path: /H2_Smile

spring:
#JPA配置
  jpa:
    show-sql: true  #表示在控制台显示 sql 语句,默认为 false
    hibernate:
      ddl-auto: update #默认为 none(无)

#ddl-auto 选择项如下
#create :启动时删数据库中的表,然后创建,退出时不删除数据表
#create-drop :启动时创建表,退出时删除数据表
#update :如果启动时表格式不一致则更新表,原有数据保留
#validate :项目启动表结构进行校验 如果不一致则报错

更多详细配置,可参考官网附录:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#appendix

浏览器 MVC 访问进行 CRUD

1、浏览器访问 TVController 控制层,TVController 直接调用 TVRepository 持久层,省略中间的 Services 层。

2、TVController 控制层内容如下:

import com.wmx.www.entity.Television;
import com.wmx.www.repository.TVRepository;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * Created by Administrator on 2019/2/28 0028.
 * 电视机控制层
 *
 * @RestController 注解是一个组合注解,相当于同时加了 @Controller、@ResponseBody。
 * @ResponseBody 表示类中所有方法的返回值,全部直接输出到浏览器请求页面
 */
@RestController
public class TVController {
    @Resource
    private TVRepository tvRepository;//电视机·仓库

    /**
     * Spring4.3 开始引进了 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping
     * 来简化常用的HTTP方法的映射,并更好地表达被注解方法的语义。
     * 以 @GetMapping为例,其相当于 @RequestMapping(method = RequestMethod.GET)的缩写,-
     * 该注解将HTTP Get 映射到特定的处理方法上。
     *
     * @return
     */
    //测试添加
    @GetMapping("/saveTV")
    public String saveTest() {
        //添加3个电视机,主键未设值时,采用自动增长
        for (int i = 0; i < 3; i++) {
            Television television = new Television();
            television.setTvName("小米" + (i + 1));
            television.setTvPrice(4400.0F);
            television.setDateOfProduction(new Date());
            tvRepository.save(television);
        }
        return "添加成功...";
    }

    //测试查询所有
    @GetMapping("/findAllTV")
    public List findAllTest() {
        List televisionList = tvRepository.findAll();
        for (Television television : televisionList) {
            System.out.println("查询所有:" + television);
        }
        return televisionList;
    }

    //测试查询单个
    @GetMapping("/findOneTV")
    public String findOneById(Integer tvId) {
        /**
         * 推荐使用 findById 方式,而不是 getOne方法
         * isPresent 判断 Optional是否为空,即有没有值
         */
        if (!StringUtils.isEmpty(tvId)) {
            Optional televisionOptional = tvRepository.findById(tvId);
            if (televisionOptional.isPresent()) {
                System.out.println("Television::" + televisionOptional.get());//取值
                return televisionOptional.get().toString();
            } else {
                System.out.println("主键为 " + tvId + " 的值为空...");
                return "主键为 " + tvId + " 的值为空...";
            }
        } else {
            return "请传入需要检索的 tvId 参数值...";
        }
    }

    //测试更新
    //@PathVariable可以用来映射URL中的占位符到目标方法的参数中
    @GetMapping("/updateTV/{tvId}/")
    public String updateTest(@PathVariable(value = "tvId") Integer tvId) {
        //这里根据页面传入的 id 值更新它
        if (!StringUtils.isEmpty(tvId)) {
            if (tvRepository.existsById(tvId)) {
                Television television = new Television();
                television.setTvId(tvId);
                television.setTvName("努比亚小牛520");
                television.setTvPrice(8888F);
                television.setDateOfProduction(new Date());
                //没有专门的 update 方法,save 方法当主键存在时,则更新,否则新增
                tvRepository.save(television);
                return "数据更新完成...";
            } else {
                return "当前修改的 tvId=" + tvId + " 数据不存在...";
            }
        } else {
            return "请传入需要修改的 tvId 参数值...";
        }
    }

    //测试根据主键 id 删除
    @GetMapping("/delById")
    public String delById(Integer tvId) {
        if (!StringUtils.isEmpty(tvId)) {
            if (tvRepository.existsById(tvId)) {
                tvRepository.deleteById(tvId);
                return "删除数据完成...";
            } else {
                return "主键为 " + tvId + " 的数据不存在...";
            }
        } else {
            return "请传入需要修改的 tvId 参数值...";
        }
    }

    //测试删除所有
    @GetMapping("/delAllTV")
    public String delAllTest() {
        tvRepository.deleteAll();
        System.out.println("成功删除表中所有数据....");
        return ("成功删除表中所有数据....");
    }
}

3、按着配置,应用访问的测试路径如下:

添加数据:http://localhost:8080/H2_Smile/saveTV
查询所有:http://localhost:8080/H2_Smile/findAllTV
根据id查询:http://localhost:8080/H2_Smile/findOneTV?tvId=10
根据id更新:http://localhost:8080/H2_Smile/updateTV/10/
根据id删除:http://localhost:8080/H2_Smile/delById?tvId=10
删除表中所有数据:http://localhost:8080/H2_Smile/delAllTV

H2 自带控制层访问

1、因为 JDBC URl 中使用了 AUTO_SERVER=TRUE 混合模式,所以在 java 程序操作 H2 数据库的同时,也可以使用下载的 H2 Database 程序运行,在 H2 Controller 中进行查看。

2、可以直接双击运行 maven 仓库下的 h2-x.x.xxx.jar 包打开 web 控制台页面,或者从 h2 官网下载。

Spring Boot 2.1.3 整合 H2Datase 嵌入式数据库_第1张图片

H2 Controller 连接使用的 JDBC URL 路径、以及账号,密码要与应用配置文件中的保持一致。

3、如果全局配置文件中配置数据源时,url 配置为:url: jdbc:h2:E:\wmx\h2Database\test2;AUTO_SERVER=TRUE,则表示 H2 生成的数据库文件会放在 E:\wmx\h2Database 目录下:

Spring Boot 2.1.3 整合 H2Datase 嵌入式数据库_第2张图片

test2.mv.db:这是数据库存储数据的文件
test2.trace.db:这是一个跟踪文件
test2.lock.db:这是一个锁文件

Spring Boot 配置 H2 控制台

1、上面演示的是 Java 应用中使用 H2 数据库,使用 Java 程序来对 H2 进行增删改查,然后使用下载的 h2-xx.xx.jar 程序手动从网页管理界面 H2 Console 控制台进行了查看。

2、显然 Java 应用中也导入了 h2-version.jar 包,肯定无需再借助外部的 h2-version.jar 程序,也能进行 H2 Console 查询和管理,Spring Boot 既然提供了  H2 组件,则显然会提供专门的配置,如下所示:

# H2 Web Console (H2ConsoleProperties)
spring.h2.console.enabled=false # Whether to enable the console.是否启用控制台
spring.h2.console.path=/h2-console # Path at which the console is available. 控制台访问路径
spring.h2.console.settings.trace=false # Whether to enable trace output.是否启用跟踪输出
spring.h2.console.settings.web-allow-others=false # Whether to enable remote access.是否启用远程访问

官网地址:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#appendix

3、现在修改全局配置 application.yml 文件,添加 h2 配置如下:

spring:
#H2 Web 控制台配置,启用 h2 Console 控制台,并设置访问路径
  h2:
    console:
      enabled: true
      path: /h2_console

4、接着再次运行项目,进行浏览器访问:

如上所示,此时便可以直接从 Java  web 应用访问 H2 Database 的 H2 Console 控制台了,而不需要使用下载的 h2-version.jar 程序了。

你可能感兴趣的:(H2_Databse)