无需编程,基于PostgreSQL零代码生成CRUD增删改查RESTful API接口

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 采用抽象工厂设计模式,可以无缝切换不同类型的数据库,从crudapi 1.3.0版本开始,添加了对大象数据库PostgreSQL的支持。并且以学生对象为例,零代码实现了CRUD增删改查RESTful API,后续计划支持更多的数据库,比如Oracle,MSSQL Server,Mongodb等。

无需编程,基于PostgreSQL零代码生成CRUD增删改查RESTful API接口

回顾

在前面文章中,已经介绍了crudapi主要功能和使用方式,crudapi 1.2.0只支持MySQL数据库,为了支持更多数据库,对代码进行了重构,采用抽象工厂设计模式,可以无缝切换不同类型的数据库,从crudapi 1.3.0版本开始,添加了对大象数据库PostgreSQL的支持。

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

UI界面

通过学生对象为例,无需编程,基于PostgreSQL数据库,通过配置零代码实现CRUD增删改查RESTful API接口和管理UI。

table
创建学生表

table
编辑学生数据

customer
学生数据列表

customer
通过pgadmin查询postsql数据

实现原理

基类

CrudAbstractRepository为抽象类,主要功能为数据库表的crud增删改查操作。

public abstract class CrudAbstractRepository {
  public Long create(String tableName, Map<String, Object> map) {
    log.info("CrudAbstractRepository->create");
  }
}

CrudAbstractFactory为工厂类,用于创建CrudAbstractRepository。

public abstract class CrudAbstractFactory {
  public abstract CrudAbstractRepository getCrudRepository();

  public Long create(String tableName, Map<String, Object> map) {
    log.info("CrudAbstractFactory->create");
    CrudAbstractRepository repository = this.getCrudRepository();
    return repository.create(tableName, map);
  }
}

MySql子类

CrudAbstractRepository实现了通用数据库处理功能,MySql中如果有不同的处理方法,可以通过Override复写对应的方法,最终子类覆盖父类方法,比如MySqlCrudRepository重新实现了create添加数据功能。

@Component
public class MySqlCrudRepository extends CrudAbstractRepository {
  @Override
  public Long create(String tableName, Map<String, Object> map) {
    log.info("MySqlCrudRepository->create");

    return super.create(tableName, map);
  }
}
public class MySqlCrudFactory extends CrudAbstractFactory {
  @Autowired
  private MySqlCrudRepository mySqlCrudRepository;
  
  @Override
  public CrudAbstractRepository getCrudRepository() {
    return mySqlCrudRepository;
  }
}

PostSql子类

和MySql类似,PostSqlCrudRepository中如果有需要重写的部分,直接覆盖同名方法即可。

@Component
public class PostSqlCrudRepository extends CrudAbstractRepository {
  @Override
  public Long create(String tableName, Map<String, Object> map) {
    log.info("PostSqlCrudRepository->create");
    return super.create(tableName, obj);
  }
}
public class PostSqlCrudFactory extends CrudAbstractFactory {
  @Autowired
  private PostSqlCrudRepository postSqlCrudRepository;
  
  @Override
  public CrudAbstractRepository getCrudRepository() {
    return postSqlCrudRepository;
  }
}

CrudTemplate

通过CrudDatasourceProperties读取spring.datasource.driverClassName

@ConfigurationProperties(prefix = "spring.datasource")
@Component
public class CrudDatasourceProperties {
  private String driverClassName;

  public String getDriverClassName() {
    return driverClassName;
  }

  public void setDriverClassName(String driverClassName) {
    this.driverClassName = driverClassName;
  }
}

根据spring.datasource.driverClassName的值,通过反射动态创建MySqlCrudFactory或者PostSqlCrudFactory工厂对象,

@Configuration
public class CrudTemplateConfig {
  public static final String MYSQL_DRIVER_NAME = "com.mysql.cj.jdbc.Driver";
   
  Map<String, String> driverClassNameMap = new HashMap<String, String>() {
    private static final long serialVersionUID = 1L;
    {
      put("com.mysql.cj.jdbc.Driver", "cn.crudapi.core.repository.mysql.MySqlCrudFactory");
      put("org.postgresql.Driver", "cn.crudapi.core.repository.postsql.PostSqlCrudFactory");
    }
  };

  
  @Autowired
  private CrudDatasourceProperties crudDatasourceProperties;
  
  @Bean
  public CrudTemplate crudTemplate(CrudAbstractFactory factory) {
    CrudTemplate crudTemplate =  new CrudTemplate(factory);
    return crudTemplate;
  }
    
  @Bean
  public CrudAbstractFactory crudAbstractFactory() {
    CrudAbstractFactory crudAbstractFactory = null;
    String driverClassName = crudDatasourceProperties.getDriverClassName();
    log.info("CrudTemplateConfig->driverClassName: " + driverClassName);
    
    try {
      String factoryClassName = driverClassNameMap.get(driverClassName);
      if (factoryClassName == null) {
        factoryClassName = driverClassNameMap.get(MYSQL_DRIVER_NAME);
      }
      log.info("CrudTemplateConfig->factoryClassName: " + factoryClassName);
      
      Class<?> cls = Class.forName(factoryClassName);
      Object obj = cls.newInstance();
      
      crudAbstractFactory = (CrudAbstractFactory)obj;
    } catch (Exception e) {
      e.printStackTrace();
    }
    
    return crudAbstractFactory;
  }
}

