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

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

目录

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<Class, AbstractLikeSqlConverter> 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<String> fields = this.getKeyFields(sql, bou

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值