Derby 数据库的使用
·
文章目录
项目结构

说明一下:
data 和 derby.log 是项目启动后自动创建的,不需要手动去创建
test-schema.sql
CREATE TABLE t_user
(
id BIGINT NOT NULL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100),
age INTEGER
);
application.properties
spring.datasource.url=jdbc:derby://localhost:1527/data/myappdb;create=true;autoCommit=true
spring.datasource.driver-class-name=org.apache.derby.jdbc.ClientDriver
spring.datasource.username=
spring.datasource.password=
spring.sql.init.mode=never
mybatis-plus.mapper-locations=classpath*:/mapper/**/*.xml
mybatis-plus.type-aliases-package=com.example.demo.entity
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.global-config.db-config.db-type=derby
DerbyConfig
package com.example.config;
import org.apache.derby.drda.NetworkServerControl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import java.net.InetAddress;
@Configuration
public class DerbyConfig implements CommandLineRunner {
@Value("${derby.mode:network}")
private String derbyMode;
@Override
public void run(String... args) {
if ("network".equalsIgnoreCase(derbyMode)) {
startDerbyNetworkServer();
}
}
private void startDerbyNetworkServer() {
try {
NetworkServerControl server = new NetworkServerControl(InetAddress.getByName("localhost"), 1527);
server.start(null);
System.out.println("✅ Derby Network Server started on localhost:1527");
System.out.println("✅ Now both Application and IDEA can connect simultaneously");
} catch (Exception e) {
System.err.println("❌ Failed to start Derby Network Server: " + e.getMessage());
}
}
}
其余的文件
其余的文件 mapper service serviceImpl xml 等文件都是使用 mybaitsX 插件生成的
启动步骤
- 项目启动
- 连接 derby 数据库

注意!!!
这里的版本要和 pom 文件里面的版本需要保持一致

3. 在 APP 里面执行 建表语句

