/**
* Copyright (C) 2015 Winbons Technology Software Co.,Ltd
* All Rights Reserved.
* Development of this software Winbons Technology Software Co.,Ltd.
* Without the formal written consent of the Company,
* any other individuals, groups may not use,
* copy, modify, or distribute this software
* @Description: TODO(用一句话描述该文件做什么)
* @author HeatoN.Feng
* @date 2016-2-18 上午12:31:10
* @version 1.0
*/
package saas.framework.mutitenant.db;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import saas.framework.cache.JedisCallback;
import saas.framework.cache.RedisCmdHelper;
import saas.framework.mutitenant.TenantConstant;
import saas.framework.mutitenant.cache.RedisDB;
import saas.framework.utils.StringUtils;
@Component
public class TenantDatabaseHelper implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(TenantDatabaseHelper.class);
@Autowired
private JedisPool jedisPool;
private static RedisCmdHelper redisCmdHelper;
private static ConcurrentHashMap<Long, String> tenant_database = new ConcurrentHashMap<Long, String>();
public static String getSchemaByTenantId(Long tenantId){
String schema = tenant_database.get(tenantId);
if(null == schema){
final String key = TenantConstant.TENANT_SCHEMA_PREFIX + tenantId;
schema = (String)redisCmdHelper.executeCallBack(new JedisCallback() {
@Override
public String executCmd(Jedis jedis) {
return jedis.get(key);
}
});
if(!StringUtils.isEmptyString(schema)){
tenant_database.put(tenantId, schema);
}
}
if(StringUtils.isEmptyString(schema)){
logger.error("【在Redis里找不到此租户的对应库映射:dbId=" + tenantId + "】");
}
return null == schema? "SCHEMA-0" : schema;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(jedisPool, "redis config [jedisPool] must not be null");
redisCmdHelper = new RedisCmdHelper();
redisCmdHelper.setJedisPool(jedisPool);
redisCmdHelper.setDb(RedisDB.SCHEMA_DB.getIndex());
}
}
----------------------------------------------------------------------------------------
/**
* Copyright (C) 2013 Winbons Technology Software Co.,Ltd
* All Rights Reserved.
* Development of this softwareWinbons Technology Software Co.,Ltd.
* Without the formal written consent of the Company,
* any other individuals, groups may not use,
* copy, modify, or distribute this software
* @Title: TenantSwitch.java
* @Package saas.framework.mutitenant
* @Description: TODO(用一句话描述该文件做什么)
* @author yxx
* @date 2014-3-17 下午4:33:40
* @version 1.0
*/
package saas.framework.mutitenant;
/**
* @ClassName: TenantSwitch
* @Description: TODO(这里用一句话描述这个类的作用)
* @author yxx
* @date 2014-3-17 下午4:33:40
*/
public class TenantConstant {
public final static String MYCAT_HINT = "/*!mycat:";
public static final String NON_PARSER = "/*noformat*/";
public static final String TENANT_HINT_PREFIX = "/*#tenant:";
public static final int TENANT_HINT_PREFIX_LEN = TENANT_HINT_PREFIX.length();
//FIXME 支持从指定租户获取相关数据,例如意见反馈需要回复其它租户的消息
public static final String TENANT_HINT = "/*#tenant:dbid={0}*/";
/**
* 是否开启连接数据库中间件,例如CRM系统
*/
public static final String TENANT_DB_NEED_PROXY = "tenant_db_proxy";
public static final String TENANT_SQL_NEED_PARSE = "tenant_sql_parse";
/**
* 是否需要支持分库。例如平台
*/
public static final String TENANT_DB_NEED_SCHEMA = "tenant_db_schema";
public static final String TENANT_SCHEMA_PREFIX = "TENANT_SCHEMA_";
public static final String INSERT_SQL = "insert";
public static final int NO_PARSER_LEN = NON_PARSER.length();
private static ThreadLocal<Boolean> needParse = new ThreadLocal<Boolean>();
public static void closeParse() {
needParse.set(false);
}
/**
*
* @Title: setNeedParse
* @Description: 设置是否开启sql转换 默认不开启
* @return void 返回类型
* @throws
* @date 2014-3-17 下午4:43:57
*/
public static void openParse() {
needParse.set(true);
}
/**
* Attation is can be null
*
* @return
*/
public static Boolean isNeedParse() {
return needParse.get();
}
public static void clear() {
needParse.remove();
}
}
-------------------------------------------------------------------------
package saas.framework.utils;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
public class StringUtils extends org.springframework.util.StringUtils {
private static Escaper escaper = new Escaper(true);
private static String EMPTY_STR = "";
public static final String defaultDelimiter = "[;]";
private static String STRING_HTTP_PREFIX = "http://";
private static String STRING_HTTPS_PREFIX = "https://";
// bt字节参考量
public static final long SIZE_BT = 1024L;
// KB字节参考量
public static final long SIZE_KB = SIZE_BT * 1024L;
// MB字节参考量
public static final long SIZE_MB = SIZE_KB * 1024L;
// GB字节参考量
public static final long SIZE_GB = SIZE_MB * 1024L;
// TB字节参考量
public static final long SIZE_TB = SIZE_GB * 1024L;
public static final int SCALE = 2;
private static Pattern HKMobilePattern = Pattern.compile("^[5,6,9]\\d{7}$");
private static Pattern mobilePattern = Pattern.compile("^[1][3,4,5,8][0-9]{9}$");
private static Pattern mobileOrPhonePattern=Pattern.compile("1([\\d]{10})|((\\+[0-9]{2,4})?\\(?[0-9]+\\)?-?)?[0-9]{7,8}");
private static Pattern emailPattern = Pattern.compile("^[\\w-_\\.+]*[\\w-_\\.]\\@([\\w-]+\\.)+[\\w]+[\\w]$");
static final Pattern CHINESE_PATTERN = Pattern.compile("[\u4e00-\u9fa5]");
private StringUtils() {
;
}
/**
* 检查字符串是否为<code>null</code>或空字符串<code>""</code>。
*
* <pre>
* StringUtil.isEmptyString(null) = true
* StringUtil.isEmptyString("") = true
* StringUtil.isEmptyString(" ") = true
* StringUtil.isEmptyString("bob") = false
* StringUtil.isEmptyString(" bob ") = false
* </pre>
*
* @param str
* 要检查的字符串
*
* @return 如果为空, 则返回<code>true</code>
*/
public static boolean isEmptyString(String s) {
if (null == s || s.trim().length() == 0) {
return true;
}
return false;
}
public static String toString(Object s) {
if (null == s) {
return EMPTY_STR;
}
return valueOf(s);
}
/**
* Trims a given String. An empty String will be returned if the given
* String is null.
*
* @param s
* The String to be Trimmed.
* @return The String trimmed.
*/
public static String trim(String s) {
if (s == null)
return EMPTY_STR;
else
return s.trim();
}
/**
* Trims a given String and then verifies its size against the specified
* size. If the sizes do not match, null will be returned.
*
* @param s
* The String to be trimmed and verified.
* @param size
* The size for the verification.
* @return The trimmed String or null if the size verification failed.
*/
public static String trimAndVerifySize(String s, int size) {
s = trim(s);
if (s.length() != size)
return null;
else
return s;
}
/**
* Checks if a given String contains only digits.
*
* @param s
* A String to be checked.
* @return <PRE>
* true
* </PRE>
*
* if the given String contains only digits,
*
* <PRE>
* false
* </PRE>
*
* otherwise.
*/
public static boolean isAllDigit(String s) {
if (s == null || s.equals(EMPTY_STR))
return false;
else {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (!Character.isDigit(c))
return false;
}
return true;
}
}
/**
* Repeats a given String in the specified number of times, then
* concatenates and returns it.
*
* @param s
* A String to be repeated and concatenated.
* @param occurs
* The number of times of the given String to be repeated.
* @return The concatenated String.
*/
public static String repeatString(String s, int occurs) {
StringBuffer result = new StringBuffer();
if (s != null && occurs > 0) {
for (int i = 0; i < occurs; i++) {
result.append(s);
}
}
return result.toString();
}
/**
* replace all the specify regex do not case UpperCase or LowerCase
*
* @param text
* @param regex
* @param replacement
* @return
* @throws IllegalAccessException
*/
public static String replaceAllIgnoreCase(String text, String regex, String replacement)
throws IllegalAccessException {
if (null == text || null == regex || null == replacement)
throw new IllegalAccessException("Null Paramter Not Allow!");
text = text.replaceAll("(?i)" + regex, replacement);
return text;
}
/**
* 替换字符串,不采用正则表达式,在性能要求高的情况下使用
*
* @param line
* @param str1
* @param str2
* @return
*/
public static final String replaceAll(String line, String str1, String str2) {
StringBuffer newStr = new StringBuffer();
int lastAppendIndex = 0;
int start = line.indexOf(str1, lastAppendIndex);
if (start == -1)
return line;
while (start > -1) {
newStr.append(line.substring(lastAppendIndex, start));
newStr.append(str2);
lastAppendIndex = start + str1.length();
start = line.indexOf(str1, lastAppendIndex);
}
newStr.append(line.substring(lastAppendIndex, line.length()));
return newStr.toString();
}
/**
* 分割字符串,不采用正则表达式,在性能要求高的情况下使用
*
* @param line
* @param separator
* @return
*/
public static final String[] split(String line, String separator) {
int index = 0;
List<String> matchList = new ArrayList<String>();
int start = line.indexOf(separator, index);
if (start == -1)
return new String[] { line.toString() };
while (start > -1) {
String match = line.subSequence(index, start).toString();
matchList.add(match);
index = start + separator.length();
start = line.indexOf(separator, index);
}
matchList.add(line.subSequence(index, line.length()).toString());
int resultSize = matchList.size();
while (resultSize > 0 && matchList.get(resultSize - 1).equals(""))
resultSize--;
String[] result = new String[resultSize];
return (String[]) matchList.subList(0, resultSize).toArray(result);
}
public static String sub(String value, int maxLength) {
if (StringUtils.isEmptyString(value))
return "";
return org.apache.commons.lang.StringUtils.substring(value, 0, maxLength);
}
/**
* 总是消除所有的HTML标签的内容,并返回一个子串 过长字符返回省略号
*
* @param content
* @param maxLength
* @return
*/
public static String ellipsis(String content, int maxLength) {
StringBuffer substring = new StringBuffer();
int offset = 0;
boolean flag = true;
while (offset < content.length()) {
char c = content.charAt(offset);
int length = substring.length();
if (length >= maxLength && allowToCut(c)) {
substring.append(" ...");
break;
}
if (length >= maxLength + 20) {
substring.append(" ...");
break;
}
if (c == '<')
flag = false;
if (flag)
substring.append(c);
if (c == '>')
flag = true;
offset++;
}
return substring.toString();
}
private static boolean allowToCut(char c) {
if (c <= 57 && c >= 48)
return false;
if (c <= 90 && c >= 65)
return false;
if (c <= 122 && c >= 97)
return false;
return true;
}
/**
* @param length
* @param prefix
* @param s
* @return
*/
public static String addStringPrefix(int length, String prefix, String s) {
int strLen = null == s ? 0 : s.length();
int needPrefixNum = length - strLen;
StringBuffer result = new StringBuffer();
for (int i = 0; i < needPrefixNum; i++) {
result.append(prefix);
}
result.append(s);
return result.toString();
}
// 固定长度字符串,不足补空格 src-传入字符串,length-固定字符串长度,padding-填补什么,leadingPad-前补还是后补
// true为前补 false为后补
public static String fixLength(String src, int length, char padding, boolean leadingPad) {
if (src == null) {
src = "";
}
if (length <= src.length()) {
return src;
}
StringBuilder result = new StringBuilder(src);
for (int i = src.length(), j = length; i < j; i++) {
if (leadingPad) {
result.insert(0, padding);
} else {
result.append(padding);
}
}
return result.toString();
}
public static String displayStdSize(long longSize, int scale) {
if (longSize >= 0 && longSize < SIZE_BT) {
return longSize + "B";
} else if (longSize >= SIZE_BT && longSize < SIZE_KB) {
BigDecimal longs = new BigDecimal(Double.valueOf(longSize + "").toString());
BigDecimal sizeB = new BigDecimal(Double.valueOf(SIZE_BT + "").toString());
String result = longs.divide(sizeB, scale, BigDecimal.ROUND_HALF_UP).toString();
return result + "KB";
} else if (longSize >= SIZE_KB && longSize < SIZE_MB) {
BigDecimal longs = new BigDecimal(Double.valueOf(longSize + "").toString());
BigDecimal sizeKB = new BigDecimal(Double.valueOf(SIZE_KB + "").toString());
String result = longs.divide(sizeKB, scale, BigDecimal.ROUND_HALF_UP).toString();
return result + "MB";
} else if (longSize >= SIZE_MB && longSize < SIZE_GB) {
BigDecimal longs = new BigDecimal(Double.valueOf(longSize + "").toString());
BigDecimal sizeMB = new BigDecimal(Double.valueOf(SIZE_MB + "").toString());
String result = longs.divide(sizeMB, scale, BigDecimal.ROUND_HALF_UP).toString();
return result + "GB";
} else {
BigDecimal longs = new BigDecimal(Double.valueOf(longSize + "").toString());
BigDecimal sizeGB = new BigDecimal(Double.valueOf(SIZE_GB + "").toString());
String result = longs.divide(sizeGB, scale, BigDecimal.ROUND_HALF_UP).toString();
return result + "TB";
}
}
public static String displayStdSize(long longSize) {
return displayStdSize(longSize, SCALE);
}
public static String[] tokenizeToStringArray(final String str) {
return tokenizeToStringArray(str, StringUtils.defaultDelimiter);
}
public static String[] tokenizeToStringArray(final String str, final String delimiters) {
return str == null ? null : org.springframework.util.StringUtils.tokenizeToStringArray(str, delimiters);
}
public static Object[] removeDuplicatesAndNulls(final Object[] array) {
if (array == null) {
return null;
}
final LinkedHashMap<Object, Object> ht = new LinkedHashMap<Object, Object>();
for (final Object element : array) {
if (element == null) {
continue;
}
ht.put(element, element);
}
final Object[] ret = (Object[]) Array.newInstance(array.getClass().getComponentType(), ht.size());
int j = 0;
final Iterator it = ht.values().iterator();
while (it.hasNext()) {
ret[j++] = it.next();
}
return ret;
}
public static Collection removeDuplicatesAndNulls(final Collection coll) {
if (coll == null) {
return null;
}
return toList(removeDuplicatesAndNulls(coll.toArray(new Object[coll.size()])));
}
public static List toList(final Object obj) {
if (obj == null) {
return null;
}
if (obj.getClass().isArray()) {
final List l = new ArrayList();
for (final Object o : (Object[]) obj) {
l.add(o);
}
return l;
} else if (obj instanceof Collection) {
return new ArrayList((Collection) obj);
} else if (obj instanceof Enumeration) {
return new ArrayList(Collections.list((Enumeration) obj));
}
return null;
}
public static boolean hasText(final String str) {
return org.springframework.util.StringUtils.hasText(str);
}
public static String getExcelColumnLabel(int index) {
String rs = "";
do {
index--;
rs = ((char) (index % 26 + (int) 'A')) + rs;
index = (int) ((index - index % 26) / 26);
} while (index > 0);
return rs;
}
public static String valueOf(Object obj) {
return null == obj ? null : obj.toString();
}
public static Long toLong(String value) {
if (isEmptyString(value))
return null;
return Long.valueOf(value);
}
/**
* @Title: filterWebsitePrefix
* @Description: 过滤网址前缀(目前支持过滤http://和https://)
* @param @param websiteStr
* @param @return 设定文件
* @return String 返回类型
* @throws
* @date 2013-4-27 上午9:23:12
*/
public static String filterWebsitePrefix(String websiteStr) {
websiteStr = replaceLinebreakToEmptyString(websiteStr);
if (org.apache.commons.lang.StringUtils.containsIgnoreCase(websiteStr, STRING_HTTP_PREFIX)) {
String[] siteStr = websiteStr.split(STRING_HTTP_PREFIX);
if (siteStr.length > 0) {
websiteStr = siteStr[siteStr.length - 1];
} else {
return EMPTY_STR;
}
} else if (org.apache.commons.lang.StringUtils.containsIgnoreCase(websiteStr, STRING_HTTPS_PREFIX)) {
String[] siteStr = websiteStr.split(STRING_HTTPS_PREFIX);
if (siteStr.length > 0) {
websiteStr = siteStr[siteStr.length - 1];
} else {
return EMPTY_STR;
}
}
return websiteStr;
}
public static String replaceLinebreakToEmptyString(String s) {
if (isEmptyString(s))
return EMPTY_STR;
StringBuilder ret = new StringBuilder();
char[] cs = s.toCharArray();
for (char c : cs) {
switch (c) {
case '\r':
case '\n':
ret.append("");
break;
default:
ret.append(c);
break;
}
}
return ret.toString();
}
public static String transferCharJavascript(String s) {
StringBuilder ret = new StringBuilder();
char[] cs = s.toCharArray();
for (char c : cs) {
switch (c) {
case '\r':
case '\t':
case '\n':
case '"':
case '\\':
case '\'':
case '<':
case '>':
case '\0':
ret.append(String.format("\\u%04x", (int) c));
break;
default:
ret.append(c);
break;
}
}
return ret.toString();
}
public static String escapeJson(String value) {
return escaper.escapeJsonString(value);
}
public static String escapeSqlForLike(String value) {
StringBuilder ret = new StringBuilder();
char[] cs = value.toCharArray();
for (char c : cs) {
switch (c) {
case '%':
ret.append("\\%");
break;
case '_':
ret.append("\\_");
break;
case '[':
ret.append("\\[");
break;
case '\\':
ret.append("\\\\");
break;
case '\'':
ret.append("''");
break;
default:
ret.append(c);
break;
}
}
return ret.toString();
}
public static String unescapeSqlForLike(String value) {
StringBuilder ret = new StringBuilder();
char[] cs = value.toCharArray();
for (char c : cs) {
switch (c) {
case '\\':
ret.append("");
break;
default:
ret.append(c);
break;
}
}
return ret.toString();
}
public static String escapeSQLForMySQL(String value) {
StringBuilder ret = new StringBuilder();
char[] cs = value.toCharArray();
for (char c : cs) {
switch (c) {
case '\\':
ret.append("\\\\");
break;
case '\'':
ret.append("''");
break;
// case '%': 百分号如果sql是=的判断,则不成立,只有用 LIKE时才需要转移
// ret.append("\\%");
// break;
default:
ret.append(c);
break;
}
}
return ret.toString();
}
public static String encodeFileName(final HttpServletRequest request, String fileName)
throws UnsupportedEncodingException {
String agent = request.getHeader("USER-AGENT");
if (StringUtils.isEmptyString(agent))
return fileName;
agent = agent.toLowerCase();
if ((-1 != agent.indexOf("msie")) || (-1 != agent.indexOf("opera")) || (-1 != agent.indexOf("webkit"))) {
fileName = URLEncoder.encode(fileName, "UTF-8");
fileName = StringUtils.replace(fileName, "+", "%2B");
fileName = StringUtils.replace(fileName, " ", "%20");
return fileName;
} else if ((-1 != agent.indexOf("mozilla"))) {
return "=?UTF-8?B?" + (EncodeUtils.base64Encode(fileName.getBytes("UTF-8"))) + "?=";
} else {
return fileName;
}
}
/**
* 用SQL方式,hibernate 使用like 必须使用
*
* @param value
* @return
*/
public static String escapeSql(String value) {
StringBuilder ret = new StringBuilder();
char[] cs = value.toCharArray();
for (char c : cs) {
switch (c) {
case '%':
ret.append("[%]");
break;
case '_':
ret.append("[_]");
break;
case '[':
ret.append("[[]");
break;
case '\'':
ret.append("''");
break;
default:
ret.append(c);
break;
}
}
return ret.toString();
}
// Since the subject is used to set the filename, it's not a bad idea to
// sanitize it to remove illegal characters.
public static String sanitizeFilename(String name) {
return name.replaceAll("[:\\\\/*?|<> \"']", "_");
}
private static boolean checkStr(Pattern p, String str) {
return p.matcher(str).matches();
}
public static boolean isMobile(String str) {
boolean isMobile = checkStr(mobilePattern, str);// 是否为大陆手机号
if(!isMobile){
isMobile = checkStr(HKMobilePattern, str);// 是否为香港手机号
}
return isMobile;
}
public static boolean isMobileOrPhone(String str) {
return checkStr(mobileOrPhonePattern, str);
}
public static boolean isEmail(String str) {
return checkStr(emailPattern, str);
}
/**
* 替换html的特殊字符
*
* @param content
* @return
*/
public static String html(String content) {
if (content == null)
return "";
String html = content;
html = html.replaceAll("&", "&");
html = html.replace("'", "'");
html = html.replace("\"", """); // "
html = html.replace("\t", " ");// 替换跳格
html = html.replace(" ", " ");// 替换空格
html = html.replace("<", "<");
html = html.replaceAll(">", ">");
return html;
}
public static boolean isChineseChar(String str) {
boolean temp = false;
Matcher m = CHINESE_PATTERN.matcher(str);
if (m.find()) {
temp = true;
}
return temp;
}
public static String escapeRegexLimitword(String content) {
if (content == null)
return "";
String str = content;
/*str = str.replaceAll("\\.", "\\\\.");
str = str.replace("$", "\\$");
str = str.replace("\\^", "\\\\^");
str = str.replaceAll("\\*", "\\\\*");
str = str.replaceAll("\\+", "\\\\+");
str = str.replaceAll("\\?", "\\\\?");
str = str.replaceAll("\\", "\\\\");
str = str.replaceAll("\\/", "\\\\/");
str = str.replace("{", "\\{");
str = str.replace("[", "\\[");
str = str.replace("(", "\\(");
str = str.replaceAll("\\|", "\\\\|");
str = str.replace("}", "\\}");
str = str.replace("]", "\\]");
str = str.replace(")", "\\)");*/
return str;
}
public static void main(String[] args) {
//System.out.println(isEmail("yxx@hh.com.cn"));
//System.out.println(isChineseChar("heello111"));
//String keyword = escapeRegexLimitword("*.?+$^[](){}|\\/");
//System.out.println("keyword: " + keyword);
//keyword = StringUtils.escapeRegexLimitword(keyword);
//Pattern patternSubject = Pattern.compile(keyword.toLowerCase());
//Matcher matcherSubject = patternSubject.matcher("$sf");
//System.out.println(matcherSubject.find());
System.out.println(isMobileOrPhone("012-12345678"));
}
}
-------------------------------------------------------------------------