动态Java 代码生成技术
ObjectiveSQL 基于JSR 269 规范,依靠数据模型的定义,动态生成 queryAll,countAll,update 等一系列简单SQL 的逻辑代码,并基于IntelliJ IDEA 插件提供动态代码提示,可以有效提升应用系统的开发效率。
// Defining a Member Class who will have capability of API of SQL
@DomainModel
public class Member {
private String no;
private String name;
private Integer gender;
@Relation(relationType = RelationType.HAS_MANY)
private List<Order> orders;
}
// Counting number of all members
long memberCount = Member.countAll();
// Querying all members
List<Member> members = Member.queryAll();
// Creating a Member instance with HashMap who contains attributes of Member
Member.create(rawMemberHashMap);
// Below, all members will have relation object 'order' instance
// who is calcuated by ObjectiveSQL
Member member = Member.queryByPrimaryKey(1, Member.HAS_MANY_ORDERS);
List<Member> members = Member.queryAll(Member.HAS_MANY_ORDERS);
关联查询
关联查询是应用系统中频繁使用的基础特性,ObjectiveSQL 为了简化应用系统的开发,同时也为了避免N+1 问题的出现,基于HAS_MANY、HAS_ONE、BELONGS_TO 三种类型的关系定义,自动生成相应的逻辑处理代码,降低应用系统开发的复杂度。
过程化SQL 编程
ObjectiveSQL 结合代码的自动生成和多种数据库函数的抽象和封装,使得SQL 编程与Java 编程可以有机结合,可以按过程式编程的方式进行SQL 编程,不再出现各种字符串的拼接,也不需要使用各种模板语言,有效降低SQL 语句的语法和逻辑错误,并可以实现SQL 语句的单元测试。
// Calculating the member related order data
Member.Table member = Member.asTable();
Order.Table order = Order.asTable();
Select select = new Select();
select.from(order, member)
.where(order.memberId.eq(member.id));
select.project(member.no,
member.name,
member.mobile,
countDistinct(order.no).as("order_count"),
sum(order.quantity).as("total_quantity"),
sum(order.amount).as("total_amount"),
min(order.salesAt).as("first_shopping"),
max(order.salesAt).as("last_shopping"));
select.groupBy(member.no, member.name, member.mobile);
return select.execute(DatabaseType.MySQL, Member.class);
-- Calculate average amount of per product
SELECT SUM(order.amount) / SUM(order.quantity) * 100
FROM orders AS order GROUP BY order.produc_id
Order.Table orderTable = Order.asTable();
Select select = new Select();
select.project(sum(orderTable.amount) / sum(orderTable.quantity) * $(100) )
.from(orderTable)
.groupBy(orderTable.productId);
提示:上述Java 代码生成的SQL 与手工编写的SQL 一致,可以看出Java 代码量与SQL 的代码量差别不大,只是多了一些定义,可读性差别也比较接近。完整代码参见:Product.java
等价表达式
将SQL 转义为Java 编程中,最困难的就是就表达式的转义,通常都是以Java 中的函数对表达式进行封装,这样反而会使的Java 中的SQL 编程变得复杂和可理解性差。复杂SQL 编程中,在Project 时经常会使用到各种统计函数和逻辑表达式,例如:SUM、IFNULL、CASE WHEN等,还会使用到各种运算符的使用,例如:SUM(order.amount) / SUM(order.quantity) 等。
上述表达式通常都是以字符串的形式存在于Java,而ObjectiveSQL 通过对Java Compiler 的调整,实现了SQL 与Java 的表达式的一致表现形式。