如何在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