嵌入式和客户端/服务器 JavaDB 编程
最后修改于 2020 年 7 月 13 日
在本教程中,我们将使用 JavaDB 以嵌入式和客户端/服务器模式创建 Java 应用程序。我们使用 JdbcTemplate 执行 SQL 语句。
JdbcTemplate 是一个用于简化 JDBC 编程的工具。它负责处理乏味且易出错的低级细节,例如事务处理、资源清理和正确异常处理。JdbcTemplate 包含在 Spring 的 spring-jdbc 模块中。
JavaDB
JavaDB 是随 JDK 提供的 Apache Derby 数据库。Derby 是一个用 Java 编写的关系型数据库管理系统。它实现了 SQL-92 核心子集以及一些 SQL-99 功能。它使用 IBM DB2 SQL 语法。Derby 的占地面积很小,约为 2MB。它支持事务。Derby 使用的数据库格式是可移植和平台独立的。
$ ls $JAVA_HOME/db 3RDPARTY bin lib LICENSE NOTICE README-JDK.html RELEASE-NOTES.html
JavaDB 的主目录位于 $JAVA_HOME/db 目录。
JDBC
JDBC 是 Java 编程语言的 API,它定义了客户端如何访问数据库。它提供了用于查询和更新数据库中数据的各种方法。JDBC 面向关系型数据库。从技术角度来看,该 API 是 java.sql 包中的一组类。要将 JDBC 用于特定数据库,我们需要该数据库的 JDBC 驱动程序。
客户端/服务器和嵌入式 Derby 应用程序
Derby 可以在 Java 应用程序中以两种基本方式使用:客户端/服务器和嵌入式。对于客户端/服务器应用程序,我们使用 org.apache.derby.jdbc.ClientDriver;对于 Derby 嵌入式应用程序,我们使用 org.apache.derby.jdbc.EmbeddedDriver。
Maven 依赖
Derby 驱动程序有两个 Maven 依赖项:derby 和 derbynet。derby 依赖项用于嵌入式应用程序,derbynet 用于客户端/服务器应用程序。
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.13.1.1</version>
</dependency>
这是包含 derby 驱动程序的 Maven 依赖项。
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.13.1.1</version>
</dependency>
这是包含 derbyclient 驱动程序的 Maven 依赖项。
连接字符串
客户端/服务器应用程序和嵌入式应用程序的连接字符串是不同的。
jdbc:derby://:1527/dbname
这是客户端/服务器应用程序的连接 URL。
jdbc:derby:dbname
这是嵌入式应用程序的连接 URL。
CARS 表
在我们的应用程序中,我们使用以下表
-- SQL for the CARS table
SET SCHEMA USER12;
CREATE TABLE CARS(ID BIGINT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY
(START WITH 1, INCREMENT BY 1), NAME VARCHAR(30), PRICE INT);
INSERT INTO CARS(Name, Price) VALUES('Audi', 52642);
INSERT INTO CARS(Name, Price) VALUES('Mercedes', 57127);
INSERT INTO CARS(Name, Price) VALUES('Skoda', 9000);
INSERT INTO CARS(Name, Price) VALUES('Volvo', 29000);
INSERT INTO CARS(Name, Price) VALUES('Bentley', 350000);
INSERT INTO CARS(Name, Price) VALUES('Citroen', 21000);
INSERT INTO CARS(Name, Price) VALUES('Hummer', 41400);
INSERT INTO CARS(Name, Price) VALUES('Volkswagen', 21600);
cars.sql 文件创建了 CARS 表。
$ $DERBY_HOME/bin/ij ij version 10.11 ij> CONNECT 'jdbc:derby:testdb'; ij> RUN 'cars.sql';
使用 ij 工具,我们从 SQL 脚本创建表。
JavaDB 嵌入式应用程序
在下面的示例中,我们从 CARS 表中检索所有汽车。该应用程序以嵌入式模式使用 JavaDB。
当应用程序使用嵌入式驱动程序访问 Derby 数据库时,Derby 引擎不在单独的进程中运行,也没有需要启动和关闭的单独数据库进程。相反,Derby 数据库引擎在与应用程序相同的 Java 虚拟机 (JVM) 中运行。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>JavaDBEmbedded</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.13.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
</dependencies>
</project>
这是 Maven POM 文件。它包含这些依赖项:derby 和 spring-jdbc。
package com.zetcode.bean;
public class Car {
private Long Id;
private String name;
private int price;
public Long getId() {
return Id;
}
public void setId(Long Id) {
this.Id = Id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
这是我们的 Car bean。实例化的类填充了来自 CARS 表的数据库记录。
package com.zetcode;
import com.zetcode.bean.Car;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
public class JavaDBEmbedded {
public static void main(String[] args) {
System.setProperty("derby.system.home", "/home/janbodnar/.derby");
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
dataSource.setUrl("jdbc:derby:testdb;user=USER12");
String sql = "SELECT * FROM Cars WHERE Id=?";
Long id = 1L;
JdbcTemplate jtm = new JdbcTemplate(dataSource);
Car car = (Car) jtm.queryForObject(sql, new Object[] {id},
new BeanPropertyRowMapper(Car.class));
System.out.printf("%d ", car.getId());
System.out.printf("%s ", car.getName());
System.out.printf("%d ", car.getPrice());
}
}
该示例以嵌入式模式连接到 Derby。它检索由其 ID 标识的汽车对象。
System.setProperty("derby.system.home", "/home/janbodnar/.derby");
通过设置 Derby 系统主目录,我们指示在哪里查找 testdb 数据库。
SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); dataSource.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
我们将 EmbeddedDriver 设置到数据源。
dataSource.setUrl("jdbc:derby:testdb;user=USER12");
这是连接到嵌入式模式下的 testdb 数据库以及 USER12 模式的 URL。
String sql = "SELECT * FROM Cars WHERE Id=?";
此 SQL 语句从数据库中选择一个汽车对象。
JdbcTemplate jtm = new JdbcTemplate(dataSource);
创建了一个 JdbcTemplate;它将数据源作为参数。
Car car = (Car) jtm.queryForObject(sql, new Object[] {id},
new BeanPropertyRowMapper(Car.class));
我们使用 queryForObject 方法查询对象。我们提供了 SQL 语句、参数和行映射器。BeanPropertyRowMapper 将一行转换为 Car 目标类的新实例。
System.out.printf("%d ", car.getId());
System.out.printf("%s ", car.getName());
System.out.printf("%d ", car.getPrice());
我们将汽车数据打印到终端。
1 Audi 52642
这是应用程序的输出。
JavaDB 客户端/服务器应用程序
在第二个示例中,我们创建了一个客户端/服务器模式的 JavaDB 应用程序。在此模式下,Derby 服务器与 Java 应用程序是分开的。
$ $DERBY_HOME/bin/startNetworkServer &
我们使用 startNetworkServer 工具启动 Derby 网络服务器。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>JavaDBClientServer</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.13.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
</dependencies>
</project>
这是 Maven POM 文件。它包含这些依赖项:derbyclient 和 spring-jdbc。
package com.zetcode.bean;
public class Car {
private Long Id;
private String name;
private int price;
// getters and setter
}
这是我们的 Car bean。
package com.zetcode.main;
import com.zetcode.bean.Car;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
public class JavaDBClientServer {
public static void main(String[] args) {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriver(new org.apache.derby.jdbc.ClientDriver());
dataSource.setUrl("jdbc:derby://:1527/testdb;user=USER12");
String sql = "SELECT * FROM Cars WHERE Id=?";
Long id = 1L;
JdbcTemplate jtm = new JdbcTemplate(dataSource);
Car car = (Car) jtm.queryForObject(sql, new Object[]{id},
new BeanPropertyRowMapper(Car.class));
System.out.printf("%d ", car.getId());
System.out.printf("%s ", car.getName());
System.out.printf("%d ", car.getPrice());
}
}
在 JavaDBClientServer 中,我们连接到 Derby 网络服务器并从 CARS 表检索一辆汽车。
dataSource.setDriver(new org.apache.derby.jdbc.ClientDriver());
对于客户端/服务器应用程序,我们需要 ClientDriver。
dataSource.setUrl("jdbc:derby://:1527/testdb;user=USER12");
我们使用网络服务器的连接字符串。
在本教程中,我们学习了如何创建使用嵌入式和客户端/服务器模式 JavaDB 的 Java 应用程序。