Skip to content

Commit bc1598a

Browse files
author
kaiqin
committed
feat(service): sql语法兼容调整
1 parent 6f2bee1 commit bc1598a

File tree

4 files changed

+152
-73
lines changed

4 files changed

+152
-73
lines changed

src/main/java/ooo/github/io/dm/convert/DataScopeInterceptor.java

Lines changed: 13 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
55
import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
66
import lombok.extern.slf4j.Slf4j;
7+
import ooo.github.io.dm.convert.sql.SqlHandler;
78
import org.apache.ibatis.executor.resultset.ResultSetHandler;
89
import org.apache.ibatis.executor.statement.StatementHandler;
910
import org.apache.ibatis.mapping.BoundSql;
1011
import org.apache.ibatis.plugin.*;
1112
import org.apache.ibatis.reflection.MetaObject;
1213
import org.apache.ibatis.reflection.SystemMetaObject;
14+
import org.springframework.beans.factory.annotation.Autowired;
1315
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
1416
import org.springframework.stereotype.Component;
1517
import org.springframework.util.ObjectUtils;
@@ -19,9 +21,11 @@
1921
import java.util.*;
2022

2123
/**
22-
* @author kaiqin
24+
* @author fengwang26
25+
* @version 1.0
26+
* mybatis-plus 全局拦截器
2327
*/
24-
@ConditionalOnProperty(prefix = "ooo.dm.interceptor", name = "enable", havingValue = "true", matchIfMissing = true)
28+
@ConditionalOnProperty(prefix = "iflytek.dm.interceptor", name = "enable", havingValue = "true", matchIfMissing = true)
2529
@Intercepts({
2630
//SQL语句处理器
2731
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}), //预备工作
@@ -36,50 +40,15 @@
3640
@Slf4j
3741
public class DataScopeInterceptor extends AbstractSqlParserHandler implements Interceptor {
3842

39-
40-
private static final String ANTI_QUOTATION_MARKS = "`";
41-
42-
/**
43-
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
44-
*/
45-
private static final String STR_TO_DATE = "str_to_date";
46-
47-
/**
48-
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
49-
*/
50-
private static final String TO_DATE = "to_date";
51-
52-
53-
/**
54-
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
55-
*/
56-
private static final String STR_TO_DATE_FMT = "%Y-%m-%d";
57-
58-
/**
59-
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
60-
*/
61-
private static final String TO_DATE_FMT = "YYYY-MM-DD";
62-
63-
/**
64-
* Mysql 中 DATEDIFF(date1, date2) => Dm DATEDIFF(datepart,date1,date2)
65-
* Mysql 中计算时间边界 DATEDIFF(date1, date2) => Dm DATEDIFF(datepart,date1,date2)
66-
* datepart 取值:
67-
* DD:返回两个日期间隔的天数
68-
* MONTH:
69-
* WK:
70-
* MS:
71-
*/
72-
private static final String DATEDIFF = "datediff";
73-
7443
/**
7544
* 如果是identity,需要转为大写并加引号 todo
7645
*/
7746
private static final String IDENTITY = "identity";
7847
private static final String SLASH_IDENTITY_SLASH = "\"identity\"";
7948

80-
private static final String DATEDIFF_DATEPART = "datediff(DD,";
81-
private static final String SCHEMA_TABLES = "information_schema.tables";
82-
private static final String SCHEMA_COLUMNS = "information_schema.columns";
49+
50+
@Autowired
51+
private List<SqlHandler> sqlHandlers;
8352

8453

8554
@Override
@@ -100,21 +69,7 @@ public Object intercept(Invocation invocation) throws Throwable {
10069
Object result = invocation.proceed();
10170
Object o = this.formatResultMap(result);
10271
return this.formatResultMap(o);
103-
}
104-
105-
106-
//else if(handler instanceof ParameterHandler){
107-
// ParameterHandler parameterHandler = (ParameterHandler) handler;
108-
// PreparedStatement ps = (PreparedStatement) invocation.getArgs()[0];
109-
//
110-
// // 反射获取 BoundSql 对象,此对象包含生成的sql和sql的参数map映射
111-
// Field boundSqlField = parameterHandler.getClass().getDeclaredField("boundSql");
112-
// boundSqlField.setAccessible(true);
113-
// BoundSql boundSql = (BoundSql) boundSqlField.get(parameterHandler);
114-
//
115-
// List<String> paramNames = new ArrayList<>();
116-
//}
117-
else {
72+
} else {
11873
log.info("无法判断Mybatis执行类:{}", handler.getClass().getName());
11974
}
12075

@@ -124,7 +79,7 @@ public Object intercept(Invocation invocation) throws Throwable {
12479
/**
12580
* 处理返回结果集
12681
*
127-
* @param result
82+
* @param result 入参
12883
*/
12984
private Object formatResultMap(Object result) {
13085
if (ObjectUtils.isEmpty(result)) {
@@ -160,24 +115,9 @@ private Object formatResultMap(Object result) {
160115
*/
161116
private String modifySql(String sql) {
162117
String transSql = sql.toLowerCase();
163-
//判断Sql中是否含有
164-
if (transSql.contains(ANTI_QUOTATION_MARKS)) {
165-
log.info("达梦数据库适配-去除反引号[`]!");
166-
transSql = transSql.replaceAll(ANTI_QUOTATION_MARKS, "\"");
167-
168-
}
169-
//将 MYSQL 中 str_to_date() 函数替换为达梦 to_date(),注意时间格式掩码
170-
if (transSql.contains(STR_TO_DATE)) {
171-
log.info("达梦数据库适配-替换字符转化时间函数str_to_date()");
172-
transSql = transSql.replaceAll(STR_TO_DATE_FMT, TO_DATE_FMT).replaceAll(STR_TO_DATE, TO_DATE);
118+
for (SqlHandler sqlHandler : sqlHandlers) {
119+
transSql = sqlHandler.handle(transSql);
173120
}
174-
175-
// Datediff
176-
if (transSql.contains(DATEDIFF)) {
177-
log.info("达梦数据库适配-替换字符转化时间函数DATEDIFF()");
178-
transSql = transSql.replaceAll(DATEDIFF + "\\(", DATEDIFF_DATEPART);
179-
}
180-
181121
return transSql;
182122

183123
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package ooo.github.io.dm.convert.sql;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.stereotype.Service;
5+
6+
/**
7+
* 达梦针对mysql的函数处理
8+
*
9+
* @author kaiqin
10+
*/
11+
@Slf4j
12+
@Service
13+
public class FunctionHandler implements SqlHandler {
14+
15+
/**
16+
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
17+
*/
18+
private static final String STR_TO_DATE = "str_to_date";
19+
20+
/**
21+
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
22+
*/
23+
private static final String TO_DATE = "to_date";
24+
25+
26+
/**
27+
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
28+
*/
29+
private static final String STR_TO_DATE_FMT = "%Y-%m-%d";
30+
31+
/**
32+
* Mysql 的字符转换为日期 -》 Dm to_date(char,fmt)
33+
*/
34+
private static final String TO_DATE_FMT = "YYYY-MM-DD";
35+
36+
/**
37+
* Mysql 中 DATEDIFF(date1, date2) => Dm DATEDIFF(datepart,date1,date2)
38+
* Mysql 中计算时间边界 DATEDIFF(date1, date2) => Dm DATEDIFF(datepart,date1,date2)
39+
* datepart 取值:
40+
* DD:返回两个日期间隔的天数
41+
* MONTH:
42+
* WK:
43+
* MS:
44+
*/
45+
private static final String DATEDIFF = "datediff";
46+
47+
private static final String DATEDIFF_DATEPART = "datediff(DD,";
48+
49+
@Override
50+
public String handle(String sql) {
51+
//将 MYSQL 中 str_to_date() 函数替换为达梦 to_date(),注意时间格式掩码
52+
if (sql.contains(STR_TO_DATE)) {
53+
log.info("达梦数据库适配-替换字符转化时间函数str_to_date()");
54+
sql = sql.replaceAll(STR_TO_DATE_FMT, TO_DATE_FMT).replaceAll(STR_TO_DATE, TO_DATE);
55+
}
56+
57+
if (sql.contains(DATEDIFF)) {
58+
log.info("达梦数据库适配-替换字符转化时间函数DATEDIFF()");
59+
sql = sql.replaceAll(DATEDIFF + "\\(", DATEDIFF_DATEPART);
60+
}
61+
return sql;
62+
}
63+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package ooo.github.io.dm.convert.sql;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.stereotype.Service;
5+
6+
import java.util.Objects;
7+
8+
/**
9+
* 关键字处理,达梦的关键字目前已知的有desc,type
10+
* 需要在业务侧加上@TableField(value = "`desc`")
11+
*
12+
* <p>
13+
* select id,code,parent_code,NAME,"DESC","TYPE",sort,table_name,table_desc,create_by,create_time,update_by,update_time from tb_aaa
14+
* 对于达梦数据库来说,关键字需要双引号包裹起来,并且需要转为大写(mysql只需要用``包裹即可)
15+
*
16+
* @author kaiqin
17+
*/
18+
@Service
19+
@Slf4j
20+
public class KeywordHandler implements SqlHandler {
21+
22+
private static final String ANTI_QUOTATION_MARKS = "`";
23+
24+
private static final String TYPE_LOWER_CASE = "\"type\"";
25+
26+
private static final String DESC_LOWER_CASE = "\"desc\"";
27+
28+
private static final String DESC_UPPER_CASE = "\"DESC\"";
29+
30+
private static final String TYPE_UPPER_CASE = "\"TYPE\"";
31+
32+
@Override
33+
public String handle(String sql) {
34+
if (sql == null) {
35+
return null;
36+
}
37+
38+
if (sql.contains(ANTI_QUOTATION_MARKS)) {
39+
log.info("达梦数据库适配-去除反引号[`]!");
40+
sql = sql.replaceAll(ANTI_QUOTATION_MARKS, "\"");
41+
String[] sqlSplit = sql.split("");
42+
StringBuilder finalSql = new StringBuilder();
43+
boolean start = false;
44+
log.info("达梦数据库关键字适配-关键字转写");
45+
for (String each : sqlSplit) {
46+
if (Objects.equals(each, "\"")) {
47+
start = !start;
48+
}
49+
if (start) {
50+
finalSql.append(each.toUpperCase());
51+
} else {
52+
finalSql.append(each);
53+
}
54+
}
55+
return finalSql.toString();
56+
}
57+
return sql;
58+
}
59+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package ooo.github.io.dm.convert.sql;
2+
3+
/**
4+
* sql处理器
5+
*
6+
* @author kaiqin
7+
*/
8+
public interface SqlHandler {
9+
10+
/**
11+
* 处理sql
12+
*
13+
* @param sql 返回处理后的sql
14+
* @return 处理后的sql
15+
*/
16+
String handle(String sql);
17+
}

0 commit comments

Comments
 (0)