APIJSON 博客2 AbstractSQLConfig 第二篇

2021SC@SDUSC

Config是什么?

微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的!

  上图所示,假如有三个配置文件,然后每一个配置文件都连接了数据库(同一个),这个时候如果我要换一个数据库使用,那么就要将所有配置文件中的配置进行替换,这个时候我们就可以使用 Config Server 来进行统一配置,这样在我们管理的时候也会比较简单!

我们来看AbstractSQLConfig第一部

1.

PATTERN_RANGE = Pattern.compile("^[0-9%,!=\\<\\>/\\.\\+\\-\\*\\^]+$"); 
// ^[a-zA-Z0-9_*%!=<>(),"]+$ 导致 exists(select*from(Comment)) 通过!
PATTERN_FUNCTION = Pattern.compile("^[A-Za-z0-9%,:_@&~!=\\<\\>\\|\\[\\]\\{\\} /\\.\\+\\-\\*\\^\\?\\$]+$"); 
//TODO 改成更好的正则,校验前面为单词,中间为操作符,后面为值

 凡是 SQL 边界符、分隔符、注释符 都不允许,例如 ' " ` ( ) ; # -- ,以免拼接 SQL 时被注入意外可执行指令

这里用到了 java.util.regex.Pattern

Pattern.compile函数语法
Pattern Pattern.compile(String regex, int flag)
知识学习
Pattern.compile函数中两个参数
1、regex 表示定义的规则
2、flag 表示设置的参数类型,主要包含以下几种情况:
(1)Pattern.CASE_INSENSITIVE(?i) 默认情况下,大小写不明感的匹配只适用于US-ASCII字符集。让表达式忽略大小写进行匹配。
(2)Pattern.COMMENTS(?x) 此种模式下,匹配时会忽略表达式中空格字符(表达式里的空格,tab,回车)。注释从#开始,一直到这行结束。
(3)Pattern.UNIX_LINES(?d) 此种模式下,只有’\n’才被认作一行的中止,并且与’.’,’^’,以及’$’进行匹配。
(4)Pattern.MULTILINE(?m) 此种模式下,上箭头和单引号分别匹配一行的开始和结束。此外,’^‘仍然匹配字符串的开始,’’也匹配字符串的结束。默认情况下,这两个表达式仅仅匹配字符串的开始和结束。
(5)Pattern.DOTALL:此种模式下,表达式’.‘可以匹配任意字符,包括表示一行的结束符。默认情况下,表达式’.'不匹配行的结束符。

 实现的功能是对字符串进行截取,排除SQL 边界符、分隔符、注释符的情况

2.

		TABLE_KEY_MAP = new HashMap<String, String>();
		TABLE_KEY_MAP.put(Table.class.getSimpleName(), Table.TABLE_NAME);
		TABLE_KEY_MAP.put(Column.class.getSimpleName(), Column.TABLE_NAME);
		TABLE_KEY_MAP.put(PgClass.class.getSimpleName(), PgClass.TABLE_NAME);
		TABLE_KEY_MAP.put(PgAttribute.class.getSimpleName(), PgAttribute.TABLE_NAME);
		TABLE_KEY_MAP.put(SysTable.class.getSimpleName(), SysTable.TABLE_NAME);
		TABLE_KEY_MAP.put(SysColumn.class.getSimpleName(), SysColumn.TABLE_NAME);
		TABLE_KEY_MAP.put(ExtendedProperty.class.getSimpleName(), ExtendedProperty.TABLE_NAME);

此处用到了java.util.HashMap;

知识学习

HashMap是我们最常用的类之一,它实现了hash算法

HashMap存储的是key-value形式的键值对,这个键值对在实现中使用一个静态内部类Entry来表示,它存储了key、value、hash值、以及在hash冲突时链表中下一个元素的引用。

HashMap底层实现使用了一个数组来存储元素。它的初始容量默认是16,而且必须容量必须是2的整数次幂,最大容量是1<<30(10.7亿+),同时还使用一个加载因子(load factor)来控制这个map的这个hash表的扩容,默认为0.75,即当容量达到初始容量3/4时会扩容(当然不只这样,后面会说明)。

在往HashMap中添加元素时,会计算key的hashCode,然后基于这个hashCode和数组大小来确定它在数组中的存储位置,当遇到hash冲突时,会以链表的形式存储在数组中。

简介put(key, value)方法的执行过程:
  通过key值,使用散列算法计算出来一个hash值,用来确定该元素需要存储到数组中的哪个位置(index)。
  根据计算出来的位置(index),可以查看该位置是否被占用:
  如果位置(index)未被占用,将(key\value)封装成一个节点,保存到该位置。
  如果位置(index)被占用,使用key和链表中的节点一一比较:
    ---->如果链表中不存在该key,将(key/value)封装成节点添加到该链表中。
    ---->如果链表中已存在该key,替换该key对应节点的value值。

 上图代码中使用的put方法将键值对加入到Map中,

如果key在Map中已经存在,则会被替换并且返回这个旧值,不存在则返回null

V put(K key, V value);

在本项目代码中使用的意义在于将方法名和值对应起来

如Table.class.getSimpleName()=Table.TABLE_NAME

3.

		CONFIG_TABLE_LIST = new ArrayList<>();  // Table, Column 等是系统表 AbstractVerifier.SYSTEM_ACCESS_MAP.keySet());
		CONFIG_TABLE_LIST.add(Function.class.getSimpleName());
		CONFIG_TABLE_LIST.add(Request.class.getSimpleName());
		CONFIG_TABLE_LIST.add(Response.class.getSimpleName());
		CONFIG_TABLE_LIST.add(Access.class.getSimpleName());
		CONFIG_TABLE_LIST.add(Document.class.getSimpleName());
		CONFIG_TABLE_LIST.add(TestRecord.class.getSimpleName());

		DATABASE_LIST = new ArrayList<>();
		DATABASE_LIST.add(DATABASE_MYSQL);
		DATABASE_LIST.add(DATABASE_POSTGRESQL);
		DATABASE_LIST.add(DATABASE_SQLSERVER);
		DATABASE_LIST.add(DATABASE_ORACLE);
		DATABASE_LIST.add(DATABASE_DB2);
		DATABASE_LIST.add(DATABASE_CLICKHOUSE);

这里用到了java.util.ArrayList;

知识学习 

数组和数组列表之间有着重大的区别。数组是 Java 语言的一个特征,对于每个元素类型 T ,都有数组类型 T[]; 然而, ArrayList 类是个定义 java.util 包中的类库。这是一个存放 object 类型元素的 " 普通性 " 的类型。要注意的是,要从数组列表中提取元素时,需要进行类型转换。
  使用 add 方法可以向数组列表中添加新元素:
   ArrayList staff = new ArrayList();
   staff.add(new Employee(....));
   staff.add(new Employee(....));

 在该段代码中,是向CONFIG_TABLE_LIST和DATABASE_LIST中添加数据

这里需要一提的是

public abstract class AbstractSQLConfig implements SQLConfig

该类实现SQLConfig接口

这里放上SQLConfig的代码


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值