一、 Derby 数据库介绍
Apache Derby 是100% Java 编写的内存数据库,属于 Apache 的一个开源项目。并且是一个容易管理的关系数据库管理系统,可以和一些商业产品的特性进行交付。
Apache Derby 是一个与平台无关的数据库引擎,它以 Java 类库的形式对外提供服务。与其他难以部署的数据库不同, Derby 数据库体积小、安装非常简单,只需要将其 *.jar 文件复制到系统中并为用户的项目添加该 *.jar 文件即可。
二、 Derby 数据库的两种运行模式
1) 内嵌模式。Derby数据库与应用程序共享同一个JVM,通常由应用程序负责启动和停止,对除启动它的应用程序外的其它应用程序不可见,即其它应用程序不可访问它;
2) 网络模式。Derby数据库独占一个JVM,做为服务器上的一个独立进程运行。在这种模式下,允许有多个应用程序来访问同一个Derby数据库。
三、可以从许多技术方面来区分 Derby 和其他数据库系统
Derby 易于管理。当嵌入到客户机应用程序中时, Derby 系统不需要任何管理干预。
Derby 是可嵌入的。应用程序可以将数据库管理系统( Database Management System , DBMS )引擎嵌入应用程序进程中,从而无需管理单独的数据库进程或服务。通过网络服务器( Network Server )架构或您选择的服务器架构,可以将 Derby 作为单独的进程来运行。
Derby 是一个纯 Java 的类库:对于 Java 开发人员,这点十分重要,因为他们正试图维护 Java 技术的优点,
例如平台无关性、易于配置以及易于安装。
Derby不需要专有的 Java 虚拟机( Java Virtual Machine , JVM )。因为完全是用 Java 语言编写的,所以它适应所有合格的 JVM 。
DerbyDBMS 引擎是轻量级的。类文件大小大约是 2MB ,并且只使用了4MB 的 Java 堆。
Derby 支持使用 Java 编写存储过程和函数,这些存储过程和函数可以在应用程序的任何层上运行。 Derby 没有专用的存储过程语言,它使用 JDBC 。
四、 Derby 数据库的优缺点
1 、 Derby 定位是小型数据库 , 特别是嵌入式 .支持的数据库小于 50GB, 对于小型网站 , 事务不复杂的应用, 使用它的还是很不错的 . 另外大型桌面应用也可以用它来保存配置和其他数据 , 可以做到与文件格式无关 ,因为都是访问数据库 .
2 、功能: Derby 支持标准 SQL92, SQL1999, SQL2003, 支持临时表 , 索引 , 触发器 , 视图 , 存储过程 ,外键 , 约束 , 并行 , 事务 , 加密与安全等 . 只要有JDK(>=1.3), 就可以运行 Derby.
3 、安全性: Derby 的安全性也做得很到位 , 包括用户鉴权和加密解密 .
4 、性能: Derby 的性能也是不错的 . 在插入 100 万条记录时 , CPU 的占用率一直低于 40%, 平均每插一条记录耗时小于 0.3 毫秒 . 这对于满足桌面应用程序是绰绰有余的 . 但是比 Oracle 、 MySql 等专业数据库性
能要低
五、 使用方法
1、安装Derby数据库
只需要从Derby官方网站下载Derby的zip或者tar包,解压就可以了。这里以db-derby-10.4.1.3-bin版本为例,解压后得到以下目录:
1) bin目录,包含了一些工具脚本和设备环境的脚本;
2) demo目录,包含了一些实例程序;
3) docs目录,包含了Derby的文档;
4) javadoc目录,包含了Derby的API文档;
5) lib目录,包含了Derby数据库的jar文件;
6) test目录,Derby的一些测试jar包;
2、使用ij脚本
1) 运行内嵌模式的Derby数据库在命令行中找到bin目录,使用输入ij使用ij工具(或单击ij.bat后启动ij工具)。然后通过如下命令创建数据库,并与数据库创建连接:connect ‘jdbc:derby:firstdb;create=true';(通过connect命令可以与指定数据库创建连接,通过一个JDBC URL来指定与哪个数据库创建连接。ij命令是不区分大小写的。参数中jdbc:derby是Derby数据库的驱动协议;firstdb是数据库名称,由于没有指定路径,数据库将会被创建在当前你命令行下所在的目录下;create=true表示如果数据库不存在,则创建该数据库;";"是ij命令的终止符。当数据库创建成功时,Derby会在当前你命令行下所在的目录下创建一个与数据库命一致(这里是firstdb)的目录,其中存放了数据库的文件。)与数据库连接上后,就可以开始执行SQL脚本了,如创建一个表格:
create table firsttable(id int primary key, name varchar(20));
然后插入记录:
insert into firsttable values(1, ‘Hotpepper');
也可以执行查询:
select * from firsttable;
也可以通过run命令来执行sql文件:
run 'E:/derby/demo/ToursDB_schema.sql';
最后通过exit;来退出ij工具。
你可以在当前你命令行下所在的目录中找到一个derby.log的日志文件,derby在其中记录的数据库启动、关闭的信息。
2) 运行网络模式的Derby数据库
这种模式下,需要使用两个控制台窗口,一个用于启动Derby数据库服务端,另一个做为访问Derby数据库的客户端。需要在命令行进入bin目录,运行startNetworkServer.bat启动数据库服务器,另一个端口跟运行内嵌模式的Derby数据库类似,只是连接的命令不同:
connect 'jdbc:derby://localhost:1527/G:/CSESI_DATA/CSESI;create=true';
(其中localhost:1527是本地和端口号,后面的是G盘的某个数据库,也可以是网上的)
一、插入(INSERT时报错)
1、错误:java.sql.SQLIntegrityConstraintViolationException: 列“test”无法接受空值。
可能原因:建表时test列为not null 但插入数据时给与了null值
2、错误:java.sql.SQLSyntaxErrorException: 列“eeeq”不在 FROM 列表的任何表中,或者它出现在 join 规范内但超出 join 规范的作用域,或者它出现在 HAVING 子句中但不在 GROUP BY 列表中。如果这是 CREATE 或 ALTER TABLE 语句,则“eeeq”不是目标表中的列。
可能原因:可能把INSERT INTO "testTable" ("test1", "test2", "test3") VALUES (‘eeeq’, 1, 2)写成了INSERT INTO "testTable" ("test1", "test2", "test3") VALUES ("eeeq", 1, 2)。其实就是说必须设置成‘eeeq’,其他格式eeeq、"eeeq"等都会报该错误
3、错误:java.sql.SQLSyntaxErrorException: 尝试修改标识列“ID”
可能原因:id列设置了自动增长,但是添加数据的时候尝试给id列指定一个值
二、更新/修改(UPDATE/ALTER时报错)
1、错误:java.sql.SQLSyntaxErrorException: 列“2”不在 FROM 列表的任何表中,或者它出现在 join 规范内但超出 join 规范的作用域,或者它出现在 HAVING 子句中但不在 GROUP BY 列表中。如果这是 CREATE 或 ALTER TABLE 语句,则“2”不是目标表中的列。
可能原因:表中并没有数据,但是尝试更新,那肯定是报错的
2、错误:约束条件“FK_WWW”无效:表“"APP"."TEST"”上没有与外键中列的数量和类型相匹配的唯一键或主键约束条件。
可能原因:两表的对应字段数据类型不一致
BIGINT 返回给定字符串或数字的 64-bit 整数常量。
CHAR 返回给定值的固定长度的字符表示,最大长度为 254 个字节,该给定值必须是内置的 Apache Derby 类型之一。
DATE 返回输入值的日期表示。
DOUBLE 返回输入数字或字符串的双精度浮点表示。
INTEGER 返回给定字符串、日期、时间或数字的整数常量。
SMALLINT 返回给定字符串或数字的小整数常量。
TIME 返回输入值的时间表示。
TIMESTAMP 返回输入值的时间戳表示。
VARCHAR 返回给定日期、时间、时间戳或字符串值的长度可变的字符表示,最大长度为 32,672 个字节。
之前在网上看到有人问 Derby SQL 分页实现的问题,网上有人给出这样的解决方案,SQL 如下:
其实,这样的分页查询,性能不理想,我试过在 300W 数据量中采用这种分页方式,需要 20~30秒之久;其实 Derby 10.6 以上版本有更好的分页支持,直接给出 SQL 实现如下:
这样分页性能可以提升至毫秒级速度···
希望对遇到同样需求的朋友有帮助,其实 Derby 是很棒的纯 Java 实现的开源数据库···