Spring Boot神操作-多个数据源Service层封装

news/2024/7/3 2:17:32

点击上方“方志朋”,选择“设为星标”

回复”666“获取新整理的面试文章

作者:@pdai

pdai.tech/md/spring/springboot-data-multi.html

mysql, es, mongodb 三个数据源用配置文件方式连接,JPA只是正对dao做了封装,本文主要介绍如何对service层进行封装。@pdai

  • Spring Boot - 多个数据源Service层封装

  • 类关系图

  • 封装的一些配置

    • application.yml

    • pom.xml

  • 封装后使用

    • MySQL 动态数据访问

  • Mongo 动态数据访问

  • ElasticSearch 动态数据访问(单个index+type)

  • ElasticSearch 动态数据访问(多个index+type)

  • 源代码托管

类关系图

  • 对多个数据源连接获取数据进行统一封装

  • ES spring-data方式不支持多个Index和Type的查找功能,添加了DynamicESDao支持

  • 大大简化封装之后的调用, 调用方式如下

封装的一些配置

application.yml

banner:charset: UTF-8location: classpath:banner.txt
server:port: 5555contextPath: /session:timeout: 0
spring:application:name: 'spring-boot-datasource-demo'output:ansi:enabled: DETECTmessages:basename: i18n/messagesthymeleaf:cache: falseprofiles:active: dev# MySQL data source settingsdatasource:url: jdbc:mysql://localhost:3306/cdc_standalone?useSSL=falseusername: rootpassword: bfXa4Pt2lUUScy8jakXf# MySQL JPA settingsjpa:generate-ddl: trueshow-sql: trueproperties:hibernate:dialect: org.hibernate.dialect.MySQLDialectformat_sql: true# NoSQL data source settingsdata:# MongoDB 2.2+ settingsmongodb:uri: mongodb://standalone:fhY1tPt1lpUSbS7jwkTf@10.11.60.4:27017/standalone# ElasticSearch settingselasticsearch:cluster-name: es-logs-01cluster-nodes: 10.11.60.5:9300


pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>spring-boot-datasource-demo</groupId><artifactId>spring-boot-datasource-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-datasource-demo</name><description>spring-boot-datasource-demo</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.4.1.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><commons.lang.version>3.3.2</commons.lang.version><springfox.version>2.7.0</springfox.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${springfox.version}</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${springfox.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.15</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons.lang.version}</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.1</version></dependency><dependency><groupId>com.github.wenhao</groupId><artifactId>jpa-spec</artifactId><version>3.2.3</version></dependency></dependencies><build><sourceDirectory>src</sourceDirectory><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>

封装后使用

封装之后使用将非常简单,公共的Service行为将被封装处理

MySQL 动态数据访问

通过几行代码即可实现对MySQL的访问,同时支持动态的条件查询;

User

@Entity
@Table(name = "tb_user")
public class User extends BaseEntity {private static final long serialVersionUID = 1L;/*** 用户id*/@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id", nullable = false)private Integer id;private String userName;private String nickName;private String password;private Integer sex;private String telephone;private String email;private String address;private Integer deleteStatus;private Integer locked = 0;private String description;@JSONField(format = "yyyy-MM-dd HH:mm:ss")private Date createTime;@JSONField(format = "yyyy-MM-dd HH:mm:ss")private Date updateTime;@ManyToMany(cascade = { CascadeType.REFRESH }, fetch = FetchType.LAZY)@JoinTable(name = "tb_user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = {@JoinColumn(name = "role_id") })private java.util.Set<Role> roles;// getter & setter
}

Dao

@Repository
public interface IUserDao extends IBaseJpaDao<User, Integer>{
}

Service

public interface IUserService extends IBaseJpaService<User, Integer> {
}
@Service
public class UserServiceImpl extends BaseJpaServiceImpl<User, Integer> implements IUserService {@Autowiredprivate IUserDao userDao;@Overridepublic IBaseJpaDao<User, Integer> getBaseDao() {return this.userDao;}@Overridepublic void delete(Integer id) {User user = find(id);Assert.state(!"admin".equals(user.getUserName()), "超级管理员用户不能删除");super.delete(id);}
}

Controller

@RestController
@RequestMapping("/admin/user")
public class UserController {/*** user service*/@Autowiredprivate IUserService userService;/*** @param searchText* @param user* @param model* @return*/@GetMapping(value = "/list")public List<User> list(@RequestParam(value = "searchText", required = false, defaultValue="a") String searchText) {return userService.findAll(Specifications.<User>and().like("userName", "%" + searchText + "%").build());}
}

