WhiteDG / mybatis-crypto

🔐 A mybatis-based crypto plugin
Apache License 2.0
72 stars 20 forks source link

疑似PageHelper会导致无法进入本插件的拦截器 #17

Open paulzhn opened 11 months ago

paulzhn commented 11 months ago

https://github.com/pagehelper/Mybatis-PageHelper 这个插件似乎会影响责任链,Google可以搜到很多反馈,如http://xtong.tech/2018/08/01/MyBatis%E6%8B%A6%E6%88%AA%E5%99%A8%E5%9B%A0pagehelper%E8%80%8C%E5%A4%B1%E6%95%88%E7%9A%84%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3/ 。 该仓库的作者在 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Interceptor.md 给了一个教程,不知道作者是否可以做一下兼容?

我不太懂Java底层的设计,不知道他们那种做法是不是合理...但是因为这个pageHelper还比较热门,已经是屎山里埋得比较深了,如果不兼容的话可能很多项目都会有问题。🥲

WhiteDG commented 11 months ago
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

我用这个版本试了一下是正常的,可以提供一下你具体使用的是哪个版本以及如何配置的吗,如果有个可以复现的 demo 就更好了。

wkinged commented 8 months ago

使用

com.github.pagehelper
        <artifactId>pagehelper</artifactId>
        <version>5.1.8</version>
    </dependency>

XXX_COUNT 查总行数正常,但执行查询数据时,参数编程Hashmap,丢失注解信息,在这里返回,不加密了 image

WhiteDG commented 8 months ago

@wkinged 你的意思是执行 COUNT SQL 时条件参数正常(应该是个实体类?),执行数据查询 SQL 时参数变成了 HashMap 导致查询时没有加密,查不到对应的数据吗?

因为我不知道你的代码具体是怎么写的,所以我只能根据你提供的版本信息然后按我自己的理解写代码测试,但是没有没有出现你提到的问题。所以如果你可以提供一个最小可复现的 demo 的话,就比较方便我定位以及解决问题。

wkinged commented 8 months ago

懂了,是我们没配置好, 我没有加(@Param("et")、yml没配置 mapped-key-prefixes: et, encrypted List<User> selectList(@Param("et") User user); 不加@Param("et"),pageHelper第二次查询List时,会把User编程hashMap,导致无法识别加密属性, 可通过ConfigurationCustomizer自定义插件顺序,把加密插件加前面即可(这样需要修改大量代码) 大神,看看能不能优化一下。

WhiteDG commented 8 months ago

可以试试修改 PageHelper 插件的注入方式,这样不需要修改大量代码。

先排除掉 pagehelper-spring-boot-starter 自动注入 PageHelperAutoConfiguration

@SpringBootApplication(exclude = {PageHelperAutoConfiguration.class})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

然后用 ConfigurationCustomizer 配置分页插件(参考 PageHelperAutoConfiguration)

import com.github.pagehelper.PageInterceptor;
import com.github.pagehelper.autoconfigure.PageHelperProperties;
import org.apache.ibatis.session.Configuration;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import java.util.Properties;

@org.springframework.context.annotation.Configuration
@EnableConfigurationProperties({PageHelperProperties.class})
@AutoConfigureAfter({MybatisAutoConfiguration.class})
public class PageHelperAutoConfiguration {

    @Autowired
    private PageHelperProperties properties;

    @Bean
    @ConfigurationProperties(prefix = PageHelperProperties.PAGEHELPER_PREFIX)
    public Properties pageHelperProperties() {
        return new Properties();
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        PageInterceptor interceptor = new PageInterceptor();
        Properties properties = new Properties();
        //先把一般方式配置的属性放进去
        properties.putAll(pageHelperProperties());
        //在把特殊配置放进去,由于close-conn 利用上面方式时,属性名就是 close-conn 而不是 closeConn,所以需要额外的一步
        properties.putAll(this.properties.getProperties());
        interceptor.setProperties(properties);

        return new ConfigurationCustomizer() {
            @Override
            public void customize(Configuration configuration) {
                configuration.addInterceptor(interceptor);
            }
        };
    }
}
wkinged commented 8 months ago

如何控制MyBatisCrypto插件是在pagehelper插件前面呢? MyBatisCryptoAutoConfiguration也是自动装配的, 总不能在PageHelperAutoConfiguration 中配置MyBatisCrypto插件吧?

WhiteDG commented 8 months ago

myBatis-crypto 插件没有指定顺序,是通过 @bean 注入的,mybatis-spring-boot-starter 在配置插件的时候,是先执行 ConfigurationCustomizer 再添加 @bean 注入的插件,这样就可以保证 myBatis-crypto 插件执行顺序早于 PageHelper

mybatis-spring-boot-starter 具体代码位置: