spring使用内存数据库(h2)

2020-11-09 15:37:04 浏览数 (1)

什么是内存数据库?

内存数据库,就是不需要去安装类似于mysql、oracle等这些数据库,而是通过程序运行的时候将sql执行将数据读取到内存中,程序结束后从内存中移除,减少因为安装sql或者一系类配置。

内存数据库可以解决什么问题?

没有测试环境,测试数据不能直接干扰真实线上数据;

环境原因,导致连接的时候慢、卡顿、超时等问题,本地装库又繁琐;

有哪些内存数据库?

H2

参考http://www.h2database.com/html/main.html

https://www.cnblogs.com/cnjavahome/p/8995650.html

HSQLDB

参考:http://hsqldb.org/

Apache Dery

参考:https://db.apache.org/derby/

sqlite

参考:https://www.sqlite.org/index.html

https://www.runoob.com/sqlite/sqlite-tutorial.html

内存数据库这么多,到底选哪个好?可以参考对比:

https://db-engines.com/en/system/Derby;H2;HyperSQL

最后建议根据自己的需求来选择,毕竟鞋子合不合适自己的脚试过了才知道!

代码下载:https://gitee.com/hong99/spring/issues/I1N1DF

代码实现

项目结构与位置

新增maven包

代码语言:javascript复制
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
    <scope>runtime</scope>
</dependency>

com.hong.spring.h2.vo.User

代码语言:javascript复制
package com.hong.spring.h2.vo;

import java.io.Serializable;

/**
 * 用户实体
 */
public class User implements Serializable {
   //用户名
   private String username;
   //年龄
   private Integer age;

   public User() {
   }

   public User(String username, Integer age) {
      this.username = username;
      this.age = age;
   }

   @Override
   public String toString() {
      return "User [username="   username   ", age="   age   "]";
   }

   public String getUsername() {
      return username;
   }

   public void setUsername(String username) {
      this.username = username;
   }

   public Integer getAge() {
      return age;
   }

   public void setAge(Integer age) {
      this.age = age;
   }

}

com.hong.spring.h2.dao.UserDao

代码语言:javascript复制
package com.hong.spring.h2.dao;



import com.hong.spring.h2.vo.User;

import java.util.List;

/**
 *
 * 功能描述:用户dao
 *
 * @param:
 * @return:
 * @auther: csh
 * @date: 2020/10/16 16:32
 */
public interface UserDao {

   /**
    * 查询用户
    * 
    * @return
    */
   List<User> listUser();

}

com.hong.spring.h2.dao.UserDaoImpl

代码语言:javascript复制
package com.hong.spring.h2.dao;

import com.hong.spring.h2.vo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 *
 * 功能描述:用户dao实现 
 *
 * @param: 
 * @return: 
 * @auther: csh
 * @date: 2020/10/16 16:32
 */
@Repository
public class UserDaoImpl implements UserDao {

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

   @Override
   public List<User> listUser() {
      List<User> users = this.jdbcTemplate.query(
              "SELECT username, age FROM USER",
              new RowMapper<User>() {
                  public User mapRow(ResultSet rs, int rowNum) throws SQLException {
                     User user = new User();
                      user.setUsername(rs.getString("username"));
                      user.setAge(rs.getInt("age"));
                      return user;
                  }
              });
      
      return users;
   }

}

com.hong.spring.h2.service.UserService

代码语言:javascript复制
package com.hong.spring.h2.service;

import com.hong.spring.h2.vo.User;

import java.util.List;

/**
 *
 * 功能描述:用户服务接口
 *
 * @param:
 * @return:
 * @auther: csh
 * @date: 2020/10/16 16:33
 */
public interface UserService {

   /**
    * 查询用户
    * 
    * @return
    */
   List<User> listUser();
}

com.hong.spring.h2.service.UserServiceImpl

代码语言:javascript复制
package com.hong.spring.h2.service;

import com.hong.spring.h2.dao.UserDao;
import com.hong.spring.h2.vo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *
 * 功能描述:用户服务接口实现 
 *
 * @param: 
 * @return: 
 * @auther: csh
 * @date: 2020/10/16 16:34
 */
@Service
public class UserServiceImpl implements UserService {

   private UserDao userdao;
   
    @Autowired
    public void setUserDao(UserDao userdao) {
        this.userdao = userdao;
    }

   @Override
    public List<User> listUser() {
      return userdao.listUser();
   }

}

com.hong.spring.h2.Application

代码语言:javascript复制
package com.hong.spring.h2;


import com.hong.spring.h2.service.UserService;
import com.hong.spring.h2.vo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 *
 * 功能描述:测试实现
 *
 * @param:
 * @return:
 * @auther: csh
 * @date: 2020/10/16 16:34
 */
public class Application {

   public static void main(String[] args) {
      @SuppressWarnings("resource")
      ApplicationContext context = new ClassPathXmlApplicationContext("h2/spring.xml");
      UserService UserService = context.getBean(UserService.class);
      
      List<User> users = UserService.listUser();
      
      for (User user : users) {
         System.out.println(user);
      }
   }

}

配置如下

h2/log4j2.xml

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
<!-- <Logger name="org.springframework.beans.factory" level="DEBUG"/> -->
    <Logger name="org.springframework" level="DEBUG"/>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

h2/schema.sql

代码语言:javascript复制
CREATE TABLE USER (
  USERNAME varchar(250) NOT NULL COMMENT '姓名',
  AGE INT DEFAULT NULL COMMENT '年纪'
);

h2/test-data.sql

代码语言:javascript复制
INSERT INTO user (username, age) VALUES ('admin', 11);
INSERT INTO user (username, age) VALUES ('hong', 100);

h2/spring.xml

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:jdbc="http://www.springframework.org/schema/jdbc"
   xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/jdbc 
       http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">

   <context:component-scan base-package="com.hong.spring.h2" />

    <!-- DataSource -->
   <jdbc:embedded-database id="dataSource" generate-name="true" type="H2">
       <jdbc:script location="classpath:h2/schema.sql"/>
       <jdbc:script location="classpath:h2/test-data.sql"/>
   </jdbc:embedded-database>
   
    <!-- PlatformTransactionManager -->
    <bean id="txManager" 
       class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- 定义事务Advice --> 
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!-- 所有“list”开头的都是只读 -->
            <tx:method name="list*" read-only="true"/>
            <!-- 其他方法,使用默认的事务设置 -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

</beans>

单元测试

h2.UserTest

代码语言:javascript复制
/**
 * @Auther: csh
 * @Date: 2020/10/16 16:53
 * @Description:通过h2测试
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:h2/spring.xml")
public class UserTest {

    @Autowired
    private UserService userService;

    @Test
    public void testUserService(){
        List<User> users = userService.listUser();

        for (User user : users) {
            System.out.println(user);
        }
    }
}

结果

代码语言:javascript复制
User [username=admin, age=11]
User [username=hong, age=100]

代码下载:https://gitee.com/hong99/spring/issues/I1N1DF

最后

一般在公司里面,如果多部分,有时候因为环境的原因无法进行连接数据库、慢、卡顿或者杂七杂八的一些原因,导致自测或者说自搭本地库非常繁琐,而通过这种h2或者FlyWay可以直接解决本地开发的问题,并且通过单元测试后可以直接将结果展示出来,验证程序的正确性,当然这种内存数据库有一定的弊端,比如像多数据库或者复杂的业务还是不是很方便,但是可以解决一块自己的功能不会因环境原因干着急问题。

参考文章:

https://my.oschina.net/u/4307191/blog/3509276

0 人点赞