本文是我们学院课程的一部分,标题为jOOQ –类型安全的数据库查询 。
在SQL和特定关系数据库很重要的Java应用程序中,jOOQ是一个不错的选择。 当JPA / Hibernate抽象过多,JDBC过多时,这是一种替代方法。 它显示了一种现代的领域特定语言如何可以极大地提高开发人员的生产率,从而将SQL内部化为Java。
在本课程中,我们将看到如何使用jOOQ有效地查询数据库。 在这里查看 !
1.课程项目的设置
在本部分中,我们将学习如何正确设置课程项目,您可以从这里获取: https : //github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-academy 。
为了直接从GitHub运行本课程的示例,您需要安装:
- Git( http://git-scm.com )
- Maven( http://maven.apache.org )
- Java 8( http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html )
如果您已经安装了自己喜欢的IDE(例如Eclipse,IntelliJ或NetBeans),则可以轻松地直接从GitHub导入jOOQ Academy Maven项目。 安装数据库和运行jOOQ代码生成器所需要做的就是调用:
mvn clean install
2.示例H2数据库
整个课程将针对简单的H2示例数据库运行查询,该数据库的源代码可从此处获取: https : //github.com/jOOQ/jOOQ/blob/master/jOOQ-examples/jOOQ-academy/src/main/资源/db-h2.sql
您无需手动安装任何东西。 使用Maven构建jOOQ Academy Maven项目时,将自动安装示例数据库。 作为参考,我们将在此处复制数据库:
DROP TABLE IF EXISTS book_to_book_store
;
DROP TABLE IF EXISTS book_store
;
DROP TABLE IF EXISTS book
;
DROP TABLE IF EXISTS author
;
DROP SEQUENCE IF EXISTS s_author_id
;
CREATE SEQUENCE s_author_id START WITH 1
;
CREATE TABLE author (
id INT NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50) NOT NULL,
date_of_birth DATE,
CONSTRAINT pk_t_author PRIMARY KEY (ID)
)
;
CREATE TABLE book (
id INT NOT NULL,
author_id INT NOT NULL,
title VARCHAR(400) NOT NULL,
published_in INT,
rec_timestamp TIMESTAMP,
CONSTRAINT pk_t_book PRIMARY KEY (id),
CONSTRAINT fk_t_book_author_id FOREIGN KEY (author_id) REFERENCES author(id),
)
;
CREATE TABLE book_store (
name VARCHAR(400) NOT NULL,
CONSTRAINT uk_t_book_store_name PRIMARY KEY(name)
)
;
CREATE TABLE book_to_book_store (
book_store_name VARCHAR(400) NOT NULL,
book_id INTEGER NOT NULL,
stock INTEGER,
CONSTRAINT pk_b2bs PRIMARY KEY(book_store_name, book_id),
CONSTRAINT fk_b2bs_bs_name FOREIGN KEY (book_store_name)
REFERENCES book_store (name)
ON DELETE CASCADE,
CONSTRAINT fk_b2bs_b_id FOREIGN KEY (book_id)
REFERENCES book (id)
ON DELETE CASCADE
)
;
INSERT INTO author VALUES (next value for s_author_id, 'George', 'Orwell', '1903-06-25')
;
INSERT INTO author VALUES (next value for s_author_id, 'Paulo', 'Coelho', '1947-08-24')
;
INSERT INTO book VALUES (1, 1, '1984' , 1948, null)
;
INSERT INTO book VALUES (2, 1, 'Animal Farm' , 1945, null)
;
INSERT INTO book VALUES (3, 2, 'O Alquimista', 1988, null)
;
INSERT INTO book VALUES (4, 2, 'Brida' , 1990, null)
;
INSERT INTO book_store (name) VALUES
('Amazon'),
('Barnes and Noble'),
('Payot')
;
INSERT INTO book_to_book_store VALUES
('Amazon', 1, 10),
('Amazon', 2, 10),
('Amazon', 3, 10),
('Barnes and Noble', 1, 1),
('Barnes and Noble', 3, 2),
('Payot', 3, 1)
;
DROP ALIAS IF EXISTS count_books
;
CREATE OR REPLACE ALIAS count_books AS $$
int countBooks(Connection c, int authorID) throws SQLException {
try (PreparedStatement s = c.prepareStatement("SELECT COUNT(*) FROM book WHERE author_id = ?")) {
s.setInt(1, authorID);
try (ResultSet rs = s.executeQuery()) {
rs.next();
return rs.getInt(1);
}
}
}
$$
;
如您所见,我们正在使用非常常见的SQL功能:
- 具有主键和外键的表
- ID生成的顺序
- 储存程序
3.代码生成器
jOOQ从您的数据库元信息生成Java代码。 这意味着以上架构将为上述每个表生成类,如下所示:
持有对所有表的静态引用的类
public class Tables {
public static final Author AUTHOR = // [...]
public static final Book BOOK = // [...]
public static final BookStore BOOK_STORE = // [...]
public static final BookToBookStore BOOK_TO_BOOK_STORE = // [...]
}
每个表都有对其所有列的引用
public class Author extends TableImpl<AuthorRecord> {
public final TableField<AuthorRecord, Integer> ID = // [...]
public final TableField<AuthorRecord, String> FIRST_NAME = // [...]
public final TableField<AuthorRecord, String> LAST_NAME = // [...]
public final TableField<AuthorRecord, Timestamp> DATE_OF_BIRTH = // [...]
}
这些是最重要的人工制品。 稍后,我们将研究生成的记录,POJO,DAO以及序列和存储过程的生成对象。
翻译自: https://www.javacodegeeks.com/2015/09/getting-started-with-jooq-h2-and-maven.html