mybatis/mybatis-plus模糊查询语句特殊字符转义拦截器的实现

在开发中,我们通常会遇到这样的情况。用户在录入信息是录入了‘%’,而在查询时无法精确匹配‘%’。究其原因,‘%’是MySQL的关键字,如果我们想要精确匹配‘%’,那么需要对其进行转义,本文就详细的介绍一下

目录

  • 1.使用mybatis提供的拦截器拦截所有的查询请求。
  • 2.定义SQL语句转义模板,分别对Map和Object对象进行处理

mybatis/mybatis-plus模糊查询语句特殊字符转义拦截器

在开发中,我们通常会遇到这样的情况。用户在录入信息是录入了‘%',而在查询时无法精确匹配‘%'。究其原因,‘%'是MySQL的关键字,如果我们想要精确匹配‘%',那么需要对其进行转义。

1.使用mybatis提供的拦截器拦截所有的查询请求。

具体实现在代码中均有注释

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;

import org.apache.ibatis.executor.Executor;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.plugin.*;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.RowBounds;

import java.util.*;

/**

 * mybatis/mybatis-plus模糊查询语句特殊字符转义拦截器

 *

 * @author lieber

 */

@Intercepts({ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})

@Slf4j

public class MybatisLikeSqlInterceptor implements Interceptor {

    /**

     * SQL语句like

     */

    private final static String SQL_LIKE = " like ";

    /**

     * SQL语句占位符

     */

    private final static String SQL_PLACEHOLDER = "?";

    /**

     * SQL语句占位符分隔

     */

    private final static String SQL_PLACEHOLDER_REGEX = "\\?";

    /**

     * 所有的转义器

     */

    private static Map converterMap = new HashMap<>(4);

    static {

        converterMap.put(Map.class, new MapLikeSqlConverter());

        converterMap.put(Object.class, new ObjectLikeSqlConverter());

    }

    @Override

    public Object intercept(Invocation invocation) throws Throwable {

        Object[] args = invocation.getArgs();

        MappedStatement statement = (MappedStatement) args[0];

        Object parameterObject = args[1];

        BoundSql boundSql = statement.getBoundSql(parameterObject);

        String sql = boundSql.getSql();

        this.transferLikeSql(sql, parameterObject, boundSql);

        return invocation.proceed();

    }

    @Override

    public Object plugin(Object target) {

        return Plugin.wrap(target, this);

    }

    @Override

    public void setProperties(Properties arg0) {

    }

    /**

     * 修改包含like的SQL语句

     *

     * @param sql             SQL语句

     * @param parameterObject 参数对象

     * @param boundSql        绑定SQL对象

     */

    private void transferLikeSql(String sql, Object parameterObject, BoundSql boundSql) {

        if (!isEscape(sql)) {

            return;

        }

        sql = sql.replaceAll(" {2}", " ");

        // 获取关键字的个数(去重)

        Set fields = this.getKeyFields(sql, bou

你可能感兴趣的:(mysql,数据库,database)