Springboot使用策略模式实现数据插入不同类型数据库

news/2024/11/23 5:10:36/

需求:前端会传来一些图片数据,比如图片名称,图片长宽、大小等。后端需要根据实际情况存入mysql、oracle、clickhouse等不同的数据库。

上面的需求是一个非常好的使用策略模式实现的例子。

Mapper层

定义一个顶级接口,主要定义操作图片数据的方法,这里只写了一个图片插入的方法。

/*** 图片操作mapper**/
public interface ImageMapper {/*** 返回数据库类型** @return 数据库类型*/String databaseType();/*** 图片插入方法** @param image 图片对象*/void insertImageRecord(ImageBean image);
}

定义不同的操作数据库的mapper,下面定义一个操作clickhouse的mapper,注意定义对应的mapper.xml文件,这里不体现。

@Mapper
public interface ClickhouseImageMapper extends ImageMapper {/*** 返回数据库类型* @return 数据库类型*/@Overridedefault String databaseType(){return "clickhouse";}/*** 向clickhouse数据库的iot_image表中插入数据** @param image 图片信息*/@Overridevoid insertImageRecord(ImageBean image);
}

定义操作mysql的mapper,注意定义对应的mapper.xml文件,这里不体现。

@Mapper
public interface MySqlImageMapper extends ImageMapper {/*** 返回数据库类型* @return 数据库类型*/@Overridedefault String databaseType(){return "mysql";}/*** 向clickhouse数据库的iot_image表中插入数据** @param image 图片信息*/@Overridevoid insertImageRecord(ImageBean image);
}

Service层

定义context对象,可以理解为一个service对象。这个对象主要的作用是将实现了ImageMapper.class的实例对象存储到一个map中,当有人要调用这个对象的insertImageRecord方法时,从map中取出对应mapper执行数据库的插入操作。

@Service
public class ImageContext implements ApplicationContextAware {private final Map<String, ImageMapper> imageMapperMap = new ConcurrentHashMap<>();public void insertImageRecord(String dbType, ImageBean image) {final ImageMapper imageMapper = Optional.ofNullable(imageMapperMap.get(dbType)).orElseThrow(() -> new IllegalArgumentException("invalid database type: " + dbType));imageMapper.insertImageRecord(image);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {final Map<String, ImageMapper> map = applicationContext.getBeansOfType(ImageMapper.class);map.values().forEach(source -> imageMapperMap.put(source.databaseType(), source));}
}

在需要的地方调用上述方法。

@Service
public class GetAsyncAiResultService {/*** 历史库类型,默认clickhouse*/@Value("${image.history.database.type:clickhouse}")private String databaseType;//注入上下文对象@ResourceImageContext imageContext; /*** 组织图片信息插入到clickhouse中** @param imageName   图片名称* @param imageResult 图片结果*/void insertImageRecord(String imageName, JSONObject imageResult, JSONObject imageMetaData) {//省略处理逻辑//...//插入需要的数据库,数据库类型可以通过配置文件注入的方式,这里为了展示明显,写死了imageContext.insertImageRecord(databaseType, image); }
}

总结

使用策略模式以后代码非常符合开闭原则。比如现在需要将数据插入到Oracle中,那么上述提到的所有文件都不需要动,只需要再写一个OracleImageMapper继承ImageMapper,在需要将数据插入Oracle的时候,修改配置文件即可完成。

但是,使用策略模式需要提前设计好再开发,比如本文我们在ImageMapper文件中只定义了一个插入数据库的方法,后续开发过程中发现,不仅需要插入数据库还需要查询数据库,那么上述所有提到的文件都需要变更。


http://www.ppmy.cn/news/11224.html

相关文章

MySQL的行锁总结

文章目录前言一、行锁的介绍二、行锁的使用三、使用行锁所带来的问题四、死锁和死锁检测前言 上篇文章已经学习了MySQL的全局锁和表锁&#xff0c;今天这篇文章我们对行锁进行以下学习 一、行锁的介绍 行锁就是针对数据表中行记录的锁&#xff0c;比如事务A更新了一行&#x…

在线阅读网站|基于Springboot+Vue开发实现小说阅读网站

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

Java基础学习笔记(十二)—— 数据结构

数据结构1 栈2 队列3 数组4 链表5 二叉树5.1 二叉树5.2 二叉查找树5.3 平衡二叉树5.4 红黑树6 哈希表数据结构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下&#xff0c;精心选择的数据结构可以带来更高的运行或者存储效率。…

html实现酷炫的公司年会抽奖(附源码)

文章目录1.设计来源1.1 主界面1.2 抽奖效果1.2 中奖效果2.效果和源码配置2.1 动态效果2.2 员工信息配置2.3 奖品信息配置2.4 抽奖音效配置2.5 源代码源码下载作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/128640998 ht…

二、TTY子系统框架

个人主页&#xff1a;董哥聊技术我是董哥&#xff0c;嵌入式领域新星创作者创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01;文章目录1、TTY子系统框架分析2、TTY数据处理流程3、驱动的目录结构及核心文件4、TTY在Linux下的分布1、TTY子系…

shell脚本练习2023年下岗版

shell脚本练习 1.判断指定进程的运行情况 #!/bin/bash NAMEhttpd #这里输入进程的名称 NUM$(ps -ef |grep $NAME |grep -vc grep) if [ $NUM -eq 1 ]; thenecho "$NAME running." elseecho "$NAME is not running!" fi2.判断用户是否存在 #!/bin/bash r…

软件测试---概念篇

本文主要介绍软件测试相关的一些基础概念.主要内容包括 : 什么是需求 什么是bug 什么是测试用例 开发模型和测试模型 配置管理和软件测试 一 : 什么是需求 满足用户期望或正式规定文档&#xff08;合同、标准、规范&#xff09;所具有的条件和权能&#xff0c;包含用户需求和软…

verilog学习笔记- 10)按键控制 LED 灯实验

目录 简介&#xff1a; 实验任务&#xff1a; 硬件设计&#xff1a; 程序设计&#xff1a; 下载验证 &#xff1a; 总结与反思&#xff1a; 简介&#xff1a; 按键开关是一种电子开关&#xff0c;属于电子元器件类。我们的开发板上有两种按键开关&#xff1a;第一种是本实…