ObjectiveSQL框架让你不要再写复杂SQL

朋友开发的开源项目,喜欢的话去https://github.com/braisdom/ObjectiveSql 点个star

项目介绍

ObjectiveSQL 是一个Java ORM 框架,以ActiveRecord 模式基础,结合JSR 269 API 实现数据库访问Java 代码的动态生成,从而提高生产效率,主要特性包括:

  • 动态生成数据模型访问数据库的 JAVA API 代码,其中包括数据库访问的SELECT、INSERT、UPDATE 和DELETE
  • 根据Relation 注解的定义,在查询时自动填充关联对象,同时也避免N+1 查询问题
  • 提供多种方式构造数据模型,主要以Java Bean PropertyDescriptor 形式,也支持Map 形式绑定属性
  • 多数据源支持,只需在DomainModel 中指定数据模型所属的数据源
  • 事务支持,只需要在模型方法中指定Transaction 注解,系统自动生成数据为事务代码
  • 灵活扩展,系统针对业务领域中可能遇见的扩展点提供Interface 和注入接口,主要包括:JDBC 执行器、数据类型转换、SQL 查询、SQL 持久化等
  • 面向对象SQL(开发中,预计在1.4.0 版本发布)

img

  • ObjectiveSQL 集成了Apache Dbutils 实现基础ORM 特性,包括:SQL 的执行、数据模型与Table Row 之间的相互转换、以及基础的JDBC 特性。Apache Dbutils 只提供了能用的ORM 特性,缺少关联关系,并且与应用系统之间的结合相对不够友好,本质上是一个高度抽象、且灵活的技术框架。
  • Transition 层,也是一般ORM 框架中必备的一个特性,主要用于数据模型与数据库之间的数据转换,它有两个扩展方法:rising 用于将数据库的数据转换为Java 类型的数据,sinking 用于将Java 类型的数据转换为数据库类型的数据,由于不同数据库类型也可能出现不一样的转换方法,DateTime 是很多数据库的转换方式都不一样,所以Transition 也是高度被扩展的接口,Transition 会作为一个扩展点注入Apache Dbutils。
  • API 层,是以面向对象的方式封装高度抽象的数据库访问API,主要为DomainModel 生成的具体API 服务,应用系统也可以结合 Query 和Persistence 两个接口封装出符合业务特性的API。
  • DomainModel 是对业务系统逻辑的抽象和封装,而业务逻辑中会涉及大量数据库的读写,在ObjectiveSQL 框架下,不再需要显式的编写相应的数据读写逻辑,只关注真实的业务逻辑即可。

快速开始

本文档主要介绍:如何通过ObjectiveSQL 结合 SpringBoot 实现MySQL 数据库的增、删、改和查,以及关联关系的查询。通过示例,你可以看出ObjectiveSQL 如何通过极少的编码,就可以实现数据库访问。项目完整代码请参考:SpringBootExample

1 ObjectiveSQL 依赖安装(Maven & Gradle)

<dependencies>
    <dependency>
        <groupId>com.github.braisdom</groupId>
        <artifactId>objective-sql</artifactId>
        <version>1.3.6</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>8</source>
                <target>8</target>
                <encoding>UTF-8</encoding>
                <compilerArgs>
                    <arg>-Xplugin:Manifold</arg>
                </compilerArgs>
                <annotationProcessorPaths>
                    <path>
                        <groupId>systems.manifold</groupId>
                        <artifactId>manifold-ext</artifactId>
                        <version>2020.1.27</version>
                    </path>
                    <path>
                        <groupId>com.github.braisdom</groupId>
                        <artifactId>objective-sql</artifactId>
                        <version>1.3.6</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>
compile group: 'com.github.braisdom', name: 'objective-sql', version: '1.3.6'

点击“Maven 仓库”可以找到最新版本和其它的依赖方式配置,目前最新版本为: 1.3.6

2 IntelliJ 插件安装

  • MAC 操作系统
    • Preferences >> Plugins >> Marketplace >> 搜索 “ObjectiveSql” >> 安装
  • Windows 操作系统
    • File >> Settings >> Plugins >> Marketplace >> 搜索 “ObjectiveSql“>> 安装

3 Annotation Processor 设置

Settings/Preferences >> Annotation Processor >> 选择项目后,勾选 “Enable annotation processing”

4 数据库脚本

CREATE DATABASE IF NOT EXISTS `objective_sql` CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE IF NOT EXISTS `objective_sql`.`members`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `no` VARCHAR(100),
   `name` VARCHAR(100),
   `gender` INT(2),
   `mobile` VARCHAR(11),
   `other_info` VARCHAR(512),
   `registered_at` DATETIME,
   `updated_at` DATETIME,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

5 定义领域模型

@DomainModel
public class Member {
    private String no;
    private String name;
    private Integer gender;
    private String mobile;
}

所谓领域模型,基实就是Java 中是一个定义基础数据结构的 Class,而在数据库领域是一张表的结构定义(也称为Schema),一行数据对应Class 的一个实例。以面向对象设计理论的基础去理解,对数据库表的查询、更新、修改和删除应当以静态行为的形式体现在该模型中。

