基于抽象工廠模式支持多數(shù)據(jù)源MySQL和PostgreSQL
在前面文章中,已經(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。

創(chuàng)建學(xué)生表
?
編輯學(xué)生數(shù)據(jù)
?
學(xué)生數(shù)據(jù)列表
?通過pgadmin查詢postsql數(shù)據(jù)
實(shí)現(xiàn)原理
基類
CrudAbstractRepository為抽象類,主要功能為數(shù)據(jù)庫表的crud增刪改查操作。
public abstract class CrudAbstractRepository {public Long create(String tableName, Mapmap) {log.info("CrudAbstractRepository->create");}}CrudAbstractFactory為工廠類,用于創(chuàng)建CrudAbstractRepository。public abstract class CrudAbstractFactory {public abstract CrudAbstractRepository getCrudRepository();public Long create(String tableName, Mapmap) {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ù)功能。
public class MySqlCrudRepository extends CrudAbstractRepository {public Long create(String tableName, Mapmap) {log.info("MySqlCrudRepository->create");return super.create(tableName, map);}}public class MySqlCrudFactory extends CrudAbstractFactory {private MySqlCrudRepository mySqlCrudRepository;public CrudAbstractRepository getCrudRepository() {return mySqlCrudRepository;}}
PostSql子類
和MySql類似,PostSqlCrudRepository中如果有需要重寫的部分,直接覆蓋同名方法即可。
public class PostSqlCrudRepository extends CrudAbstractRepository {public Long create(String tableName, Mapmap) {log.info("PostSqlCrudRepository->create");return super.create(tableName, obj);}}public class PostSqlCrudFactory extends CrudAbstractFactory {private PostSqlCrudRepository postSqlCrudRepository;public CrudAbstractRepository getCrudRepository() {return postSqlCrudRepository;}}
CrudTemplate
通過CrudDatasourceProperties讀取spring.datasource.driverClassName
(prefix = "spring.datasource")public class CrudDatasourceProperties {private String driverClassName;public String getDriverClassName() {return driverClassName;}public void setDriverClassName(String driverClassName) {this.driverClassName = driverClassName;}}
根據(jù)spring.datasource.driverClassName的值,通過反射動(dòng)態(tài)創(chuàng)建MySqlCrudFactory或者PostSqlCrudFactory工廠對象,
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");}};private CrudDatasourceProperties crudDatasourceProperties;public CrudTemplate crudTemplate(CrudAbstractFactory factory) {CrudTemplate crudTemplate = new CrudTemplate(factory);return crudTemplate;}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 {@Nullableprivate 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, Mapmap) {log.info("CrudTemplate->create");return crudFactory.create(tableName, map);}}
application.properties
需要根據(jù)需要配置數(shù)據(jù)庫連接驅(qū)動(dòng),無需重新發(fā)布,就可以切換不同的數(shù)據(jù)庫。
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/crudapispring.datasource.username=spring.datasource.password=spring.datasource.driverClassName=org.postgresql.Driverspring.datasource.url=jdbc:postgresql://localhost:5432/crudapispring.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ù)處理變得更簡單!
crudapi簡介
crudapi是crud+api組合,表示增刪改查接口,是一款零代碼可配置的產(chǎn)品。使用crudapi可以告別枯燥無味的增刪改查代碼,讓您更加專注業(yè)務(wù),節(jié)約大量成本,從而提高工作效率。crudapi的目標(biāo)是讓處理數(shù)據(jù)變得更簡單,所有人都可以免費(fèi)使用!無需編程,通過配置自動(dòng)生成crud增刪改查RESTful API,提供后臺UI管理業(yè)務(wù)數(shù)據(jù)。基于主流的開源框架,擁有自主知識產(chǎn)權(quán),支持二次開發(fā)。
demo演示
crudapi屬于產(chǎn)品級的零代碼平臺,不同于自動(dòng)代碼生成器,不需要生成Controller、Service、Repository、Entity等業(yè)務(wù)代碼,程序運(yùn)行起來就可以使用,真正0代碼,可以覆蓋基本的和業(yè)務(wù)無關(guān)的CRUD RESTful API。
官網(wǎng)地址:https://crudapi.cn
測試地址:https://demo.crudapi.cn/crudapi/login
關(guān)注公眾號回復(fù):crudapi,即可獲得源碼地址!
