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

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

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

  • 类关系图

  • 封装的一些配置

    • application.yml

    • pom.xml

  • 封装后使用

    • MySQL 动态数据访问

  • Mongo 动态数据访问

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

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

  • 源代码托管

类关系图

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

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

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

封装的一些配置

application.yml

 
  1. banner:

  2. charset: UTF-8

  3. location: classpath:banner.txt

  4. server:

  5. port: 5555

  6. contextPath: /

  7. session:

  8. timeout: 0

  9. spring:

  10. application:

  11. name: 'spring-boot-datasource-demo'

  12. output:

  13. ansi:

  14. enabled: DETECT

  15. messages:

  16. basename: i18n/messages

  17. thymeleaf:

  18. cache: false

  19. profiles:

  20. active: dev

  21. # MySQL data source settings

  22. datasource:

  23. url: jdbc:mysql://localhost:3306/cdc_standalone?useSSL=false

  24. username: root

  25. password: bfXa4Pt2lUUScy8jakXf

  26. # MySQL JPA settings

  27. jpa:

  28. generate-ddl: true

  29. show-sql: true

  30. properties:

  31. hibernate:

  32. dialect: org.hibernate.dialect.MySQLDialect

  33. format_sql: true

  34. # NoSQL data source settings

  35. data:

  36. # MongoDB 2.2+ settings

  37. mongodb:

  38. uri: mongodb://standalone:fhY1tPt1lpUSbS7jwkTf@10.11.60.4:27017/standalone

  39. # ElasticSearch settings

  40. elasticsearch:

  41. cluster-name: es-logs-01

  42. cluster-nodes: 10.11.60.5:9300

pom.xml

 
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  3. <modelVersion>4.0.0</modelVersion>

  4. <groupId>spring-boot-datasource-demo</groupId>

  5. <artifactId>spring-boot-datasource-demo</artifactId>

  6. <version>0.0.1-SNAPSHOT</version>

  7. <name>spring-boot-datasource-demo</name>

  8. <description>spring-boot-datasource-demo</description>

  9. <parent>

  10. <groupId>org.springframework.boot</groupId>

  11. <artifactId>spring-boot-starter-parent</artifactId>

  12. <version>1.4.1.RELEASE</version>

  13. </parent>

  14. <properties>

  15. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

  16. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

  17. <java.version>1.8</java.version>

  18. <commons.lang.version>3.3.2</commons.lang.version>

  19. <springfox.version>2.7.0</springfox.version>

  20. </properties>

  21. <dependencies>

  22. <dependency>

  23. <groupId>org.springframework.boot</groupId>

  24. <artifactId>spring-boot-starter</artifactId>

  25. </dependency>

  26. <dependency>

  27. <groupId>org.springframework.boot</groupId>

  28. <artifactId>spring-boot-starter-data-mongodb</artifactId>

  29. </dependency>

  30. <dependency>

  31. <groupId>org.springframework.boot</groupId>

  32. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>

  33. </dependency>

  34. <dependency>

  35. <groupId>org.springframework.boot</groupId>

  36. <artifactId>spring-boot-starter-data-jpa</artifactId>

  37. </dependency>

  38. <dependency>

  39. <groupId>mysql</groupId>

  40. <artifactId>mysql-connector-java</artifactId>

  41. <scope>runtime</scope>

  42. </dependency>

  43. <dependency>

  44. <groupId>org.springframework.boot</groupId>

  45. <artifactId>spring-boot-starter-web</artifactId>

  46. </dependency>

  47. <dependency>

  48. <groupId>io.springfox</groupId>

  49. <artifactId>springfox-swagger2</artifactId>

  50. <version>${springfox.version}</version>

  51. </dependency>

  52. <dependency>

  53. <groupId>io.springfox</groupId>

  54. <artifactId>springfox-swagger-ui</artifactId>

  55. <version>${springfox.version}</version>

  56. </dependency>

  57. <dependency>

  58. <groupId>com.alibaba</groupId>

  59. <artifactId>fastjson</artifactId>

  60. <version>1.2.15</version>

  61. </dependency>

  62. <dependency>

  63. <groupId>org.apache.commons</groupId>

  64. <artifactId>commons-lang3</artifactId>

  65. <version>${commons.lang.version}</version>

  66. </dependency>

  67. <dependency>

  68. <groupId>org.apache.commons</groupId>

  69. <artifactId>commons-collections4</artifactId>

  70. <version>4.1</version>

  71. </dependency>

  72. <dependency>

  73. <groupId>com.github.wenhao</groupId>

  74. <artifactId>jpa-spec</artifactId>

  75. <version>3.2.3</version>

  76. </dependency>

  77. </dependencies>

  78. <build>

  79. <sourceDirectory>src</sourceDirectory>

  80. <plugins>

  81. <plugin>

  82. <artifactId>maven-compiler-plugin</artifactId>

  83. <configuration>

  84. <source>1.8</source>

  85. <target>1.8</target>

  86. </configuration>

  87. </plugin>

  88. </plugins>

  89. </build>

  90. </project>

