mycat使用规范
Posted wanhua-wu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mycat使用规范相关的知识,希望对你有一定的参考价值。
原始语句:
INSERT INTO mail_send ( createTime, updateTime, flag, accountId, messageID, sender, senderName, fromer, replyTo, toer, ccer, bccer, SUBJECT, text, STATUS, costTime, seperated, marketed, readCount, uid, uidValidity, uidBatchNum, attached, needDownloadAttach, syncFromMailServer, messageNum, folder, sentTime, contentSummary ) VALUES ( NOW(), NULL, 0, 1115, ‘2222000000‘, NULL, NULL, ‘9999‘, ‘9999‘, NULL, NULL, NULL, NULL, ‘<html><p style=\"margin: 0px;\">it will soon be on wuwanhua2908 vacation now,(Labor Day,01/05-05/05)</p><img style=\"display:none\" class=\"just-for-mail-none-lys\"></html>‘, 0, NULL, 0, 0, 0, NULL, NULL, 0, 0, NULL, 0, 0, NULL, NULL, NULL )
1,insert语句中应该避免主键缺失
如果一个表的主键字段是ID, 那么在insert的时候语句中ID应该不能为空,尽量在业务层使用自己的ID生成器提前生成ID,避免使用数据库自增ID生成策略
原因:mycat1.6.5版本中为了补充缺失的主键ID,会尝试修改你的sql语句,这里有一些bug,导致你的sql出错
/**
* 对于主键不在插入语句的fields中的SQL,需要改写。比如hotnews主键为id,插入语句为:
* insert into hotnews(title) values(‘aaa‘);
* 需要改写成:
* insert into hotnews(id, title) values(next value for MYCATSEQ_hotnews,‘aaa‘);
*/
public static void handleBatchInsert(ServerConnection sc, SchemaConfig schema,
int sqlType,String origSQL, int valuesIndex,String tableName, String primaryKey) {
final String pk = "\("+primaryKey+",";
final String mycatSeqPrefix = "(next value for MYCATSEQ_"+tableName.toUpperCase()+",";
/*"VALUES".length() ==6 */
String prefix = origSQL.substring(0, valuesIndex + 6);
String values = origSQL.substring(valuesIndex + 6);
prefix = prefix.replaceFirst("\(", pk);
values = values.replaceFirst("\(", mycatSeqPrefix);
values =Pattern.compile(",\s*\(").matcher(values).replaceAll(","+mycatSeqPrefix);
processSQL(sc, schema,prefix+values, sqlType);
}
处理结果:
INSERT INTO mail_send (
ID,
createTime,
updateTime,
flag,
accountId,
messageID,
sender,
senderName,
fromer,
replyTo,
toer,
ccer,
bccer,
SUBJECT,
text,
STATUS,
costTime,
seperated,
marketed,
readCount,
uid,
uidValidity,
uidBatchNum,
attached,
needDownloadAttach,
syncFromMailServer,
messageNum,
folder,
sentTime,
contentSummary
)
VALUES
(
next value for MYCATSEQ_MAIL_SEND,
NOW(),
NULL,
0,
1115,
‘2222000000‘,
NULL,
NULL,
‘9999‘,
‘9999‘,
NULL,
NULL,
NULL,
NULL,
‘<html><p style=\"margin: 0px;\">it will soon be on wuwanhua2908 vacation now,(next value for MYCATSEQ_MAIL_SEND,Labor Day,01/05-05/05)</p><img style=\"display:none\" class=\"just-for-mail-none-lys\"></html>‘,
0,
NULL,
0,
0,
0,
NULL,
NULL,
0,
0,
NULL,
0,
0,
NULL,
NULL,
NULL
)
2,sql语句中应该避免使用NOW()
在sql语句中涉及到时间的字段,value不能写NOW(),尽量在业务层把时间初始化好,避免依赖数据库生成当前时间
原因:mycat1.7版本中,为了解决第一个问题中的bug,根据括号符号拆分语句(多个values拆成多个insert语句),由于NOW()中的括号导致拆分失败,最终sql执行异常
[Err] 1064 - com.alibaba.druid.sql.parser.ParserException: syntax error
public static List<String> handleBatchInsert(String origSQL, int valuesIndex){ List<String> handledSQLs = new LinkedList<>(); String prefix = origSQL.substring(0,valuesIndex + "VALUES".length()); String values = origSQL.substring(valuesIndex + "VALUES".length()); int flag = 0; StringBuilder currentValue = new StringBuilder(); currentValue.append(prefix); for (int i = 0; i < values.length(); i++) { char j = values.charAt(i); if(j==‘(‘ && flag == 0){ flag = 1; currentValue.append(j); }else if(j==‘"‘ && flag == 1){ flag = 2; currentValue.append(j); } else if(j==‘‘‘ && flag == 1){ flag = 2; currentValue.append(j); } else if(j==‘\‘ && flag == 2){ flag = 3; currentValue.append(j); } else if (flag == 3){ flag = 2; currentValue.append(j); }else if(j==‘"‘ && flag == 2){ flag = 1; currentValue.append(j); } else if(j==‘‘‘ && flag == 2){ flag = 1; currentValue.append(j); } else if (j==‘)‘ && flag == 1){ flag = 0; currentValue.append(j); handledSQLs.add(currentValue.toString()); currentValue = new StringBuilder(); currentValue.append(prefix); } else if(j == ‘,‘ && flag == 0){ continue; } else { currentValue.append(j); } } return handledSQLs; }
拆分结果1:
INSERT INTO mail_send ( createTime, updateTime, flag, accountId, messageID, sender, senderName, fromer, replyTo, toer, ccer, bccer, SUBJECT, text, STATUS, costTime, seperated, marketed, readCount, uid, uidValidity, uidBatchNum, attached, needDownloadAttach, syncFromMailServer, messageNum, folder, sentTime, contentSummary ) VALUES ( NOW()
拆分结果2:
INSERT INTO mail_send ( createTime, updateTime, flag, accountId, messageID, sender, senderName, fromer, replyTo, toer, ccer, bccer, subject, text, status, costTime, seperated, marketed, readCount, uid, uidValidity, uidBatchNum, attached, needDownloadAttach, syncFromMailServer, messageNum, folder, sentTime, contentSummary ) VALUES null 0 1115 ‘2222000000‘ null null ‘9999‘ ‘9999‘ null null null null ‘<html><p style=\"margin: 0px;\">it will soon be on wuwanhua2908 vacation now(Labor Day,01/05-05/05)
以上是关于mycat使用规范的主要内容,如果未能解决你的问题,请参考以下文章