Derby中的位操作实现

如何在Derby中进行位操作?最近公司决定将项目使用的数据库从sql server 切换到Java DB。大家都知道Apache旗下有一个著名的开源数据库叫Derby,公司决定采用这个数据库作为产品的自带数据库。所以没办法只能将原来的SQL语句用Derby的语法重写一遍。中间就遇到了语法不兼容的问题。其中位操作就困扰了我一下午。上网搜了很多例子,发现就只有一种方法,就是用mod函数来代替位操作,不过这种方法很麻烦,而且效率极差。所幸我发现Derby还支持UDF(用户自定义函数),可以定义Java函数来作为Derby的内建函数使用。这样这个问题就简单多了,下面是一个例子。

在这里我就不解释如何安装Java, Eclipse和Derby了,假设大家都机器上已经装有Java,Eclipse和Derby。有兴趣的朋友可以访问http://db.apache.org/derby/docs/dev/getstart/来获取Derby的详细内容。

1. 配置Derby到Eclipse

下载Derby的安装文件:derby_core_plugin_10.6.1.rar和derby_ui_doc_plugin_1.1.2.rar。解压并将其下的plugins里面的文件夹拷贝到Eclipse的plugins中。

 

2. 创建一个Java工程在Eclipse中,我的示例工程如下

 

3. 设置Derby的数据库路径,右键工程在打开的菜单中选择属性,

如果你的Derby服务器没起到,这个home目录是可修改的。我在工程里把它指向到了K:\Softwares\derby目录下。

 

4. 手动在Derby里创建数据库和测试表

首先,打开Derby的控制台交互窗口,在交互窗口里,我们可以手动执行一些SQL语句

然后,创建一个数据库(firstdb)和一张表(test_tb), 同时可以在数据库的目录文件夹下看到新生成的文件如下:

到这里,基本上我们需要的测试环境就算配置完成了,不过这里要提醒的是Derby是以‘;’号作为结束符的。第一次使用Derby交互窗口的朋友们一定要记得加哦^_^。

 

5. 开始写代码来实现我们需要的功能,

首先是创建一个带main函数的类,这个就不用说了。然后创建Derby的JDBC连接,请注意dbName这变量,因为我在这里将路径设置为绝对路径,也可以设置为相对路径。

 

	public static Connection creatJDBCConnection() {
		String driver = "org.apache.derby.jdbc.EmbeddedDriver";
		String dbName="K:\\Softwares\\derby\\firstdb";
		// create=true will create a new database. we have create a database
		// by manual, so set the create flag is false.
		String connectionURL = "jdbc:derby:" + dbName + ";create=false;";
		
		Connection conn = null;
		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		try {
			conn = DriverManager.getConnection(connectionURL);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return conn;
	}

 

 

接着创建一个java的实现函数和Derby的函数

 

	public static int BitwiseAnd(int a, int b) {
		return a&b;
	}

这个函数很简单没什么说的,唯一要说的就是下面这个Derby函数

 

 

	public static boolean registerUDF(Connection conn) {
		String bitwiseAndFunc = "CREATE FUNCTION BITWISEAND (" +
			"a int, b int) " +
			"RETURNS int " +
			"PARAMETER STYLE JAVA " +
			"NO SQL " +
			"LANGUAGE JAVA " +
			"EXTERNAL NAME 'code.ace.example.DerbyClass.BitwiseAnd' " ;
		
		try {
			Statement s = conn.createStatement();
			s.execute(bitwiseAndFunc);
			return true;
		} catch (SQLException e) {
			String theErr = (e).getSQLState();
			if (theErr.equals("X0Y68"))
				return true;
			
			e.printStackTrace();
			return false;
		}		
	}

请注意红色字体的部分,这三处地方的大小写,类型和名称都必须与实现函数一致,否则就会抛异常或调用失败。另外,在异常处理中我加了一些代码来处理函数已经存在的问题,因为在Derby中你创建的函数是一直存在于数据库中的,跟连接是否断开没有关系,所以必须去处理函数存在的问题。如果以上两步都做完了,那么我们就可以在SQL 语句中使用这个函数来

 

 

select id, name, flag from test_tb where BITWISEAND(flag, ?) = 1

 

下面我们写一些代码来测试一下这个函数。

 

        public static void testBitwiseAndOperation(Connection conn) {
		try {
			PreparedStatement psSelect = conn.prepareStatement(
					"select id, name, flag from test_tb where " +
					"BITWISEAND(flag, ?) = 1");
			psSelect.setInt(1, 1); // please change the second value to 2, and run again
			ResultSet rs = psSelect.executeQuery();
			if (rs.next()) {
				Formatter f = new Formatter();
				f.format("ID=%d, Name=%s, Flag=%d",
						rs.getInt(1), rs.getString(2), rs.getInt(3));
				System.out.println(f.toString());
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

注意,在开始测试前要先启动Derby服务器,

 

上面简单的介绍了一下如何用Java的实现去解决Derby数据库对一些函数不支持的问题。更多的应用大家可以上Derby的官网去获取,Derby的完整安装包中也有一些示例程序。

完整的例子代码从这里下载derby.rar, javadb.rar

posted @ 2010-12-19 20:04  moonz-wu  阅读(1845)  评论(0编辑  收藏  举报