封装后使用

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

MySQL 动态数据访问

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

  • User

 
  1. @Entity

  2. @Table(name = "tb_user")

  3. public class User extends BaseEntity {

  4. private static final long serialVersionUID = 1L;

  5. /**

  6. * 用户id

  7. */

  8. @Id

  9. @GeneratedValue(strategy = GenerationType.AUTO)

  10. @Column(name = "id", nullable = false)

  11. private Integer id;

  12. private String userName;

  13. private String nickName;

  14. private String password;

  15. private Integer sex;

  16. private String telephone;

  17. private String email;

  18. private String address;

  19. private Integer deleteStatus;

  20. private Integer locked = 0;

  21. private String description;

  22. @JSONField(format = "yyyy-MM-dd HH:mm:ss")

  23. private Date createTime;

  24. @JSONField(format = "yyyy-MM-dd HH:mm:ss")

  25. private Date updateTime;

  26. @ManyToMany(cascade = { CascadeType.REFRESH }, fetch = FetchType.LAZY)

  27. @JoinTable(name = "tb_user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = {

  28. @JoinColumn(name = "role_id") })

  29. private java.util.Set<Role> roles;

  30. // getter & setter

  31. }

  • Dao

 
  1. @Repository

  2. public interface IUserDao extends IBaseJpaDao<User, Integer>{

  3. }

  • Service

 
  1. public interface IUserService extends IBaseJpaService<User, Integer> {

  2. }

  3. @Service

  4. public class UserServiceImpl extends BaseJpaServiceImpl<User, Integer> implements IUserService {

  5. @Autowired

  6. private IUserDao userDao;

  7. @Override

  8. public IBaseJpaDao<User, Integer> getBaseDao() {

  9. return this.userDao;

  10. }

  11. @Override

  12. public void delete(Integer id) {

  13. User user = find(id);

  14. Assert.state(!"admin".equals(user.getUserName()), "超级管理员用户不能删除");

  15. super.delete(id);

  16. }

  17. }

  • Controller

 
  1. @RestController

  2. @RequestMapping("/admin/user")

  3. public class UserController {

  4. /**

  5. * user service

  6. */

  7. @Autowired

  8. private IUserService userService;

  9. /**

  10. * @param searchText

  11. * @param user

  12. * @param model

  13. * @return

  14. */

  15. @GetMapping(value = "/list")

  16. public List<User> list(@RequestParam(value = "searchText", required = false, defaultValue="a") String searchText) {

  17. return userService.findAll(Specifications.<User>and().like("userName", "%" + searchText + "%").build());

  18. }

  19. }

