無需編程,基于PostgreSQL零代碼生成CRUD增刪改查RESTful API接口

無需編程,基于PostgreSQL零代碼生成CRUD增刪改查RESTful API接口

回顧

在前面文章中,已經(jīng)介紹了crudapi主要功能和使用方式,crudapi 1.2.0只支持MySQL數(shù)據(jù)庫,為了支持更多數(shù)據(jù)庫,對代碼進(jìn)行了重構(gòu),采用抽象工廠設(shè)計(jì)模式,可以無縫切換不同類型的數(shù)據(jù)庫,從crudapi 1.3.0版本開始,添加了對大象數(shù)據(jù)庫PostgreSQL的支持。

抽象工廠模式

抽象工廠模式(Abstract Factory Pattern)是圍繞一個(gè)超級工廠創(chuàng)建其他工廠。該超級工廠又稱為其他工廠的工廠。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。在抽象工廠模式中,接口是負(fù)責(zé)創(chuàng)建一個(gè)相關(guān)對象的工廠,不需要顯式指定它們的類。每個(gè)生成的工廠都能按照工廠模式提供對象。

UI界面

通過學(xué)生對象為例,無需編程,基于PostgreSQL數(shù)據(jù)庫,通過配置零代碼實(shí)現(xiàn)CRUD增刪改查RESTful API接口和管理UI。

table

創(chuàng)建學(xué)生表

table

編輯學(xué)生數(shù)據(jù)

customer

學(xué)生數(shù)據(jù)列表

customer

通過pgadmin查詢postsql數(shù)據(jù)

實(shí)現(xiàn)原理

基類

CrudAbstractRepository為抽象類,主要功能為數(shù)據(jù)庫表的crud增刪改查操作。

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

CrudAbstractFactory為工廠類,用于創(chuàng)建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實(shí)現(xiàn)了通用數(shù)據(jù)庫處理功能,MySql中如果有不同的處理方法,可以通過Override復(fù)寫對應(yīng)的方法,最終子類覆蓋父類方法,比如MySqlCrudRepository重新實(shí)現(xiàn)了create添加數(shù)據(jù)功能。

@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;
  }
}

根據(jù)spring.datasource.driverClassName的值,通過反射動態(tài)創(chuàng)建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最終實(shí)現(xiàn)了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

需要根據(jù)需要配置數(shù)據(jù)庫連接驅(qū)動,無需重新發(fā)布,就可以切換不同的數(shù)據(jù)庫。

#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=

小結(jié)

本文主要介紹了crudapi支持多數(shù)據(jù)庫實(shí)現(xiàn)原理,并且以學(xué)生對象為例,零代碼實(shí)現(xiàn)了CRUD增刪改查RESTful API,后續(xù)計(jì)劃支持更多的數(shù)據(jù)庫,比如Oracle,MSSQL Server,Mongodb等。

實(shí)現(xiàn)方式 代碼量 時(shí)間 穩(wěn)定性
傳統(tǒng)開發(fā) 1000行左右 2天/人 5個(gè)bug左右
crudapi系統(tǒng) 0行 1分鐘 基本為0

綜上所述,利用crudapi系統(tǒng)可以極大的提高工作效率和節(jié)約成本,讓數(shù)據(jù)處理變得更簡單!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容