这次研究是H2数据库了,关键还是再Linux下进行搭建部署的,被这个数据库快弄死了弄了4天时间,现在大致可以用了,还有些细节需要修正。

我这边使用的是springboot集成模式。直接使用代码启停方式的就和我的描述就不一样了。

H2数据库有3钟模式mem,file,remote 3种模式。

内存就不说了,这个就是临时的,我觉得用内存还不如jvm内存呢。没啥意思。当然也是由于我没有细究的缘故。

file模式是本地模式。本地创建相应的数据库文件,然后进行调用。这里会存在个问题就是本地用了file之后,我其他电脑想访问这个数据库就是没法打开。报错是数据库被占用。这个是真心难受。

那么使用remote模式这边会存在直接springboot启动起不来。

那么这会就需要借用H2数据库官网上的启动方式了。网址:http://www.h2database.com/

这里将最新版的程序下载下来。version 2.1.214这个版本,在本地解压后bin目录下有个h2w.bat 文件,windows下直接启动就好了。Linux下就需要使用指令去启动了。

相关指令如下:

java -cp h2-2.1.214.jar org.h2.tools.Server -web -webAllowOthers -tcp -tcpAllowOthers -ifNotExists

这里我详细说几个参数webAllowOthers,web管理界面是否在其他IP中可以访问,tcpAllowOthers ,其他电脑是否可以通过remote模式访问该系统的H2数据库,ifNotExists数据库不存在时是否允许创建,一般linux启动的时候这个是不开启的,不然你的linux系统中会充斥着一堆杂七杂八的数据库。通过linux系统自启。

如果你想修改默认的tcp端口,那也是可以的需要将这个入参带上    -tcpPort 19200 

如果大家好奇有哪些入参可以带入,我在这边就稍微截点源码出来:

 1 public void init(String... args) {
 2         // set the serverPropertiesDir, because it's used in loadProperties()
 3         for (int i = 0; args != null && i < args.length; i++) {
 4             if ("-properties".equals(args[i])) {
 5                 serverPropertiesDir = args[++i];
 6             }
 7         }
 8         Properties prop = loadProperties();
 9         port = SortedProperties.getIntProperty(prop,
10                 "webPort", Constants.DEFAULT_HTTP_PORT);
11         ssl = SortedProperties.getBooleanProperty(prop,
12                 "webSSL", false);
13         allowOthers = SortedProperties.getBooleanProperty(prop,
14                 "webAllowOthers", false);
15         setExternalNames(SortedProperties.getStringProperty(prop, "webExternalNames", null));
16         setAdminPassword(SortedProperties.getStringProperty(prop, "webAdminPassword", null));
17         commandHistoryString = prop.getProperty(COMMAND_HISTORY);
18         for (int i = 0; args != null && i < args.length; i++) {
19             String a = args[i];
20             if (Tool.isOption(a, "-webPort")) {
21                 port = Integer.decode(args[++i]);
22             } else if (Tool.isOption(a, "-webSSL")) {
23                 ssl = true;
24             } else if (Tool.isOption(a, "-webAllowOthers")) {
25                 allowOthers = true;
26             }  else if (Tool.isOption(a, "-webExternalNames")) {
27                 setExternalNames(args[++i]);
28             } else if (Tool.isOption(a, "-webDaemon")) {
29                 isDaemon = true;
30             } else if (Tool.isOption(a, "-baseDir")) {
31                 String baseDir = args[++i];
32                 SysProperties.setBaseDir(baseDir);
33             } else if (Tool.isOption(a, "-ifExists")) {
34                 ifExists = true;
35             } else if (Tool.isOption(a, "-ifNotExists")) {
36                 ifExists = false;
37             } else if (Tool.isOption(a, "-webAdminPassword")) {
38                 setAdminPassword(args[++i]);
39             } else if (Tool.isOption(a, "-properties")) {
40                 // already set
41                 i++;
42             } else if (Tool.isOption(a, "-trace")) {
43                 trace = true;
44             }
45         }
46 //            if (driverList != null) {
47 //                try {
48 //                    String[] drivers =
49 //                        StringUtils.arraySplit(driverList, ',', false);
50 //                    URL[] urls = new URL[drivers.length];
51 //                    for(int i=0; i<drivers.length; i++) {
52 //                        urls[i] = new URL(drivers[i]);
53 //                    }
54 //                    urlClassLoader = URLClassLoader.newInstance(urls);
55 //                } catch (MalformedURLException e) {
56 //                    TraceSystem.traceThrowable(e);
57 //                }
58 //            }
59         for (String[] lang : LANGUAGES) {
60             languages.add(lang[0]);
61         }
62         if (allowOthers) {
63             key = null;
64         }
65         updateURL();
66     }
 1 public void init(String... args) {
 2         port = Constants.DEFAULT_TCP_PORT;
 3         for (int i = 0; args != null && i < args.length; i++) {
 4             String a = args[i];
 5             if (Tool.isOption(a, "-trace")) {
 6                 trace = true;
 7             } else if (Tool.isOption(a, "-tcpSSL")) {
 8                 ssl = true;
 9             } else if (Tool.isOption(a, "-tcpPort")) {
10                 port = Integer.decode(args[++i]);
11                 portIsSet = true;
12             } else if (Tool.isOption(a, "-tcpPassword")) {
13                 managementPassword = args[++i];
14             } else if (Tool.isOption(a, "-baseDir")) {
15                 baseDir = args[++i];
16             } else if (Tool.isOption(a, "-key")) {
17                 key = args[++i];
18                 keyDatabase = args[++i];
19             } else if (Tool.isOption(a, "-tcpAllowOthers")) {
20                 allowOthers = true;
21             } else if (Tool.isOption(a, "-tcpDaemon")) {
22                 isDaemon = true;
23             } else if (Tool.isOption(a, "-ifExists")) {
24                 ifExists = true;
25             } else if (Tool.isOption(a, "-ifNotExists")) {
26                 ifExists = false;
27             }
28         }
29     }