Mongo 动态数据访问

通过几行代码即可实现对Mongo的访问,同时支持动态的条件查询;

Entity

@Document(collection = "security_alert_rules")
public class EventRule extends BaseEntity {private static final long serialVersionUID = -2013673868028645757L;public static final int EVENT_STATUS_ENABLE = 0, EVENT_STATUS_DISABLE = 1;private String component;private String name;private String eventId;private String ciaLevel;private String remarks;private String script;private long threshold;private long timeWindow;private String parseEsResultKeys;private String nameCN;private String remarkCN;private String ruleType;private String redisEventKey;private int status = EVENT_STATUS_ENABLE;// getter & setter
}

Dao

@Repository
public interface IEventRuleDao extends IBaseMongoDao<EventRule, String> {
}

Service

public interface IEventRuleService extends IBaseMongoService<EventRule, String> {
}
@Service
public class EventRuleServiceImpl extends BaseMongoServiceImpl<EventRule, String> implements IEventRuleService {@AutowiredIEventRuleDao eventRuleDao;@Overridepublic IBaseMongoDao<EventRule, String> getBaseDao() {return eventRuleDao;}
}

Controller

@RestController
@RequestMapping("/admin/eventRule")
public class EventRuleController {/***/@Autowiredprivate IEventRuleService eventRuleService;/*** @param searchText* @param user* @param model* @return*/@GetMapping(value = "/list")public List<EventRule> list(@RequestParam(value = "searchText", required = false) String searchText) {EventRule param = new EventRule();param.setName(searchText);
//        Example<EventRule> rule = Example.<EventRule>of(param,
//                ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.exact()));Example<EventRule> rule = Example.<EventRule>of(param, ExampleMatcher.matching().withIgnoreCase("name","nameCN"));return eventRuleService.findAll(rule);}
}

ElasticSearch 动态数据访问(单个index+type)

通过几行代码即可实现对ElasticSearch的访问,同时支持动态的条件查询;适合数据类型比较固定,且index和type独立的,比如强类型映射的实体类;

Entity

@Document(indexName="syslog", type="logs")
public class SysLog extends BaseEntity {private static final long serialVersionUID = -4491916941883088972L;@Idprivate String _id;private Set<String> phyPorts = new LinkedHashSet<>();private Set<String> ports = new LinkedHashSet<>();private String sensor;private int vlan;private Set<String> ip = new LinkedHashSet<>();private Set<String> mac = new LinkedHashSet<>();private String description;private String type;private String vendor;private long timestamp;private String name;private String chassisId;// getter & setter
}

Dao

@Repository
public interface ISysLogDao extends IBaseESDao<SysLog, String> {
}

Service

public interface ILogService extends IBaseESService<SysLog, String> {
}
@Service
public class LogServiceImpl extends BaseESServiceImpl<SysLog, String> implements ILogService {@AutowiredISysLogDao sysLogDao;@Overridepublic IBaseESDao<SysLog, String> getBaseDao() {return sysLogDao;}
}

Controller

@RestController
@RequestMapping("/admin/log")
public class LogController {/*** user service*/@Autowiredprivate ILogService logService;/*** @param searchText* @param user* @param model* @return*/@GetMapping(value = "/list")public Page<SysLog> list(@RequestParam(value = "searchText", required = false) String searchText) {return logService.search(QueryBuilders.matchQuery("_all", searchText), new PageRequest(0, 100));}
}

ElasticSearch 动态数据访问(多个index+type)

通过几行代码即可实现对ElasticSearch的访问,同时支持动态的条件查询;适合数据类型不固定,且index和type有多个,这些index具备相同结构类型,比如syslog-EVERY-DATE(由于日志量大,将每天的日志单独存放在一个Index中);

Entity

@Document(indexName="syslog", type="logs")
public class SysLog extends BaseEntity {private static final long serialVersionUID = -4491916941883088972L;@Idprivate String _id;private Set<String> phyPorts = new LinkedHashSet<>();private Set<String> ports = new LinkedHashSet<>();private String sensor;private int vlan;private Set<String> ip = new LinkedHashSet<>();private Set<String> mac = new LinkedHashSet<>();private String description;private String type;private String vendor;private long timestamp;private String name;private String chassisId;// getter & setter
}

Dao

public interface IDymLogDao extends IDynamicEsDao<SysLog, String> {
}
@Repository
public class DymLogDaoImpl extends SimpleDynamicEsDaoImpl<SysLog, String> implements IDymLogDao {@Autowiredprotected ElasticsearchTemplate elasticsearchTemplate;@Overridepublic ElasticsearchOperations getElasticsearchOperations() {return elasticsearchTemplate;}
}

Service

public interface IDymLogService extends IDynamicESService<SysLog, String> {
}
@Service
public class DymLogServiceImpl extends DynamicESServiceImpl<SysLog, String> implements IDymLogService {@AutowiredIDymLogDao sysLogDao;@Overridepublic IDynamicEsDao<SysLog, String> getBaseDao() {return sysLogDao;}
}

Controller

@RestController
@RequestMapping("/admin/dymLog")
public class DymLogController {/*** logService*/@Autowiredprivate IDymLogService logService;/*** @param searchText* @param user* @param model* @return*/@GetMapping(value = "/list")public Page<SysLog> list(@RequestParam(value = "searchText", required = false, defaultValue = "Siemens") String searchText) {QueryBuilder queryBuilder = QueryBuilders.matchQuery("vendor", searchText);return logService.search(new NativeSearchQueryBuilder().withIndices("syslog-2018-12-17").withTypes("logs").withQuery(queryBuilder).build());}
}

源代码托管

https://github.com/realpdai/springboot-data-multidatasource-demo

热门内容:被面试官问懵B了,十亿级数据ES搜索怎么优化?
骚操作 | 不重启 JVM,替换掉已经加载的类,偷天换日?分布式锁用 Redis 还是 Zookeeper?写那么多年Java,还不知道啥是Java agent 的必须看一下!
科普|什么是负载均衡(Load balancing)最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡

http://lihuaxi.xjx100.cn/news/273154.html

相关文章

Matlab随笔之矩阵入门知识

直接输入法创建矩阵 – 矩阵的所有元素必须放在方括号“[ ]”内&#xff1b; – 矩阵列元素之间必须用逗号“&#xff0c;”或空格隔开&#xff0c;每行必须用“;”隔开 – 矩阵元素可以是任何不含未定义变量的表达式。可以是实数&#xff0c;或者是复数。 – 例a[1,2;3,4] 或 …

telnet 如何退出

ctrl]&#xff0c;然后再输入q就可以退出了。转载于:https://www.cnblogs.com/rethink/archive/2009/10/29/1591898.html

