SpringBoot:集成H2数据库并持久化,url中memfile有什么区别?

Posted Oxye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot:集成H2数据库并持久化,url中memfile有什么区别?相关的知识,希望对你有一定的参考价值。

H2依赖

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
</dependency>

持久化配置

SpringBoot版本是2.3.12.RELEASE,下面有些配置看SpringBoot版本的,比如spring.datasource.schema是这个版本以下的,spring.sql.init.data是更高版本的

./dbfile 是把持久文件生成到程序启动路径下,你也可以自定义其他路径

# 数据源配置
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.schema=classpath:db/h2-schema.sql
spring.datasource.url=jdbc:h2:file:./dbfile
spring.datasource.username=root
spring.datasource.password=root
# 下面是控制台的配置
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

H2 url的含义

先看以下两个常量,代表url开头与后半段,后半段的类型有mem内存模式file本地文件模式tcp|ssl远程模式,含义如下(参考http://www.h2database.com/html/features.html#embedded_databases)

TopicURL Format and Examples
Embedded (local) connectionjdbc:h2:[file:][] jdbc:h2:~/test jdbc:h2:file:/data/sample jdbc:h2:file:C:/data/sample (Windows only)
In-memory (private)jdbc:h2:mem:
In-memory (named)jdbc:h2:mem: jdbc:h2:mem:test_mem
Server mode (remote connections) using TCP/IPjdbc:h2:tcp://[:]/[ ] jdbc:h2:tcp://localhost/~/test jdbc:h2:tcp://dbserv:8084/~/sample jdbc:h2:tcp://localhost/mem:test
Server mode (remote connections) using TLSjdbc:h2:ssl://[:]/[ ] jdbc:h2:ssl://localhost:8085/~/sample;

org.h2.engine.Constants

	/**
     * The database URL prefix of this database.
     */
    public static final String START_URL = "jdbc:h2:";
    /**
     * The database URL format in simplified Backus-Naur form.
     */
    public static final String URL_FORMAT = START_URL +
            " .|mem:[name] | [file:]fileName | " +
            "tcp|ssl:[//]server[:port][,server2[:port]]/name [;key=value...]";

去驱动里查看,ConnectionInfo里把url截取,然后判断类型,当是file时,把持久化标识persistent标位了true,后续数据库启动和运行都会用到这个标识判断是否持久化

org.h2.engine.ConnectionInfo

	/**
     * Create a connection info object.
     *
     * @param u the database URL (must start with jdbc:h2:)
     * @param info the connection properties or @code null
     * @param user the user name or @code null
     * @param password
     *            the password as @code String or @code char[], or
     *            @code null
     */
    public ConnectionInfo(String u, Properties info, String user, Object password) 
        u = remapURL(u);
        originalURL = url = u;
        if (!u.startsWith(Constants.START_URL)) 
            throw getFormatException();
        
        if (info != null) 
            readProperties(info);
        
        if (user != null) 
            prop.put("USER", user);
        
        if (password != null) 
            prop.put("PASSWORD", password);
        
        readSettingsFromURL();
        Object timeZoneName = prop.remove("TIME ZONE");
        if (timeZoneName != null) 
            timeZone = TimeZoneProvider.ofId(timeZoneName.toString());
        
        setUserName(removeProperty("USER", ""));
        name = url.substring(Constants.START_URL.length());
        parseName();
        convertPasswords();
        String recoverTest = removeProperty("RECOVER_TEST", null);
        if (recoverTest != null) 
            FilePathRec.register();
            try 
                Utils.callStaticMethod("org.h2.store.RecoverTester.init", recoverTest);
             catch (Exception e) 
                throw DbException.convert(e);
            
            name = "rec:" + name;
        
    	

	private void parseName() 
        if (".".equals(name)) 
            name = "mem:";
        
        if (name.startsWith("tcp:")) 
            remote = true;
            name = name.substring("tcp:".length());
         else if (name.startsWith("ssl:")) 
            remote = true;
            ssl = true;
            name = name.substring("ssl:".length());
         else if (name.startsWith("mem:")) 
            persistent = false;
            if ("mem:".equals(name)) 
                unnamed = true;
            
         else if (name.startsWith("file:")) 
            name = name.substring("file:".length());
            persistent = true;
         else 
            persistent = true;
        
        if (persistent && !remote) 
            name = IOUtils.nameSeparatorsToNative(name);
        
    

SpringBoot集成Redis

SpringBoot集成Redis

1、概述

Redis是什么?

Redis(Remote Dictionary Server ),即远程字典服务。

是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis能该干什么?

  1. 内存存储、持久化,内存是断电即失的,所以需要持久化(RDB、AOF)
  2. 高效率、用于高速缓冲
  3. 发布订阅系统
  4. 地图信息分析
  5. 计时器、计数器(eg:浏览量)
  6. … …

特性

  1. 多样的数据类型

  2. 持久化

  3. 集群

  4. 事务


2、测试Redis

SpringBoot操作数据,Spring-Data、 jbdc、redis… …

SpringData与SpringBoot齐名的项目!

说明:在SpringBoot2.x之后,原来使用的jedis被替换为lettuce

jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,需使用jedis pool连接池!像BIO模式

lettuce:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据,更像NIO模式

新建一个项目

注意:

查看底层

源码分析:

@Bean
@ConditionalOnMissingBean(  //如果未注入组件条件,我们自己可以定义一个redisTemplate来替换这个默认的
    name = {"redisTemplate"}
)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    //默认的 RedisTemplate 没有过多的设置 redis 都是需要序列化的  !
    //两个泛型都是 Object  Object的类型,我们往后使用需要强制转换<String,String>
    RedisTemplate<Object, Object> template = new RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

@Bean
@ConditionalOnMissingBean  //由于String 是redis 中最常用的类型  所有说单独提出来一个bean!
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

1、导入依赖

2、配置连接

# SpringBoot 所有的配置类 都有一个自动配置类  RedisAutoConfiguration
# 自动配置类都会绑定一个 properties 配置文件  RedisProperties


#配置 redis
spring.redis.host=127.0.0.1
spring.redis.port=6379

spring.redis

3、测试!

package com.kk;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class Redis01SpringbootApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        /*
        redisTemplate
        opsForValue  操作字符串的  类似String
        opsForList  操作List  类似List
        opsForSet
        opsForHash
        opsForZSet
        opsForGeo
        opsForHyperLogLog

        除了基本的操作 ,我们常用的方法都可以直接通过redisTemplate 比如事务和基本的CRUD


         */


        //获取redis的连接对象
//        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//        connection.flushDb();
//        connection.flushAll();

        redisTemplate.opsForValue().set("kk1","kk2");
        System.out.println(redisTemplate.opsForValue().get("kk1"));

    }

}

