H2数据库说明

     H2是一个文本数据库,你可以引用到自己的项目中,或在电脑上直接使用。好处在于不需要像Oracle或Mysql那样要安装软件,而且是轻量的。H2在使用时,只要引入h2*.jar文件,并指明JDBC驱动:org.h2.Driver,还有就是数据库的路径即可。H2在项目中使用时,你可以看作H2有一个服务平台,将你的项目web端和H2数据库连接起来。

 

电脑上使用H2

首先,在电脑上使用H2时,需要到官网上下载安装包http://www.h2database.com/html/main.html。下载All Platforms (zip, 8 MB)的文件。解压之后,你就可以看到如下的文件:

其次,如果是windows系统,点击bin目录下的h2.bat或h2w.bat都可以, 如果是linux系统,者执行 sh h2.sh.笔者是在自己的windows系统上运行,所以双击h2w.bat后,在电脑的右下角可以看到这个图标。,同时会弹出浏览器的登录窗口。访问的地址是:http://192.168.111.1:8082/login.jsp?jsessionid=d3de299ee67f8926edc84ffda951e248

注意,在测试的情况下,JDBC URL的路径最后要写上test.上图是笔者自己指定了数据库文件所放置的位置,所以写上了具体的路径,其实读者也可以直接写上jdbc:h2: test。test的密码都是sa。点击Connect,你将会看到如下的页面。

好了在上面的页面中,你就可以写上自己的SQL语句了。但是H2有好多在Oracle或Mysq中常用的函数是没有的,这样在开发中可能会带来麻烦。

 

