java 嵌入式数据_java 嵌入式数据库H2

H2作为一个嵌入型的数据库,它最大的好处就是可以嵌入到我们的Web应用中,和我们的Web应用绑定在一起,成为我们Web应用的一部分。下面来演示一下如何将H2数据库嵌入到我们的Web应用中。

一、搭建测试环境和项目

1.1、搭建JavaWeb测试项目

创建一个【H2DBTest】JavaWeb项目,找到H2数据库的jar文件,如下图所示:

kRZAPxQMMU9EUEQFJ3+H21Qi86+UzlzAAAAAElFTkSuQmCC

H2数据库就一个jar文件,这个Jar文件里面包含了使用JDBC方式连接H2数据库时使用的驱动类,将"h2-1.4.183.jar"加入到【H2DBTest】项目中,如下图所示:

AAAAAElFTkSuQmCC

二、启动H2数据库

既然是要将H2数据库作为我们Web应用的一部分嵌入进来,那么我们就要在Web应用中启动H2数据库的服务,这样我们才能够连接到H2数据库,因此我们可以编写一个专门用于启动H2数据库服务的监听器(Listener),监听器示例代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package me.gacl.web.listener;

2

3 import java.sql.SQLException;

4 import javax.servlet.ServletContextEvent;

5 import javax.servlet.ServletContextListener;

6 import org.h2.tools.Server;

7

8 /**

9 * @ClassName: H2DBServerStartListener

10 * @Description: 用于启动H2数据库服务的监听器,在应用系统初始化时就启动H2数据库的服务

11 * @author: 孤傲苍狼

12 * @date: 2014-12-20 下午11:43:39

13 *

14 */

