这次研究是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
从这两张图中也可以看出,带不带端口效果都是一致的。
当然这些参数你也可以在H2的源码中找到相应的地方在,在这个类中:org.h2.engine.Constants。
在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控制台如下图
这里有个配置功能,然后你一开始点击是能点击进去的,进入配置控制界面。但是一保存时候发现一直要输入密码,关键是我前前后后找了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秒钟。
标签:
留言评论