Mongo 动态数据访问

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

  • Entity

 
  1. @Document(collection = "security_alert_rules")

  2. public class EventRule extends BaseEntity {

  3. private static final long serialVersionUID = -2013673868028645757L;

  4. public static final int EVENT_STATUS_ENABLE = 0, EVENT_STATUS_DISABLE = 1;

  5. private String component;

  6. private String name;

  7. private String eventId;

  8. private String ciaLevel;

  9. private String remarks;

  10. private String script;

  11. private long threshold;

  12. private long timeWindow;

  13. private String parseEsResultKeys;

  14. private String nameCN;

  15. private String remarkCN;

  16. private String ruleType;

  17. private String redisEventKey;

  18. private int status = EVENT_STATUS_ENABLE;

  19. // getter & setter

  20. }

  • Dao

 
  1. @Repository

  2. public interface IEventRuleDao extends IBaseMongoDao<EventRule, String> {

  3. }

  • Service

 
  1. public interface IEventRuleService extends IBaseMongoService<EventRule, String> {

  2. }

  3. @Service

  4. public class EventRuleServiceImpl extends BaseMongoServiceImpl<EventRule, String> implements IEventRuleService {

  5. @Autowired

  6. IEventRuleDao eventRuleDao;

  7. @Override

  8. public IBaseMongoDao<EventRule, String> getBaseDao() {

  9. return eventRuleDao;

  10. }

  11. }

  • Controller

 
  1. @RestController

  2. @RequestMapping("/admin/eventRule")

  3. public class EventRuleController {

  4. /**

  5. */

  6. @Autowired

  7. private IEventRuleService eventRuleService;

  8. /**

  9. * @param searchText

  10. * @param user

  11. * @param model

  12. * @return

  13. */

  14. @GetMapping(value = "/list")

  15. public List<EventRule> list(@RequestParam(value = "searchText", required = false) String searchText) {

  16. EventRule param = new EventRule();

  17. param.setName(searchText);

  18. // Example<EventRule> rule = Example.<EventRule>of(param,

  19. // ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.exact()));

  20. Example<EventRule> rule = Example.<EventRule>of(param, ExampleMatcher.matching().withIgnoreCase("name","nameCN"));

  21. return eventRuleService.findAll(rule);

  22. }

  23. }

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

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

  • Entity

 
  1. @Document(indexName="syslog", type="logs")

  2. public class SysLog extends BaseEntity {

  3. private static final long serialVersionUID = -4491916941883088972L;

  4. @Id

  5. private String _id;

  6. private Set<String> phyPorts = new LinkedHashSet<>();

  7. private Set<String> ports = new LinkedHashSet<>();

  8. private String sensor;

  9. private int vlan;

  10. private Set<String> ip = new LinkedHashSet<>();

  11. private Set<String> mac = new LinkedHashSet<>();

  12. private String description;

  13. private String type;

  14. private String vendor;

  15. private long timestamp;

  16. private String name;

  17. private String chassisId;

  18. // getter & setter

  19. }

  • Dao

 
  1. @Repository

  2. public interface ISysLogDao extends IBaseESDao<SysLog, String> {

  3. }

  • Service

 
  1. public interface ILogService extends IBaseESService<SysLog, String> {

  2. }

  3. @Service

  4. public class LogServiceImpl extends BaseESServiceImpl<SysLog, String> implements ILogService {

  5. @Autowired

  6. ISysLogDao sysLogDao;

  7. @Override

  8. public IBaseESDao<SysLog, String> getBaseDao() {

  9. return sysLogDao;

  10. }

  11. }

  • Controller

 
  1. @RestController

  2. @RequestMapping("/admin/log")

  3. public class LogController {

  4. /**

  5. * user service

  6. */

  7. @Autowired

  8. private ILogService logService;

  9. /**

  10. * @param searchText

  11. * @param user

  12. * @param model

  13. * @return

  14. */

  15. @GetMapping(value = "/list")

  16. public Page<SysLog> list(@RequestParam(value = "searchText", required = false) String searchText) {

  17. return logService.search(QueryBuilders.matchQuery("_all", searchText), new PageRequest(0, 100));

  18. }

  19. }

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

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

  • Entity

 
  1. @Document(indexName="syslog", type="logs")

  2. public class SysLog extends BaseEntity {

  3. private static final long serialVersionUID = -4491916941883088972L;

  4. @Id

  5. private String _id;

  6. private Set<String> phyPorts = new LinkedHashSet<>();

  7. private Set<String> ports = new LinkedHashSet<>();

  8. private String sensor;

  9. private int vlan;

  10. private Set<String> ip = new LinkedHashSet<>();

  11. private Set<String> mac = new LinkedHashSet<>();

  12. private String description;

  13. private String type;

  14. private String vendor;

  15. private long timestamp;

  16. private String name;

  17. private String chassisId;

  18. // getter & setter

  19. }

  • Dao

 
  1. public interface IDymLogDao extends IDynamicEsDao<SysLog, String> {

  2. }

  3. @Repository

  4. public class DymLogDaoImpl extends SimpleDynamicEsDaoImpl<SysLog, String> implements IDymLogDao {

  5. @Autowired

  6. protected ElasticsearchTemplate elasticsearchTemplate;

  7. @Override

  8. public ElasticsearchOperations getElasticsearchOperations() {

  9. return elasticsearchTemplate;

  10. }

  11. }

  • Service

 
  1. public interface IDymLogService extends IDynamicESService<SysLog, String> {

  2. }

  3. @Service

  4. public class DymLogServiceImpl extends DynamicESServiceImpl<SysLog, String> implements IDymLogService {

  5. @Autowired

  6. IDymLogDao sysLogDao;

  7. @Override

  8. public IDynamicEsDao<SysLog, String> getBaseDao() {

  9. return sysLogDao;

  10. }

  11. }

  • Controller

 
  1. @RestController

  2. @RequestMapping("/admin/dymLog")

  3. public class DymLogController {

  4. /**

  5. * logService

  6. */

  7. @Autowired

  8. private IDymLogService logService;

  9. /**

  10. * @param searchText

  11. * @param user

  12. * @param model

  13. * @return

  14. */

  15. @GetMapping(value = "/list")

  16. public Page<SysLog> list(

  17. @RequestParam(value = "searchText", required = false, defaultValue = "Siemens") String searchText) {

  18. QueryBuilder queryBuilder = QueryBuilders.matchQuery("vendor", searchText);

  19. return logService.search(new NativeSearchQueryBuilder().withIndices("syslog-2018-12-17").withTypes("logs")

  20. .withQuery(queryBuilder).build());

  21. }

  22. }

源代码托管

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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值