6 使用实践

结合SpringBoot 我们提供了一份完整的使用示例,覆盖了常用场景,完整代码请参考:MembersController.java

6.1 创建会员

@PostMapping("/members")
public ResponseObject create(@RequestBody RequestObject rawMember) throws SQLException {
    Member dirtyMember = Member.newInstanceFrom(rawMember, false);
    Member member = Member.create(dirtyMember, true);
    return ResponseObject.createSuccessResponse(member);
}

6.2 根据会员号查询单个会员

// Querying a member by member no
@GetMapping("/members/{no}")
public ResponseObject getMember(@PathVariable("no") String memberNo) throws SQLException {
    Member member = Member.queryByNo(memberNo);
    return ResponseObject.createSuccessResponse(member);
}

6.3 查询所有会员

// Querying all members
@GetMapping("/members")
public ResponseObject getMembers() throws SQLException {
    List<Member> members = Member.queryAll();
    return ResponseObject.createSuccessResponse(members);
}

6.4 根据会员号更新会员

// Updating a member with member no
@PutMapping("/members/{no}")
public ResponseObject updateMember(@PathVariable("no") String memberNo,
                                   @RequestBody RequestObject rawMember) throws SQLException {
    Member member = Member.queryByNo(memberNo);
    Member.update(member.getId(), Member.newInstanceFrom(rawMember), true);
    return ResponseObject.createSuccessResponse();
}

6.5 根据会员号删除会员

// Deleting a member with member no
@DeleteMapping("/members/{no}")
public ResponseObject deleteMember(@PathVariable("no") String memberNo) throws SQLException {
    int deleteCount = Member.destroy("member_no = ?", memberNo);
    return ResponseObject.createSuccessResponse(deleteCount);
}

7 小结

通过上述示例,应用系统可以以极简单代码,实现对数据库的存储和查询,从而将设计和编码的重心转移到应用系统本身,ObjectiveSql 提供了丰富的API和扩展接口,最大限度的满足应用系统的实际需求,当前只展示示例仅仅是冰山一角,详细内容请看后续。

IntelliJ IDEA 插件安装

由于数据库访问Java API 是由ObjectiveSQL 在编译期间生成,在IntelliJ IDEA 在编码过程中无法识别生成的方法或属性,ObjectiveSQL 提供了IntelliJ IDEA 插件,用于解决编码过程中的编译错误和动态代码提示。

1 应用市场安装

img

进入IntelliJ IDEA 的 Preference 对话框后,以“ObjectiveSQL” 关键字进行搜索,并点击安装

2 本地安装最新版本

由于IntelliJ IDEA 插件仓库审核需要一定时间,针对一些Bug 的紧急修复会临时发布最新版本供用户下载,可以按下列方式,从本地安装ObjectiveSQL 插件。

object-sql-intellij-1.2.7下载

img

下载完成后,进行Preference -> Plugins 选项中点击 Install Plugin From Disk… 菜单,选中下载的 .zip 文件,即可完成安装

名称映射规则

Class 名称与Table 名称、字段名称与Column 名称的缺省映射规则是一个开发团队成熟的重要标志,团队成员遵循统一的规则降低了沟通成本,并且也减少了开发过程中出错的机率,与敏捷开发中的隐喻也是有着异曲同工的作用。

Java 的开发体系中一直强调“扩展性”,认为技术型框架中存在的强制遵循的规则,阻碍了系统的可扩展性,却不知,固化一些已经约定俗成的规则,是系统开发中效率的关键,就像人类社会发展了数千年,除了法律的约束外,更多的是民间存在的习俗,有了这些被人所认可的习俗,人与人之间才能够形成有效的生产力。

规则会迭代和变化,这并不意味着规则不重要,很多人会挑战规则的内容和形成过程,但挑战的结果就是:又形成了一套新的规则。

1 类与字段命名规则

缺省情况下,类名遵循Java 的规范,以驼峰的单数形式命名,而表名则以下划线 “” 分隔单词的复数形式命名,Java 字段以驼峰形式命名,而数据库表Column名称以下划线“” 分隔单词,具体示例如下:

Java 类名 数据库表名
Article articles
LineItem line_items
Deer deers
Mouse mice
Person people
Java 字段名称 数据库 Column 名称
name name
restisterAt restister_at

2 关联对象名称约束

img

ObjectiveSQL 定义的关联关系主要包括三种:HAS_ONE,HAS_MANY,和BELONGS_TO,其中HAS_MANY 为复杂形式,其它均为单数形式,其它命名规则如下:

  • HAS_MANY 时,主表中用于承载关联对象的字段以驼峰形式的复数命名
  • HAS_ONE 时,主表中用于承载关联对象的字段以驼峰形式的单数命名
  • BELONGS_TO 时,从表中用于承载关联对象的字段以驼峰形式的单数命名
  • 其它用于映射数据库字段的命名规则遵循普通字段命名规则
posted @ 2020-11-18 17:33  天宇轩-王  阅读(1312)  评论(0编辑  收藏  举报