清华团队将Transformer用到3D点云分割上后,效果好极了

萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI当Transformer遇上3D点云&#xff0c;效果会怎么样&#xff1f;一个是当下最热门的模型&#xff08;NLP、图像领域表现都不错&#xff09;&#xff0c;另一个是自动驾驶领域、机器人抓取等领域的关键技术。来自清华计算机系的团队…

程序员必备网站之一:No Design

点击上方“方志朋”&#xff0c;选择“设为星标”回复”666“获取新整理的面试文章大家好&#xff0c;我是小 G。昨天在逛 Hacker News 的时候&#xff0c;我偶然发现个宝藏网站&#xff1a;No Design。地址&#xff1a;https://nodesign.dev网站上收集了许多十分便利的 UI 设计…

文件解析库doctotext源码分析

doctotext中没有make install选项&#xff0c;make后生成可执行文件在buile目录下面有.so动态库和头文件&#xff0c;需要的可以从这里面拷贝build/doctotext就是可执行程序。doctotext内置了两种检测文件类型方法&#xff1a;1、以后缀为依据检测文件类型2、以内容为依据检测文…

学习OpenCV,新手常会问我的十个问题 | 视觉入门

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达初次学习OpenCV新手经常问我的十个问题&#xff0c;有你问我过下面的问题之一吗&#xff1f;Q1按照视频做的&#xff0c;我怎么显示了不了图像或者视频解答&#xff1a;最…

AI芯片行业发展的来龙去脉

作者 | 清华大学微电子学研究所尹首一来源 | 《微纳电子与智能制造》期刊引言人 工 智 能( aritificial intelligence &#xff0c;AI )是 一 门融合了数学 、计算机科学 、统计学 、脑神经学和社会科学 的前沿综合性技术。它的目标是希望计算机可以像 人一样思考 &#xff0c;…

Python爬虫入门教程:超级简单的Python爬虫教程

这是一篇详细介绍 [Python]爬虫入门的教程&#xff0c;从实战出发&#xff0c;适合初学者。读者只需在阅读过程紧跟文章思路&#xff0c;理清相应的实现代码&#xff0c;30 分钟即可学会编写简单的 Python 爬虫。 这篇 Python 爬虫教程主要讲解以下 5 部分内容&#xff1a; 了…