4. 测试
@RestController
@RequestMapping("/derby")
public class DerbyController {
@Autowired
private TUserService tUserService;
@RequestMapping("/test")
public String test() {
List<TUser> list = tUserService.list();
return list.toString();
}
@RequestMapping("/insert")
public String insert() {
TUser tUser = new TUser();
tUser.setUsername("setUsername");
tUser.setEmail("setEmail");
tUser.setAge(0);
boolean save = tUserService.save(tUser);
return save + "";
}
}
特别说明
- derby 可以使用 嵌入式模式,也就是 embedded 模式 和 客户端模式,也就是 remote
- 如果使用 embedded 模式,只允许一个 jvm 线程连接,也就是说,我一边使用工具连接 derby 数据库,一边通过接口查询数据,会报错
- 而使用 remote 模式,则可以避免这种情况
- derby 想启动 remote 模式,需要手动开启,也就是写代码,就是上文我提供的 DerbyConfig 这个文件
- derby 是随项目启动而启动的,项目一关,工具就连不上了
思考
什么时候使用 derby 合适,什么时候使用 mysql 合适?
选择 Derby 还是 MySQL,主要取决于你的项目需求、规模和对数据库特性的要求。为了帮你快速把握,我用一个表格汇总它们的核心区别:
| 特性 | Apache Derby | MySQL |
|---|---|---|
| 架构 | 嵌入式 (亦可网络模式) | 客户端-服务器架构 |
| 管理 | 零管理,开箱即用 | 需安装、配置、维护 |
| 性能焦点 | 嵌入式模式下读写快,资源占用低 | 高并发、大数据量、复杂查询 |
| 扩展性 | 弱,不适合分布式或大规模数据 | 强,支持集群、分片、读写分离 |
| SQL支持 | 支持SQL标准 | 支持SQL标准,并有大量扩展 |
| 主要场景 | 嵌入式应用、桌面应用、移动应用、测试 | Web应用、企业应用、高并发系统、大型应用 |
🔍 Derby 就像一个轻便的工具箱,就在你的应用程序“内部”工作。它非常适合嵌入式或轻量级的应用场景:
- 嵌入式应用:需要将数据库和应用打包在一起,无需用户单独安装和配置数据库的场景,例如桌面软件、移动应用。
- 开发与测试:希望快速搭建环境,避免复杂的数据库安装和配置,常用于单元测试或原型验证。
- 小型或轻型应用:数据量不大(通常在GB级别以下),并发用户数很少(例如单用户或少量用户)的场景。
- 需要零管理:应用场景要求简单的数据管理,且不希望投入精力进行数据库运维。
🌐 MySQL 则像一个强大的独立发电站,应用程序作为“客户端”通过网络连接到这个“服务器”。它擅长支持多用户、高并发、大数据量的场景:
- Web应用程序:需要支持大量用户并发访问的网站、Web应用服务。
- 企业级应用:需要处理大量数据和高并发请求,对性能、可靠性、可扩展性要求较高的关键业务系统,如CRM、ERP等。
- 需要复杂功能:应用需要复杂的SQL查询、存储过程、触发器、视图、分布式事务等高级功能。
- 高可用与扩展:系统需要高可用性保障(如主从复制、集群)、水平扩展(如分库分表)或大数据量(TB级别)处理能力。
💡 一些选择建议
- 初学者或快速原型:可以从 Derby 入手,它能让你更专注于业务逻辑而非数据库管理。
- 考虑未来变化:如果预计应用未来可能在用户量、数据量或复杂性方面显著增长,且你希望减少后续数据库迁移的工作量,那么即使初期规模较小,直接选择 MySQL 也可能是更省力的选择。
- 混合使用:在大型项目中,有时也会混合使用。例如,主应用使用 MySQL,而每个客户端或某个特定模块使用内嵌的 Derby 处理本地数据。
Derby 支持 mysql 的语法么? 支持事务么?
Apache Derby 和 MySQL 虽然都是关系型数据库,但在 SQL 语法上存在一些差异。让我用一个表格来汇总它们的主要特性对比,以便你快速了解:
| 特性 | Apache Derby | MySQL |
|---|---|---|
| SQL标准支持 | 支持 SQL92、部分 SQL99 和 SQL2003 特性 | 支持 SQL 标准,并提供大量扩展(如 FROM_UNIXTIME, REPLACE) |
| 特定函数 | 不支持 MySQL 特有函数(如 FROM_UNIXTIME),但提供类似功能的函数(如 TIMESTAMPADD 计算 Unix 时间戳) | 支持大量特有函数(如 FROM_UNIXTIME) |
| 分页语法 | 不支持 LIMIT• 10.4+:支持 ROW_NUMBER()• 10.7+:支持 OFFSET/FETCH | 支持 LIMIT 和 OFFSET |
| 条件语句 | 不支持存储过程或函数中的 IF 语句,但可使用 CASE 表达式或 MERGE 语句实现条件插入/更新 | 支持 IF 语句(存储过程中)、IF() 函数、REPLACE 语句 |
| 事务支持 | 完全支持 ACID 事务(原子性、一致性、隔离性、持久性) | 完全支持 ACID 事务 |
| 运行模式 | 嵌入式(与应用同 JVM)、网络服务器模式 | 客户端-服务器模式 |
| 适用场景 | 嵌入式应用、单元测试、桌面应用 | Web 应用、高并发系统、大型应用 |
🧭 给开发者的建议
- 在 Derby 中模拟 MySQL 函数:当需要在使用 Derby 进行测试或开发时模拟 MySQL 特有函数(如
FROM_UNIXTIME),可以:- 编写兼容层:创建自定义函数或使用 Derby 提供的其他函数(如
TIMESTAMPADD)来模拟实现。 - 使用抽象层:在应用代码中利用 ORM(如 Hibernate)或自定义的 DAO 层来抽象 SQL 差异,避免直接编写依赖特定数据库的 SQL。
- 编写兼容层:创建自定义函数或使用 Derby 提供的其他函数(如
- 处理条件插入/更新:在 Derby 中,需要实现“如果存在则更新,否则插入”的逻辑时,可以使用
MERGE语句(Derby 支持),这是更符合 SQL 标准的方式。 - 管理分页查询:根据你所使用的 Derby 版本,选择合适的分页方式:
- Derby 10.7 及以上:使用标准的
OFFSET ... FETCH子句。 - Derby 10.4 至 10.6:使用
ROW_NUMBER()函数配合子查询。 - 更早版本或简单分页:考虑使用 JDBC 的
setMaxRows()方法。
- Derby 10.7 及以上:使用标准的
💎 总结
Derby 是一个轻量级、嵌入式、支持 ACID 事务的关系型数据库,非常适合嵌入式环境、单元测试和桌面应用。虽然它不完全支持 MySQL 的所有语法特性(尤其是某些特定函数和 LIMIT 子句),但其对 SQL 标准和事务的良好支持,使其在特定场景下是一个可靠的选择。
更多推荐
所有评论(0)