类似RestTemplate,CrudTemplate最终实现了crud增删改查功能

public class CrudTemplate {
  @Nullable
  private volatile CrudAbstractFactory crudFactory;

  public CrudTemplate() {
    super();
    log.info("CrudTemplate->Constructor");
  }
  
  public CrudTemplate(CrudAbstractFactory crudFactory) {
    super();
    log.info("CrudTemplate->Constructor crudFactory");
    this.crudFactory = crudFactory;
  }
  
  public Long create(String tableName, Map<String, Object> map) {
    log.info("CrudTemplate->create");
    return crudFactory.create(tableName, map);
  }
}

application.properties

需要根据需要配置数据库连接驱动,无需重新发布,就可以切换不同的数据库。

#mysql
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/crudapi
spring.datasource.username=
spring.datasource.password=

#postgresql
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/crudapi
spring.datasource.username=
spring.datasource.password=

小结

本文主要介绍了crudapi支持多数据库实现原理,并且以学生对象为例,零代码实现了CRUD增删改查RESTful API,后续计划支持更多的数据库,比如Oracle,MSSQL Server,Mongodb等。

实现方式 代码量 时间 稳定性
传统开发 1000行左右 2天/人 5个bug左右
crudapi系统 0行 1分钟 基本为0

综上所述,利用crudapi系统可以极大的提高工作效率和节约成本,让数据处理变得更简单!

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
安全 Java API
告别繁琐编码,拥抱Java 8新特性:Stream API与Optional类助你高效编程,成就卓越开发者!
【8月更文挑战第29天】Java 8为开发者引入了多项新特性,其中Stream API和Optional类尤其值得关注。Stream API对集合操作进行了高级抽象,支持声明式的数据处理,避免了显式循环代码的编写;而Optional类则作为非空值的容器,有效减少了空指针异常的风险。通过几个实战示例,我们展示了如何利用Stream API进行过滤与转换操作,以及如何借助Optional类安全地处理可能为null的数据,从而使代码更加简洁和健壮。
107 0
|
1月前
|
分布式计算 Java 大数据
大数据-147 Apache Kudu 常用 Java API 增删改查
大数据-147 Apache Kudu 常用 Java API 增删改查
27 1
|
2月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
1月前
|
存储 数据库连接 API
构建RESTful API:使用FastAPI实现高效的增删改查操作
构建RESTful API:使用FastAPI实现高效的增删改查操作
48 0
|
1月前
|
IDE API 定位技术
Python--API编程:IP地址翻译成实际的物理地址
Python--API编程:IP地址翻译成实际的物理地址
|
3月前
|
JavaScript API 开发者
RESTful API 设计的传奇征程:突破常规,拥抱最佳实践,铸就编程巅峰!
【8月更文挑战第7天】希望通过以上的探讨,能让您对 RESTful API 设计有更深入的理解和认识。
53 5
|
3月前
|
JSON API 数据库
神秘编程力量来袭!Rails 究竟隐藏着怎样的魔力,能构建出强大的 RESTful API?快来一探究竟!
【8月更文挑战第31天】《构建 RESTful API:使用 Rails 进行服务端开发》介绍了如何利用 Ruby on Rails 框架高效构建可扩展的 RESTful API。Rails 采用“约定优于配置”,简化开发流程,通过示例展示了路由定义、控制器设计及模型层交互等内容,帮助开发者快速搭建稳定可靠的服务端。无论小型项目还是大型应用,Rails 均能提供强大支持,提升开发效率。
28 0
|
3月前
|
开发框架 前端开发 API
使用代码生成工具快速开发应用-结合后端Web API提供接口和前端页面快速生成,实现通用的业务编码规则管理
使用代码生成工具快速开发应用-结合后端Web API提供接口和前端页面快速生成,实现通用的业务编码规则管理
|
6天前
|
SQL 缓存 测试技术
构建高性能RESTful API:最佳实践与避坑指南###
—— 本文深入探讨了构建高性能RESTful API的关键技术要点,从设计原则、状态码使用、版本控制到安全性考虑,旨在为开发者提供一套全面的最佳实践框架。通过避免常见的设计陷阱,本文将指导你如何优化API性能,提升用户体验,确保系统的稳定性和可扩展性。 ###
39 12
|
3天前
|
JSON JavaScript API
深入浅出Node.js:从零开始构建RESTful API
【10月更文挑战第39天】 在数字化时代的浪潮中,API(应用程序编程接口)已成为连接不同软件应用的桥梁。本文将带领读者从零基础出发,逐步深入Node.js的世界,最终实现一个功能完备的RESTful API。通过实践,我们将探索如何利用Node.js的异步特性和强大的生态系统来构建高效、可扩展的服务。准备好迎接代码和概念的碰撞,一起解锁后端开发的新篇章。