15 public class H2DBServerStartListener implements ServletContextListener {

16

17 //H2数据库服务器启动实例

18 private Server server;

19 /*

20 * Web应用初始化时启动H2数据库

21 */

22 public void contextInitialized(ServletContextEvent sce) {

23 try {

24 System.out.println("正在启动h2数据库...");

25 //使用org.h2.tools.Server这个类创建一个H2数据库的服务并启动服务,由于没有指定任何参数,那么H2数据库启动时默认占用的端口就是8082

26 server = Server.createTcpServer().start();

27 System.out.println("h2数据库启动成功...");

28 } catch (SQLException e) {

29 System.out.println("启动h2数据库出错:" + e.toString());

30 e.printStackTrace();

31 throw new RuntimeException(e);

32 }

33 }

34

35 /*

36 * Web应用销毁时停止H2数据库

37 */

38 public void contextDestroyed(ServletContextEvent sce) {

39 if (this.server != null) {

40 // 停止H2数据库

41 this.server.stop();

42 this.server = null;

43 }

44 }

45 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

监听器写好之后,我们在Web.xml文件中注册这个监听器,另外,因为我们要将H2数据库嵌入到我们的Web应用当中,为了能够方便访问H2数据库提供的Console,我们可以在Web.xml文件中配置用于访问H2数据库Console的Servlet。

Web.xml文件的配置如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2

3 me.gacl.web.listener.H2DBServerStartListener

4

5

6

7

8 H2Console

9 org.h2.server.web.WebServlet

10

11 webAllowOthers

12

13

14

15 trace

16

17

18 1

19

20

21

22 H2Console

23 /console/*

24

48304ba5e6f9fe08f3fa1abda7d326ab.png

配置好Listener和访问Console的Servlet之后,我们就可以把H2数据库当作是我们Web应用中的一部分来使用了。

将Web应用部署到Tomcat服务器,当启动Tomcat服务器时,在控制台就可以看到H2数据库启动成功的消息,如下图所示:

a22c7dba72c804111f7737b4ac5932a3.png

为了进一步验证H2数据库是否真的是通过监听器正常启动了,我们可以访问一下H2数据库的Console,输入访问地址:"http://localhost:8080/H2DBTest/console/"进行访问,如下图所示:

ab715833adaa0f8527c376bcc7713a35.png

能够看到H2数据库Console的登录页面,说明了H2数据库已经正常启动了。

三、向H2数据库注册自定义的数据库函数

H2作为一个数据库,和其他类型的数据库一样,会自带有一些数据库函数给我们使用,但是H2数据库提供的数据库函数有限,无法满足我们开发中的需求,幸运的是,H2数据库支持自定义数据库函数的,因此我们可以根据开发中的实际应用场景编写满足我们需求的数据库函数。

下面就来说一下如何实现H2数据库的自定义函数

在MySQL数据库中有一个UUID函数是用来生成UUID的,执行"SELECT UUID()"就可以看到UUID函数生成的UUID,如下图所示:

3768332077999143ec4170c81d371ada.png

而默认情况下,H2数据库是没有提供有UUID这个函数给我们使用的,如下图所示:

9a3dc765a68540c47d1bdaf7467c2d0a.png

那么我们现在就来实现一个UUID函数,然后注册到H2数据库当中,这样H2数据库就支持UUID函数了,具体做法分为两个步骤:

(1) 使用Java实现自定义函数的方法。

(2) 将Java的自定义函数注册到H2数据库中。

首先我们来实现这个UUID函数,在java中,生成一个UUID的方法是使用java.util.UUID这个类里面的一个randomUUID()方法生成的,封装成一个uuid方法,代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package h2db.function.ext;

2

3 import java.util.UUID;

4

5 /**

6 * @ClassName: H2DBFunctionExt

7 * @Description: 针对H2数据库函数的扩展

8 * @author: 孤傲苍狼

9 * @date: 2014-12-20 下午11:20:34

10 *

11 */

12 public class H2DBFunctionExt {

13

14 /**

15 * 用法:SELECT uuid();

16 * H2数据库注册uuid函数:CREATE ALIAS uuid FOR "h2db.function.ext.H2DBFunctionExt.uuid";

17 * @Method: uuid

18 * @Description: 实现MySQL数据库的uuid函数,用于生成UUID

19 * @Anthor:孤傲苍狼

20 *

21 * @return

22 */

23 public static String uuid(){

24 return UUID.randomUUID().toString();

25 }

26 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

这样,我们的uuid函数就算是编写好了,需要注意的是,类和方法必须是公共(Public)的,且方法需为静态(static)的,如方法中使用了Connection对象需将其关闭。

接下来我们要将其注册到H2数据库中,须执行"CREATE ALIAS"语句,SQL语法如下:

1 CREATE ALIAS [IF NOT EXISTS] newFunctionAliasName [DETERMINISTIC] FOR classAndMethodName

其中[]括起来的部分是可选的,本例须执行的语句为:  CREATE ALIAS UUID FOR"h2db.function.ext.H2DBFunctionExt.uuid" ,执行结果如下图所示:

99baacfbc9b58edd22b2a96f188ccff6.png

这样H2数据库中就多了一个UUID函数可以使用了,我们再次执行"SELECT UUID()"语句就可以被H2数据库正常解析了,执行结果如下图所示:

d082c230a18e9897a8f0be7fee0b422f.png

以上就是针对H2数据库函数的一个扩展,我们向H2数据库新增加了一个UUID函数用于生成uuid。因此当H2数据库提供的函数不满足我们开发中的实际需求时,就可以使用这种方式来扩展H2数据库的函数了。接下来演示一下一次性向H2数据库扩展多个函数,我们编写一个H2DBFunctionExt类,在类中编写针对H2数据库的扩展函数,代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package h2db.function.ext;

2

3 import java.net.InetAddress;

4 import java.net.UnknownHostException;

5 import java.text.ParseException;

6 import java.text.SimpleDateFormat;

7 import java.util.Date;

8 import java.util.UUID;

9

10 /**

11 * @ClassName: H2DBFunctionExt

12 * @Description: 针对H2数据库函数的扩展

13 * @author: 孤傲苍狼

14 * @date: 2014-12-20 下午11:20:34

15 *

16 */

17 public class H2DBFunctionExt {

18

19 /**

20 * 用法:SELECT uuid();

21 * H2数据库注册uuid函数:CREATE ALIAS IF NOT EXISTS uuid FOR "h2db.function.ext.H2DBFunctionExt.uuid";

22 * @Method: uuid

23 * @Description: 实现MySQL数据库的uuid函数,用于生成UUID

24 * @Anthor:孤傲苍狼

25 *

26 * @return

27 */

28 public static String uuid(){

29 return UUID.randomUUID().toString();

30 }

31

32 /**

33 * H2数据库注册currentTime函数:CREATE ALIAS IF NOT EXISTS currentTime FOR "h2db.function.ext.H2DBFunctionExt.now";

34 * @Method: now

35 * @Description: 实现MySQL数据库的now()函数,用于生成当前系统时间

36 * @Anthor:孤傲苍狼

37 *

38 * @return

39 */

40 public static String now(){

41 return new Date().toLocaleString();

42 }

43

44 /**

45 * H2数据库注册IP函数:CREATE ALIAS IF NOT EXISTS IP FOR "h2db.function.ext.H2DBFunctionExt.getIp";

46 * @Method: getIp

47 * @Description:

48 * @Anthor:孤傲苍狼

49 *

50 * @return

51 */

52 public static String getIp(){

53 try {

54 InetAddress addr = InetAddress.getLocalHost();

55 //获得本机IP

56 return addr.getHostAddress();

57 } catch (UnknownHostException e) {

58 e.printStackTrace();

59 return "未知的IP地址";

60 }

61 }

62

63 /**

64 * H2数据库注册date_format函数:CREATE ALIAS IF NOT EXISTS date_format FOR "h2db.function.ext.H2DBFunctionExt.date_format";

65 * @Method: date_format

66 * @Description: 实现MySQL数据库的date_format()函数,用于格式化日期

67 * @Anthor:孤傲苍狼

68 * @param date

69 * @param pattern

70 * @return

71 */

72 public static String date_format(String date,String pattern){

73 if (date != null) {

74 SimpleDateFormat sdf = new SimpleDateFormat(pattern);

75 try {

76 Date temp = sdf.parse(date);

77 return sdf.format(temp);

78 } catch (ParseException e) {

79 e.printStackTrace();

80 }

81 }

82 return "";

83 }

84 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

为了实现批量注册H2数据库的扩展函数,我们可以编写一个Servlet,专门用于注册扩展函数,代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package me.gacl.sys.init;

2

3

4 import java.sql.Connection;

5 import java.sql.Statement;

6

7 import javax.servlet.ServletException;

8 import javax.servlet.http.HttpServlet;

9

10 import me.gacl.util.JdbcUtil;

11

12 /**

13 * @ClassName: RegisterH2ExtFuncServlet

14 * @Description:注册H2数据库的扩展函数

15 * @author: 孤傲苍狼

16 * @date: 2014-12-20 下午11:47:03

17 *

18 */

19 public class RegisterH2ExtFuncServlet extends HttpServlet {

20

21 /**

22 * @Field: serialVersionUID

23 */

24 private static final long serialVersionUID = 4379248469825545593L;

25

26 public void init() throws ServletException {

27 //1、注册uuid函数的SQL语句

28 String sql1 = "CREATE ALIAS IF NOT EXISTS uuid FOR \"h2db.function.ext.H2DBFunctionExt.uuid\"";

29 //2、注册currentTime函数的SQL语句

30 String sql2 = "CREATE ALIAS IF NOT EXISTS currentTime FOR \"h2db.function.ext.H2DBFunctionExt.now\"";

31 //3、注册IP函数的SQL语句

32 String sql3 = "CREATE ALIAS IF NOT EXISTS IP FOR \"h2db.function.ext.H2DBFunctionExt.getIp\"";

33 //4、注册date_format函数的SQL语句

34 String sql4 = "CREATE ALIAS IF NOT EXISTS date_format FOR \"h2db.function.ext.H2DBFunctionExt.date_format\"";

35 Connection connection = null;

36 Statement stmt = null;

37 try {

38 //获取数据库连接

39 connection = JdbcUtil.getConnection();

40 //获取Statement对象

41 stmt = connection.createStatement();

42 //添加要执行的SQL

43 stmt.addBatch(sql1);

44 stmt.addBatch(sql2);

45 stmt.addBatch(sql3);

46 stmt.addBatch(sql4);

47 //批量执行上述的4条SQL

48 stmt.executeBatch();

49 System.out.println("H2数据库扩展函数注册成功!");

50 stmt.clearBatch();

51 } catch (Exception e) {

52 System.out.println("H2数据库扩展函数注册失败!");

53 e.printStackTrace();

54 }finally{

55 try {

56 stmt.close();

57 connection.close();

58 } catch (Exception e2) {

59 e2.printStackTrace();

60 }

61 }

62 }

63 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

在Web.xml中注册RegisterH2ExtFuncServlet

48304ba5e6f9fe08f3fa1abda7d326ab.png

1

2 注册H2数据库的扩展函数

3 RegisterH2DBExtFunction

4 me.gacl.sys.init.RegisterH2ExtFuncServlet

5

14 1

15

48304ba5e6f9fe08f3fa1abda7d326ab.png

RegisterH2ExtFuncServlet要批量执行SQL语句,因此需要连接上H2数据库才能够执行,工具类JdbcUtil提供了获取数据库连接的方法,JdbcUtil的代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 /**

2 *

3 */

4 package me.gacl.util;

5

6 import java.io.InputStream;

7 import java.sql.Connection;

8 import java.util.Properties;

9 import org.h2.jdbcx.JdbcConnectionPool;

10

11 public class JdbcUtil {

12

13 /**

14 * H2数据库自带的连接池

15 */

16 private static JdbcConnectionPool cp = null;

17

18 static{

19 try {

20 //加载src目录下的h2config.properties

21 InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("h2config.properties");

22 Properties prop = new Properties();

23 prop.load(in);

24 //创建数据库连接池

25 cp = JdbcConnectionPool.create(prop.getProperty("JDBC_URL"), prop.getProperty("USER"), prop.getProperty("PASSWORD"));

26 } catch (Exception e) {

27 System.out.println("连接池初始化异常");

28 e.printStackTrace();

29 }

30 }

31

32 /**

33 * @Method: getConnection

34 * @Description:获取数据库连接

35 * @Anthor:孤傲苍狼

36 * @return

37 * @throws Exception

38 */

39 public static Connection getConnection() throws Exception{

40 return cp.getConnection();

41 }

42

43 public static JdbcConnectionPool getCp() {

44 return cp;

45 }

46 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

h2config.properties的配置信息如下:

JDBC_URL=jdbc:h2:tcp://localhost/~/h2db

USER=gacl

PASSWORD=123

当web应用启动时,就会执行RegisterH2ExtFuncServlet这个Servlet中的init方法,init方法内部的处理就是通过JdbcUtil工具类获取一个H2的数据库连接,然后创建Statement对象,再由Statement对象批量执行SQL向H2数据库注册扩展函数。

RegisterH2ExtFuncServlet执行的过程中如果没有出现任何错误,那就说明所有的针对H2数据库的扩展函数都注册成功了,我们可以到H2的Console去验证一下上述的4个扩展函数,如下图所示:

5615a7cdc0857c2187d8a1f5633b06d9.png

关于在Web应用中嵌入使用H2数据库,以及针对H2数据库函数的扩展的内容就讲解这么多了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLite 作为一个开源的嵌入数据库产品,具有系统开销小,检索效率高的特性,适用于手机、PDA、机顶盒设备等电器,并且作为嵌入数据库在可下载的消费类应用程序中运行的很好。这篇文章介绍嵌入数据库产品SQLite 的技术特点,并着重讨论研究与Java语言之间的接口,并以实例说明如何使用JAVA 开发基于SQLite 的应用程序。 正文: 通常我们采用各种数据库产品来实现对数据的存储、检索等功能,例如,Oracle,SQL Server, MySQL 等等。这些产品除提供基本的查询,删除,添加等功能外,也提供了很多高级特性,如触发器,存储过程,数据备份恢复,全文检索功能等。但实际上,很多的应用,仅仅利用到了这些数据库产品的基本特性而已。而且在一些小型应用上,或者某些特殊场合的应用,比如桌面程序,这些数据库产品就明显有一些臃肿。在这些情况下,嵌入数据库的优势就特别明显了。 嵌入数据库无须独立运行的数据库引擎,它是由程序直接调用相应的API 去实现对数据的存取操作。更直白的讲,嵌入数据库是一种具备了基本数据库特性的数据文件。嵌入数据库与其它数据库产品的区别是,前者是程序驱动, 而后者是引擎响应嵌入数据库的一个很重要的特点是它们的体积非常小,编译后的产品也不过几十K。这不但对桌面程序的数据存储方案是一个很好的选择,也使得它们可以应用到一些移动设备上。同时,很多嵌入数据库在性能上也优于其它数据库,所以在高性能的应用上也常见嵌入数据库的身影。 下面介绍的是开放源代码的嵌入数据库,SQLite。同时侧重研究如何应用Java 连接SQLite数据库,并开发基于SQLite 的应用程序。 ......

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值