mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-06 16:48:24 +08:00
!477 添加 1.sqlserver 转义 scheme table colums 包装 根据 . 分割后分别包装 2.SQLserver保留字
Merge pull request !477 from macy0122/main
This commit is contained in:
commit
b03cfc6af6
@ -38,7 +38,6 @@ public class DialectFactory {
|
||||
* 此 map 中,用于覆盖系统的方言实现
|
||||
*/
|
||||
private static final Map<DbType, IDialect> dialectMap = new EnumMap<>(DbType.class);
|
||||
|
||||
/**
|
||||
* 通过设置当前线程的数据库类型,以达到在代码执行时随时切换方言的功能
|
||||
*/
|
||||
@ -142,9 +141,9 @@ public class DialectFactory {
|
||||
case DB2_1005:
|
||||
return new DB2105Dialect(KeywordWrap.NONE, DB2105Dialect.DB2105LimitOffsetProcessor.DB2105);
|
||||
case SQLSERVER:
|
||||
return new CommonsDialectImpl(KeywordWrap.NONE_CASE_SENSITIVE, LimitOffsetProcessor.SQLSERVER);
|
||||
return new SqlserverDialectImpl(KeywordWrap.SQUARE_BRACKETS, LimitOffsetProcessor.SQLSERVER);
|
||||
case SQLSERVER_2005:
|
||||
return new CommonsDialectImpl(KeywordWrap.NONE_CASE_SENSITIVE, LimitOffsetProcessor.SQLSERVER_2005);
|
||||
return new Sqlserver2005DialectImpl(KeywordWrap.SQUARE_BRACKETS, LimitOffsetProcessor.SQLSERVER_2005);
|
||||
case INFORMIX:
|
||||
return new CommonsDialectImpl(KeywordWrap.NONE, LimitOffsetProcessor.INFORMIX);
|
||||
case SINODB:
|
||||
|
||||
@ -18,6 +18,7 @@ package com.mybatisflex.core.dialect;
|
||||
import com.mybatisflex.core.constant.SqlConsts;
|
||||
import com.mybatisflex.core.util.StringUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@ -88,6 +89,7 @@ public class KeywordWrap {
|
||||
this(false, Collections.emptySet(), prefix, suffix);
|
||||
}
|
||||
|
||||
|
||||
public KeywordWrap(boolean caseSensitive, String prefix, String suffix) {
|
||||
this(caseSensitive, Collections.emptySet(), prefix, suffix);
|
||||
}
|
||||
@ -103,7 +105,8 @@ public class KeywordWrap {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public KeywordWrap(boolean caseSensitive, boolean keywordsToUpperCase, Set<String> keywords, String prefix, String suffix) {
|
||||
public KeywordWrap(boolean caseSensitive, boolean keywordsToUpperCase, Set<String> keywords, String prefix,
|
||||
String suffix) {
|
||||
this.caseSensitive = caseSensitive;
|
||||
this.keywordsToUpperCase = keywordsToUpperCase;
|
||||
this.keywords = keywords.stream().map(String::toUpperCase).collect(Collectors.toSet());
|
||||
@ -128,6 +131,37 @@ public class KeywordWrap {
|
||||
}
|
||||
}
|
||||
|
||||
//数据scheme table 包装 根据 . 分割后分别包装
|
||||
public String wrapKeyword(String keyword) {
|
||||
StringBuilder resultBuilder = new StringBuilder();
|
||||
String[] split = keyword.split("\\.");
|
||||
if (split != null && split.length > 0) {
|
||||
Arrays.asList(split)
|
||||
.forEach(f -> resultBuilder.append(prefix).append(f).append(suffix).append("."));
|
||||
return resultBuilder.toString().substring(0, resultBuilder.length() - 1);
|
||||
} else {
|
||||
return prefix + keyword + suffix;
|
||||
}
|
||||
}
|
||||
|
||||
//sqlserver 转义 scheme table colums 包装 根据 . 分割后分别包装
|
||||
public String wrap4Sqlserver(String keyword) {
|
||||
if (StringUtil.isBlank(keyword) || SqlConsts.ASTERISK.equals(keyword.trim())) {
|
||||
return keyword;
|
||||
}
|
||||
|
||||
if (caseSensitive || keywords.isEmpty()) {
|
||||
return wrapKeyword(keyword);
|
||||
}
|
||||
|
||||
if (keywordsToUpperCase) {
|
||||
keyword = keyword.toUpperCase();
|
||||
return keywords.contains(keyword) ? wrapKeyword(keyword) : keyword;
|
||||
} else {
|
||||
return keywords.contains(keyword.toUpperCase()) ? wrapKeyword(keyword) : keyword;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCaseSensitive() {
|
||||
return caseSensitive;
|
||||
}
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
package com.mybatisflex.core.dialect.impl;
|
||||
|
||||
import com.mybatisflex.core.dialect.KeywordWrap;
|
||||
import com.mybatisflex.core.dialect.LimitOffsetProcessor;
|
||||
import com.mybatisflex.core.util.CollectionUtil;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static com.mybatisflex.core.constant.SqlConsts.ASTERISK;
|
||||
|
||||
public class Sqlserver2005DialectImpl extends CommonsDialectImpl {
|
||||
|
||||
public static final Set<String> keywords = CollectionUtil.newHashSet("ADD", "ALL", "ALTER", "AND", "ANY", "AS",
|
||||
"ASC", "AUTHORIZATION", "BACKUP", "BEGIN", "BETWEEN", "BREAK", "BROWSE", "BULK", "BY", "CASCADE", "CASE",
|
||||
"CHECK", "CHECKPOINT", "CLOSE", "CLUSTERED", "COALESCE", "COLLATE", "COLUMN", "COMMIT", "COMPUTE", "CONSTRAINT",
|
||||
"CONTAINS", "CONTAINSTABLE", "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE",
|
||||
"CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE", "DECLARE",
|
||||
"DEFAULT", "DELETE", "DENY", "DESC", "DISTINCT", "DISTRIBUTED", "DOUBLE", "DROP", "DUMP", "ELSE", "END",
|
||||
"ERRLVL", "ESCAPE", "EXCEPT", "EXEC", "EXECUTE", "EXISTS", "EXIT", "EXTERNAL", "FETCH", "FILE", "FILLFACTOR",
|
||||
"FOR", "FOREIGN", "FREETEXT", "FREETEXTTABLE", "FROM", "FULL", "FUNCTION", "GOTO", "GRANT", "GROUP", "HAVING",
|
||||
"HOLDLOCK", "IDENTITY", "IDENTITY_INSERT", "IDENTITYCOL", "IF", "IN", "INDEX", "INNER", "INSERT", "INTERSECT",
|
||||
"INTO", "IS", "JOIN", "KEY", "KILL", "LEFT", "LIKE", "LINENO", "LOAD", "MAX", "MIN", "NATIONAL", "NOCHECK",
|
||||
"NONCLUSTERED", "NOT", "NULL", "NULLIF", "OF", "OFF", "OFFSETS", "ON", "OPEN", "OPENDATASOURCE", "OPENQUERY",
|
||||
"OPENROWSET", "OPTION", "OR", "ORDER", "OUTER", "OVER", "PERCENT", "PLAN", "PRECISION", "PREPARE", "PRIMARY",
|
||||
"PRINT", "PROC", "PROCEDURE", "PUBLIC", "RAISERROR", "READ", "READTEXT", "RECONFIGURE", "REFERENCES",
|
||||
"REPEATABLE", "RESTORE", "RESTRICT", "RETURN", "REVOKE", "RIGHT", "ROLLBACK", "ROWCOUNT", "ROWGUIDCOL", "RULE",
|
||||
"SAVE", "SCHEMA", "SECURITYAUDIT", "SELECT", "SESSION_USER", "SET", "SETUSER", "SHUTDOWN", "SOME", "STATISTICS",
|
||||
"SYSTEM_USER", "TABLE", "TABLESAMPLE", "TEXTSIZE", "THEN", "TO", "TOP", "TRAN", "TRANSACTION", "TRIGGER",
|
||||
"TRUNCATE", "TSEQUAL", "UNION", "UNIQUE", "UNPIVOT", "UPDATE", "UPDATETEXT", "USE", "USER", "USING", "VALUES",
|
||||
"VARYING", "VIEW", "WAITFOR", "WHEN", "WHERE", "WHILE", "WITH", "WITHIN GROUP", "WRITETEXT", "XACT_ABORT",
|
||||
"XLOCK");
|
||||
|
||||
public Sqlserver2005DialectImpl() {
|
||||
this(LimitOffsetProcessor.SQLSERVER_2005);
|
||||
}
|
||||
|
||||
public Sqlserver2005DialectImpl(LimitOffsetProcessor limitOffsetProcessor) {
|
||||
this(new KeywordWrap(true, false, keywords, "[", "]"), limitOffsetProcessor);
|
||||
}
|
||||
|
||||
public Sqlserver2005DialectImpl(KeywordWrap keywordWrap, LimitOffsetProcessor limitOffsetProcessor) {
|
||||
super(keywordWrap, limitOffsetProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String wrap(String keyword) {
|
||||
return ASTERISK.equals(keyword) ? keyword : keywordWrap.wrap4Sqlserver(keyword);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
package com.mybatisflex.core.dialect.impl;
|
||||
|
||||
import com.mybatisflex.core.dialect.KeywordWrap;
|
||||
import com.mybatisflex.core.dialect.LimitOffsetProcessor;
|
||||
import com.mybatisflex.core.util.CollectionUtil;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static com.mybatisflex.core.constant.SqlConsts.ASTERISK;
|
||||
|
||||
public class SqlserverDialectImpl extends CommonsDialectImpl {
|
||||
|
||||
public static final Set<String> keywords = CollectionUtil.newHashSet("ADD", "ALL", "ALTER", "AND", "ANY", "AS",
|
||||
"ASC", "BACKUP", "BEGIN", "BETWEEN", "BREAK", "BROWSE", "BULK", "BY", "CASCADE", "CASE", "CHECK", "CHECKPOINT",
|
||||
"CLOSE", "CLUSTERED", "COALESCE", "COLUMN", "COMMIT", "COMMITTED", "COMPUTE", "CONFIRM", "CONNECT",
|
||||
"CONSTRAINT", "CONTAINS", "CONTAINSTABLE", "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE",
|
||||
"CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE", "DECLARE",
|
||||
"DEFAULT", "DELETE", "DENY", "DESC", "DISTINCT", "DISTRIBUTED", "DOUBLE", "DROP", "DUMP", "ELSE", "END",
|
||||
"ERRLVL", "ESCAPE", "EXCEPT", "EXEC", "EXECUTE", "EXISTS", "EXIT", "EXTERNAL", "FETCH", "FILE", "FILLFACTOR",
|
||||
"FOR", "FOREIGN", "FREETEXT", "FREETEXTTABLE", "FROM", "FULL", "FUNCTION", "GOTO", "GRANT", "GROUP", "HAVING",
|
||||
"HOLDLOCK", "IDENTITY", "IDENTITY_INSERT", "IDENTITYCOL", "IF", "IN", "INDEX", "INNER", "INSERT", "INTERSECT",
|
||||
"INTO", "IS", "JOIN", "KEY", "KILL", "LEFT", "LIKE", "LINENO", "LOAD", "MAX", "MIN", "NATIONAL", "NOCHECK",
|
||||
"NONCLUSTERED", "NOT", "NULL", "NULLIF", "OF", "OFF", "OFFSETS", "ON", "OPEN", "OPENDATASOURCE", "OPENQUERY",
|
||||
"OPENROWSET", "OPTION", "OR", "ORDER", "OUTER", "OVER", "PERCENT", "PIPE", "PLAN", "PRECISION", "PREPARE",
|
||||
"PRIMARY", "PRINT", "PRIVILEGES", "PROC", "PROCEDURE", "PUBLIC", "RAISERROR", "READ", "READTEXT", "RECONFIGURE",
|
||||
"REFERENCES", "REPEATABLE", "RESTORE", "RESTRICT", "RETURN", "REVOKE", "RIGHT", "ROLLBACK", "ROWCOUNT",
|
||||
"ROWGUIDCOL", "RULE", "SAVE", "SCHEMA", "SECURITYAUDIT", "SELECT", "SEMANTICKEYPHRASETABLE",
|
||||
"SEMANTICSIMILARITYDETAILSTABLE", "SEMANTICSIMILARITYTABLE", "SESSION_USER", "SET", "SETUSER", "SHUTDOWN",
|
||||
"SOME", "STATISTICS", "SYSTEM_USER", "TABLE", "TABLESAMPLE", "TEXTSIZE", "THEN", "TO", "TOP", "TRAN",
|
||||
"TRANSACTION", "TRIGGER", "TRUNCATE", "TSEQUAL", "UNION", "UNIQUE", "UNPIVOT", "UPDATE", "UPDATETEXT", "USE",
|
||||
"USER", "USING", "VALUES", "VARYING", "VIEW", "WAITFOR", "WHEN", "WHERE", "WHILE", "WITH", "WITHIN GROUP",
|
||||
"WRITETEXT", "XACT_ABORT", "XLOCK");
|
||||
|
||||
public SqlserverDialectImpl() {
|
||||
this(LimitOffsetProcessor.SQLSERVER);
|
||||
}
|
||||
|
||||
public SqlserverDialectImpl(LimitOffsetProcessor limitOffsetProcessor) {
|
||||
this(new KeywordWrap(true, false, keywords, "[", "]"), limitOffsetProcessor);
|
||||
}
|
||||
|
||||
public SqlserverDialectImpl(KeywordWrap keywordWrap, LimitOffsetProcessor limitOffsetProcessor) {
|
||||
super(keywordWrap, limitOffsetProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String wrap(String keyword) {
|
||||
return ASTERISK.equals(keyword) ? keyword : keywordWrap.wrap4Sqlserver(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,8 @@ import com.mybatisflex.core.dialect.IDialect;
|
||||
import com.mybatisflex.core.dialect.KeywordWrap;
|
||||
import com.mybatisflex.core.dialect.LimitOffsetProcessor;
|
||||
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
|
||||
import com.mybatisflex.core.dialect.impl.Sqlserver2005DialectImpl;
|
||||
import com.mybatisflex.core.dialect.impl.SqlserverDialectImpl;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@ -42,11 +44,65 @@ public class SqlServer2005DialectTester {
|
||||
IDialect dialect = new CommonsDialectImpl(KeywordWrap.SQUARE_BRACKETS, LimitOffsetProcessor.SQLSERVER_2005);
|
||||
String sql = dialect.forSelectByQuery(query);
|
||||
System.out.println(sql);
|
||||
Assert.assertEquals("WITH temp_datas AS(" +
|
||||
"SELECT ROW_NUMBER() OVER ( ORDER BY [id] DESC) as __rn, * FROM [tb_account] WHERE [id] IN (?, ?) AND [sex] = ?" +
|
||||
Assert.assertEquals("WITH temp_datas AS("
|
||||
+ "SELECT ROW_NUMBER() OVER ( ORDER BY [id] DESC) as __rn, * FROM [tb_account] WHERE [id] IN (?, ?) AND [sex] = ?"
|
||||
+
|
||||
") " +
|
||||
"SELECT * FROM temp_datas WHERE __rn BETWEEN 11 AND 20 ORDER BY __rn", sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectSqlSqlserver2005() {
|
||||
QueryWrapper query = new QueryWrapper().select()
|
||||
.from("TEST.dbo.tb_account")
|
||||
.where(ACCOUNT.ID.in("100", "200"))
|
||||
.and(ACCOUNT.SEX.eq(1))
|
||||
.orderBy(ACCOUNT.ID.desc())
|
||||
.limit(0, 10);
|
||||
|
||||
IDialect dialect = new Sqlserver2005DialectImpl(KeywordWrap.SQUARE_BRACKETS,
|
||||
LimitOffsetProcessor.SQLSERVER_2005);
|
||||
String sql = dialect.forSelectByQuery(query);
|
||||
System.out.println(sql);
|
||||
Assert.assertEquals(
|
||||
"WITH temp_datas AS(SELECT ROW_NUMBER() OVER ( ORDER BY [tb_account].[id] DESC) as __rn, * FROM [TEST].[dbo].[tb_account] WHERE [tb_account].[id] IN (?, ?) AND [tb_account].[sex] = ?) SELECT * FROM temp_datas WHERE __rn BETWEEN 1 AND 10 ORDER BY __rn",
|
||||
sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectSqlSqlserver() {
|
||||
QueryWrapper query = new QueryWrapper().select()
|
||||
.from("TEST.dbo.tb_account")
|
||||
.where(ACCOUNT.ID.in("100", "200"))
|
||||
.and(ACCOUNT.SEX.eq(1))
|
||||
.orderBy(ACCOUNT.ID.desc())
|
||||
.limit(0, 10);
|
||||
|
||||
IDialect dialect = new SqlserverDialectImpl(KeywordWrap.SQUARE_BRACKETS,
|
||||
LimitOffsetProcessor.SQLSERVER);
|
||||
String sql = dialect.forSelectByQuery(query);
|
||||
System.out.println(sql);
|
||||
Assert.assertEquals(
|
||||
"SELECT * FROM [TEST].[dbo].[tb_account] WHERE [tb_account].[id] IN (?, ?) AND [tb_account].[sex] = ? ORDER BY [tb_account].[id] DESC OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY",
|
||||
sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectSqlSqlserver1() {
|
||||
QueryWrapper query = new QueryWrapper().select()
|
||||
.from("tb_account")
|
||||
.where(ACCOUNT.ID.in("100", "200"))
|
||||
.and(ACCOUNT.SEX.eq(1))
|
||||
.orderBy(ACCOUNT.ID.desc())
|
||||
.limit(0, 10);
|
||||
|
||||
IDialect dialect = new SqlserverDialectImpl(KeywordWrap.SQUARE_BRACKETS,
|
||||
LimitOffsetProcessor.SQLSERVER);
|
||||
String sql = dialect.forSelectByQuery(query);
|
||||
System.out.println(sql);
|
||||
Assert.assertEquals(
|
||||
"SELECT * FROM [tb_account] WHERE [id] IN (?, ?) AND [sex] = ? ORDER BY [id] DESC OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY",
|
||||
sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user