TCP server running at tcp://192.168.1.126:9092 (others can connect)
Web Console server running at http://192.168.1.126:8082 (others can connect)

在这里你会发现,tcp的默认端口是9092,web访问的端口是8082

springboot H2 linux下搭建使用-LMLPHPspringboot H2 linux下搭建使用-LMLPHP从这两张图中也可以看出,带不带端口效果都是一致的。

当然这些参数你也可以在H2的源码中找到相应的地方在,在这个类中:org.h2.engine.Constants。

springboot H2 linux下搭建使用-LMLPHP

在linux系统中直接将其以程序的形式进行启动后,其他应用就可以通过remote的形式进行调用了。友情提示,启动H2的时候需要使用nohup进行启动。

这里我将我的H2配置信息发出来

 1 #设置H2驱动
 2 spring.datasource.driver-class-name=org.h2.Driver
 3 #设置H2远程TCP地址
 4 spring.datasource.url = jdbc:h2:tcp://192.168.?.???/~/test1
 5 #设置web界面是否启用
 6 spring.h2.console.enabled=true
 7 #设置其他ip地址是否可以访问webConsole
 8 spring.h2.console.settings.web-allow-others=true
 9 #设置H2默认地址
10 spring.h2.console.path=/h2
11 #实际地址就是 url:端口/程序默认地址/h2 这些配置信息可以去 org.springframework.boot.autoconfigure.h2下的H2ConsoleProperties中进行查看,真的不是我不想多点参数控制,而是springboot就只开放了这些。这是真心难受啊。

其他小知识,在h2的webConsole控制台如下图

springboot H2 linux下搭建使用-LMLPHP

这里有个配置功能,然后你一开始点击是能点击进去的,进入配置控制界面。但是一保存时候发现一直要输入密码,关键是我前前后后找了1天都没找到密码是哪里设置的。真心吐血,后面发现,保存之后他就会在windows系统中的用户目录下创建一个.h2.server.properties一个文件,自从有了这个文件就需要输入密码了。删掉就没有了。

后面我通过代码跟踪的形式去查了源码发现他的登录接口核心代码

 1 private String adminLogin() {
 2         String password = attributes.getProperty("password");
 3         if (password == null || password.isEmpty() || !server.checkAdminPassword(password)) {//将if屏蔽了就可以不用管密码了
 4             return "adminLogin.jsp";
 5         }
 6         String back = (String) session.remove("adminBack");
 7         session.put("admin", true);
 8         return back != null ? back : "admin.do";
 9     }
10 
11 boolean checkAdminPassword(String password) {
12         if (adminPassword == null) {
13             return false;
14         }
15         byte[] salt = Arrays.copyOf(adminPassword, 32);
16         byte[] hash = new byte[32];
17         System.arraycopy(adminPassword, 32, hash, 0, 32);
18         return Utils.compareSecure(hash, SHA256.getHashWithSalt(password.getBytes(StandardCharsets.UTF_8), salt));
19     }

看到这里的小伙伴应该知道他的坑爹之处了吧,密码不能为空,管理员默认密码也不能为空。关键是我执行到adminPassword的时候他是空的。真的是坑爹啊。当然将其屏蔽调就可以了,我调整之后,我的系统进入webConsole的配置界面已经不需要这个该死的密码认证了。真是白花了我一天的时间,在这里我为那1天时间默哀10秒钟。

10-11 10:43