项目中使用H2

  以上只是笔者简单的对H2的使用,也只能说是带读者入门吧。如果想要了解更多H2的使用,可到官网上找资料,或下载使用文档http://www.h2database.com/h2.pdf

  1. 项目中使用H2,需要引入h2*.jar。这就好比在Oracle和Mysql中引入相应的jar文件是一样的。但是H2不需要在电脑上安装任何的软件,除非你是要在浏览器中使用,那就需要上面介绍的那样了。
  2. 在项目中创建一个类,名为H2ConnectionPool,这个是连接池的方法。在连接池中你需要指名H2数据库文本所要放置的路径,一般在项目中都是直接写上:"jdbc:h2:~/test”,这是说明放置到项目的同等路径下。笔者为了项目中好查看数据库的数据,所以指明子路径是:E:/workspace/SelfMonitor/SelfMonitor/data/test。还有需要注意的是,在同一电脑上,只能有一个H2是开着,也就是说如果你用h2w.bat启用了H2,而在项目中还想使用h2,这是不请允许的,项目启动或浏览器连接都会报在使用中。另外,在项目中可能会有多个线程在操作数据库,有时候会引起线程使用上的冲突,即一个线程在连接数据库后关闭,导致另一个线程在使用时出现异常。在这种的情况下,你需要加上MVCC=TRUE的设置。代码如下。
    1. package com.owen.h2.database2;
    2. import java.sql.Connection;
    3. import java.sql.SQLException;
    4. import org.h2.jdbcx.JdbcConnectionPool;
    5. /**
    6. *H2数据库操作
    7. *
    8. * @author owen
    9. * @DATE 20190228
    10. *
    11. */
    12. public class H2ConnectionPool
    13. {
    14. private static H2ConnectionPool cp = null;
    15. private JdbcConnectionPool jdbcCP = null;
    16. private H2ConnectionPool()
    17. {
    18. String dbPath = "E:/workspace/SelfMonitor/SelfMonitor/data/test";
    19. jdbcCP = JdbcConnectionPool.create("jdbc:h2:" + dbPath+";MVCC=TRUE", "sa", ""); jdbcCP.setMaxConnections(50);
    20. }
    21. public static H2ConnectionPool getInstance()
    22. {
    23. if (cp == null)
    24. {
    25. cp = new H2ConnectionPool();
    26. }
    27. return cp;
    28. }
    29. public Connection getConnection() throws SQLException
    30. {
    31. return jdbcCP.getConnection();
    32. }
    33. }

     

  3. 有了以上的这个连接池,接下就可以对H2数据库进行操作。以下是提供几个常用的增删改查的方法封装。
    1. package com.dc.bd.dao;
    2. import java.sql.Connection;
    3. import java.sql.DatabaseMetaData;
    4. import java.sql.PreparedStatement;
    5. import java.sql.ResultSet;
    6. import java.sql.SQLException;
    7. import java.sql.Statement;
    8. import java.util.ArrayList;
    9. import java.util.HashMap;
    10. import java.util.List;
    11. import java.util.Map;
    12. import java.util.Set;
    13. import java.util.UUID;
    14. import org.apache.commons.lang3.StringUtils;
    15. import org.slf4j.Logger;
    16. import org.slf4j.LoggerFactory;
    17. import com.dc.bd.entity.Event;
    18. import com.dc.bd.entity.KpiInfo;
    19. /**
    20. * H2数据库操作
    21. *
    22. * @author owen
    23. * @DATE 20190228
    24. *
    25. */
    26. public class H2CommonDao
    27. {
    28. private static Logger logger = LoggerFactory.getLogger(H2CommonDao.class);
    29. /**
    30. * 建表方法
    31. *
    32. * @param tableName
    33. * @param items
    34. * @return
    35. * @throws SQLException
    36. */
    37. public static Boolean crateTable(String tableName, String[] items) throws SQLException
    38. {
    39. Connection conn = null;
    40. Statement stmt = null;
    41. try
    42. {
    43. conn = H2ConnectionPool.getInstance().getConnection();
    44. DatabaseMetaData meta = conn.getMetaData();
    45. ResultSet rsTables = meta.getTables(null, null, tableName, new String[] { "TABLE" });
    46. if (!rsTables.next())
    47. {
    48. stmt = conn.createStatement();
    49. StringBuilder sql = new StringBuilder();
    50. sql.append(" CREATE TABLE IF NOT EXISTS ");
    51. if (StringUtils.isNotEmpty(tableName))
    52. {
    53. sql.append(tableName);
    54. }
    55. if (items != null && items.length > 0)
    56. {
    57. sql.append(" ( ");
    58. sql.append(" hid VARCHAR(1024), ");
    59. for (int i = 0; i < items.length; i++)
    60. {
    61. sql.append(items[i]);
    62. sql.append(" VARCHAR(5000), ");
    63. }
    64. sql.append("PRIMARY KEY(hid)) ");
    65. }
    66. stmt.execute(sql.toString());
    67. }
    68. rsTables.close();
    69. return true;
    70. } finally
    71. {
    72. releaseConnection(conn, stmt, null);
    73. }
    74. }
    75. /**
    76. * 建表方法
    77. *
    78. * @param tableName
    79. * @param items
    80. * @return
    81. * @throws SQLException
    82. */
    83. public static Boolean crateTables(Map<String,String[]> tables) throws SQLException
    84. {
    85. Connection conn = null;
    86. Statement stmt = null;
    87. try
    88. {
    89. conn = H2ConnectionPool.getInstance().getConnection();
    90. DatabaseMetaData meta = conn.getMetaData();
    91. for(Map.Entry<String,String[]> table : tables.entrySet())
    92. {
    93. String tableName = table.getKey();
    94. logger.info("******创建数据库表:"+tableName);
    95. String[] items= table.getValue();
    96. ResultSet rsTables = meta.getTables(null, null, tableName, new String[] { "TABLE" });
    97. if (!rsTables.next())
    98. {
    99. stmt = conn.createStatement();
    100. StringBuilder sql = new StringBuilder();
    101. sql.append(" CREATE TABLE IF NOT EXISTS ");
    102. if (StringUtils.isNotEmpty(tableName))
    103. {
    104. sql.append(tableName);
    105. }
    106. if (items != null && items.length > 0)
    107. {
    108. sql.append(" ( ");
    109. sql.append(" hid VARCHAR(1024), ");
    110. for (int i = 0; i < items.length; i++)
    111. {
    112. sql.append(items[i]);
    113. sql.append(" VARCHAR(5000), ");
    114. }
    115. sql.append("PRIMARY KEY(hid)) ");
    116. }
    117. stmt.execute(sql.toString());
    118. }
    119. rsTables.close();
    120. }
    121. return true;
    122. } finally
    123. {
    124. releaseConnection(conn, stmt, null);
    125. }
    126. }
    127. /**
    128. * h2数据库插入数据
    129. *
    130. * @param tableName
    131. * @param items
    132. * @param values
    133. * @return
    134. * @throws SQLException
    135. */
    136. public static Boolean insertH2(String tableName, String[] items, String[] values) throws SQLException
    137. {
    138. Connection conn = null;
    139. PreparedStatement stmt = null;
    140. ResultSet rs = null;
    141. try
    142. {
    143. conn = H2ConnectionPool.getInstance().getConnection();
    144. StringBuilder sql = new StringBuilder();
    145. sql.append(" INSERT INTO ");
    146. if (StringUtils.isNotEmpty(tableName))
    147. {
    148. sql.append(tableName);
    149. }
    150. if (items != null && items.length > 0)
    151. {
    152. sql.append(" ( ");
    153. sql.append(" hid, ");
    154. String strItems = StringUtils.join(items, ",");
    155. sql.append(strItems);
    156. sql.append(" ) ");
    157. sql.append(" VALUES( ?,");
    158. for (int i = 0; i < items.length; i++)
    159. {
    160. sql.append("? ");
    161. if (i < items.length - 1)
    162. {
    163. sql.append(", ");
    164. }
    165. }
    166. sql.append(") ");
    167. }
    168. stmt = conn.prepareStatement(sql.toString());
    169. // values
    170. stmt.setString(1, getUuid());
    171. if (values != null && values.length > 0)
    172. {
    173. for (int i = 0; i < values.length; i++)
    174. {
    175. stmt.setString(i + 2, values[i]);
    176. }
    177. }
    178. return stmt.execute();
    179. } finally
    180. {
    181. conn.commit();
    182. releaseConnection(conn, stmt, rs);
    183. }
    184. }
    185. /**
    186. * h2数据库插入数据
    187. *
    188. * @param tableName
    189. * @param items
    190. * @param values
    191. * @return
    192. * @throws SQLException
    193. */
    194. public static Boolean insertH2(String tableName, String[] items, Map<String, String[]> values) throws SQLException
    195. {
    196. Connection conn = null;
    197. PreparedStatement stmt = null;
    198. ResultSet rs = null;
    199. Boolean result = false;
    200. try
    201. {
    202. conn = H2ConnectionPool.getInstance().getConnection();
    203. for (Map.Entry<String, String[]> value : values.entrySet())
    204. {
    205. // String kpiCode = value.getKey();
    206. String[] kpiValue = value.getValue();
    207. StringBuilder sql = new StringBuilder();
    208. sql.append(" INSERT INTO ");
    209. if (StringUtils.isNotEmpty(tableName))
    210. {
    211. sql.append(tableName);
    212. }
    213. if (items != null && items.length > 0)
    214. {
    215. sql.append(" ( ");
    216. sql.append(" hid, ");
    217. String strItems = StringUtils.join(items, ",");
    218. sql.append(strItems);
    219. sql.append(" ) ");
    220. sql.append(" VALUES( ?,");
    221. for (int i = 0; i < items.length; i++)
    222. {
    223. sql.append("? ");
    224. if (i < items.length - 1)
    225. {
    226. sql.append(", ");
    227. }
    228. }
    229. sql.append(") ");
    230. }
    231. stmt = conn.prepareStatement(sql.toString());
    232. // values
    233. stmt.setString(1, getUuid());
    234. if (kpiValue != null && kpiValue.length > 0)
    235. {
    236. for (int i = 0; i < kpiValue.length; i++)
    237. {
    238. stmt.setString(i + 2, kpiValue[i]);
    239. }
    240. }
    241. result = stmt.execute();
    242. }
    243. return result;
    244. } finally
    245. {
    246. conn.commit();
    247. releaseConnection(conn, stmt, rs);
    248. }
    249. }
    250. /**
    251. * h2数据库更新数据
    252. *
    253. * @param tableName
    254. * @param items
    255. * @param values
    256. * @return
    257. * @throws SQLException
    258. */
    259. public static Boolean updateH2(String tableName, String[] items, Map<String, String[]> values,Map<String,String> params) throws SQLException
    260. {
    261. Connection conn = null;
    262. PreparedStatement stmt = null;
    263. ResultSet rs = null;
    264. Boolean result = false;
    265. try
    266. {
    267. conn = H2ConnectionPool.getInstance().getConnection();
    268. for (Map.Entry<String, String[]> value : values.entrySet())
    269. {
    270. String[] kpiValue = value.getValue();
    271. StringBuilder sql = new StringBuilder();
    272. StringBuilder dealSql = new StringBuilder();
    273. sql.append(" UPDATE ");
    274. if (StringUtils.isNotEmpty(tableName))
    275. {
    276. sql.append(tableName);
    277. }
    278. if (items != null && items.length > 0)
    279. {
    280. sql.append(" SET ");
    281. for (int i = 0; i < items.length; i++)
    282. {
    283. sql.append(items[i] + "=?, ");
    284. }
    285. String strSql = sql.toString().trim();
    286. dealSql = new StringBuilder(strSql.substring(0, strSql.length()-1));
    287. dealSql.append(" WHERE ");
    288. for(Map.Entry<String, String> param : params.entrySet())
    289. {
    290. dealSql.append(param.getKey() + "='" + param.getValue()+"'");
    291. }
    292. }
    293. logger.info(dealSql.toString());
    294. stmt = conn.prepareStatement(dealSql.toString());
    295. // values
    296. if (kpiValue != null && kpiValue.length > 0)
    297. {
    298. for (int i = 0; i < kpiValue.length; i++)
    299. {
    300. stmt.setString(i + 1, kpiValue[i]);
    301. }
    302. }
    303. result = stmt.execute();
    304. }
    305. return result;
    306. } finally
    307. {
    308. conn.commit();
    309. releaseConnection(conn, stmt, rs);
    310. }
    311. }
    312. /**
    313. * 查询方法
    314. *
    315. * @param tableName
    316. * @param items
    317. * @param params
    318. * @return
    319. * @throws SQLException
    320. */
    321. public static List<Map<String, String>> selectH2(String tableName, String[] items, Map<String, String> params)
    322. throws SQLException
    323. {
    324. Connection conn = null;
    325. PreparedStatement stmt = null;
    326. ResultSet rs = null;
    327. List<Map<String, String>> result = new ArrayList<Map<String, String>>();
    328. try
    329. {
    330. conn = H2ConnectionPool.getInstance().getConnection();
    331. StringBuilder sql = new StringBuilder();
    332. sql.append(" Select ");
    333. if (items != null && items.length > 0)
    334. {
    335. String strItems = StringUtils.join(items, ",");
    336. sql.append(strItems);
    337. }
    338. sql.append(" FROM ");
    339. if (StringUtils.isNotEmpty(tableName))
    340. {
    341. sql.append(tableName);
    342. }
    343. // 存在查询条件
    344. if (params != null && params.size() > 0)
    345. {
    346. sql.append(" WHERE ");
    347. Set<String> kSet = params.keySet();
    348. for (String key : kSet)
    349. {
    350. sql.append(key);
    351. sql.append(" = ? and ");
    352. }
    353. sql.append("1 = 1");
    354. }
    355. stmt = conn.prepareStatement(sql.toString());
    356. // 存在查询条件
    357. if (params != null && params.size() > 0)
    358. {
    359. Set<String> kSet = params.keySet();
    360. Integer index = 1;
    361. for (String key : kSet)
    362. {
    363. stmt.setString(index, params.get(key));
    364. index++;
    365. }
    366. }
    367. rs = stmt.executeQuery();
    368. while (rs.next())
    369. {
    370. Map<String, String> resultMap = new HashMap<String, String>();
    371. for (int i = 0; i < items.length; i++)
    372. {
    373. resultMap.put(items[i], rs.getString(items[i]));
    374. }
    375. result.add(resultMap);
    376. }
    377. return result;
    378. } finally
    379. {
    380. releaseConnection(conn, stmt, rs);
    381. }
    382. }
    383. /**
    384. * 自定义sql
    385. *
    386. * @param sql
    387. * @param items
    388. * @param params
    389. * @return
    390. * @throws SQLException
    391. */
    392. public static List<Map<String, String>> selectH2BySql(String sql, List<String> items, List<String> params)
    393. throws SQLException
    394. {
    395. Connection conn = null;
    396. PreparedStatement stmt = null;
    397. ResultSet rs = null;
    398. List<Map<String, String>> result = new ArrayList<Map<String, String>>();
    399. try
    400. {
    401. conn = H2ConnectionPool.getInstance().getConnection();
    402. stmt = conn.prepareStatement(sql);
    403. // 存在查询条件
    404. if (params != null && params.size() > 0)
    405. {
    406. for (int i = 0; i < params.size(); i++)
    407. {
    408. stmt.setString(i + 1, params.get(i));
    409. }
    410. }
    411. rs = stmt.executeQuery();
    412. while (rs.next())
    413. {
    414. Map<String, String> resultMap = new HashMap<String, String>();
    415. for (int i = 0; i < items.size(); i++)
    416. {
    417. resultMap.put(items.get(i), rs.getString(items.get(i)));
    418. }
    419. result.add(resultMap);
    420. }
    421. return result;
    422. } finally
    423. {
    424. releaseConnection(conn, stmt, rs);
    425. }
    426. }
    427. /**
    428. * 自定义sql
    429. *
    430. * @param sql
    431. * @param items
    432. * @param params
    433. * @return
    434. * @throws SQLException
    435. */
    436. public static boolean h2BySql(String sql)
    437. throws SQLException
    438. {
    439. Connection conn = null;
    440. PreparedStatement stmt = null;
    441. try
    442. {
    443. conn = H2ConnectionPool.getInstance().getConnection();
    444. stmt = conn.prepareStatement(sql);
    445. return stmt.execute();
    446. } finally
    447. {
    448. releaseConnection(conn, stmt, null);
    449. }
    450. }
    451. /**
    452. * 自定义sql
    453. *
    454. * @param sql
    455. * @param items
    456. * @param params
    457. * @return
    458. * @throws SQLException
    459. */
    460. public static boolean h2BySqls(List<String> sqls)
    461. throws SQLException
    462. {
    463. Connection conn = null;
    464. PreparedStatement stmt = null;
    465. try
    466. {
    467. conn = H2ConnectionPool.getInstance().getConnection();
    468. boolean result = false;
    469. for(String sql : sqls)
    470. {
    471. stmt = conn.prepareStatement(sql);
    472. result = stmt.execute();
    473. }
    474. return result;
    475. } finally
    476. {
    477. releaseConnection(conn, stmt, null);
    478. }
    479. }
    480. private static void releaseConnection(Connection conn, Statement stmt, ResultSet rs) throws SQLException
    481. {
    482. if (rs != null)
    483. {
    484. rs.close();
    485. }
    486. if (stmt != null)
    487. {
    488. stmt.close();
    489. }
    490. if (conn != null)
    491. {
    492. conn.close();
    493. }
    494. }
    495. /**
    496. * 删除表
    497. *
    498. * @param tableName
    499. * @param items
    500. * @return
    501. * @throws SQLException
    502. */
    503. public static Boolean dropTable(String tableName) throws SQLException
    504. {
    505. Connection conn = null;
    506. Statement stmt = null;
    507. try
    508. {
    509. conn = H2ConnectionPool.getInstance().getConnection();
    510. DatabaseMetaData meta = conn.getMetaData();
    511. ResultSet rsTables = meta.getTables(null, null, tableName, new String[] { "TABLE" });
    512. if (!rsTables.next())
    513. {
    514. stmt = conn.createStatement();
    515. StringBuilder sql = new StringBuilder();
    516. sql.append(" DROP TABLE ");
    517. if (StringUtils.isNotEmpty(tableName))
    518. {
    519. sql.append(tableName);
    520. }
    521. sql.append(" IF EXISTS");
    522. stmt.execute(sql.toString());
    523. }
    524. rsTables.close();
    525. return true;
    526. } finally
    527. {
    528. releaseConnection(conn, stmt, null);
    529. }
    530. }
    531. public static String getUuid()
    532. {
    533. return UUID.randomUUID().toString().replace("-", "");
    534. }
    535. }

     

    总结

以上只是笔者简单的对H2的使用,也只能说是带读者入门吧。如果想要了解更多H2的使用,可到官网上找资料,或下载使用文档http://www.h2database.com/h2.pdf