什么是内存数据库?
内存数据库,就是不需要去安装类似于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