3、自定义redisTemplate

首先先建一个实体类,测试

User类

package com.kk.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.Serializable;

@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
//在企业中,我们所有的pojo都会序列化
public class User implements Serializable {
    private String name;
    private int age;
}

测试:

@Test
public void test() throws JsonProcessingException {
    //真实的开发一般都使用json来传递对象
    User user = new User("kk", 17);
    String jsonUser = new ObjectMapper().writeValueAsString(user);//这样就变成了一个json对象了
    redisTemplate.opsForValue().set("user",jsonUser);
    System.out.println(redisTemplate.opsForValue().get("user"));
}

r = new ObjectMapper().writeValueAsString(user);//这样就变成了一个json对象了
redisTemplate.opsForValue().set(“user”,jsonUser);
System.out.println(redisTemplate.opsForValue().get(“user”));
}


==注意:如果不在User类中实现序列化,它会报错==

以上是关于SpringBoot:集成H2数据库并持久化,url中memfile有什么区别?的主要内容,如果未能解决你的问题,请参考以下文章

idea 中 springBoot 集成 h2 轻量级内存数据库

JavaWeb-SpringBoot_使用H2数据库实现用户注册登录

如何在 Spring Boot 库中启用 H2 控制台?

SpringBoot集成Redis

在内存数据库中使用 H2 进行 Spring Boot 集成测试

Spring Boot JPA 和 H2 记录未持久化