java:mybatis查询时自动添加tenantId和deleted查询条件

# 参考资料

https://blog.csdn.net/chenhz2284/article/details/139606486?spm=1001.2014.3001.5502

# 示例代码

【pom.xml】

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.3.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.3.12.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3.1</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-core</artifactId>
    <version>3.4.3.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.49</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.3.0</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.12</version>
</dependency>

【application.properties】

server.port=8080
spring.application.name=myMyBatisPlus

management.server.port=7001
management.endpoints.web.exposure.include=*

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.44.228:3306/test
spring.datasource.username=root
spring.datasource.password=root

mybatis-plus.mapper-locations=classpath:mapper/*.xml

spring.shardingsphere.props.sql.show=true

【mapper/UserMapper.xml】

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chz.myMyBatisPlus.persistence.mapper.UserMapper">

    <resultMap id="user" type="com.chz.myMyBatisPlus.persistence.po.User">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="sex" property="sex" />
        <result column="age" property="age" />
        <result column="email" property="email" />
        <result column="tenant_id" property="tenantId" />
        <result column="deleted" property="deleted" />
    </resultMap>

    <select id="selectUserById" parameterType="long" resultMap="user">
        SELECT * FROM chz_user
        WHERE id = #{id}
    </select>

</mapper>

【TestMybatisController.java】

package com.chz.myMyBatisPlus.controller;

@Slf4j
@RestController
@RequestMapping("/mybatis")
public class TestMybatisController {

    @Resource
    private UserMapper userMapper;

    @GetMapping("/selectAllUser")
    public List<User> selectAllUser() {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        List<User> users = userMapper.selectList(queryWrapper);
        return users;
    }
}

【MyBatisValidInterceptor.java】

package com.chz.myMyBatisPlus.interceptor;

@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, 
                                                                    ResultHandler.class}),
})
@Component
@Slf4j
public class MyBatisValidInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable
    {
        Object[] args = invocation.getArgs();
        MappedStatement mappedStatement = (MappedStatement) args[0];
        String sqlKey = mappedStatement.getId();

        String sql = getSqlByInvocation(invocation);
        if (StringUtils.isBlank(sql)) {
            return invocation.proceed();
        }
        if (sqlKey.endsWith("Global")) {
            return invocation.proceed();
        }

        log.info("before ::: " + sql);
        sql = parseSql(sql);
        log.info("after ::: " + sql);

        resetSql2Invocation(invocation, sql);
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object obj) {
        return Plugin.wrap(obj, this);
    }

    @Override
    public void setProperties(Properties arg0) {
    }

    public static String parseSql(String sql) throws JSQLParserException
    {
        Select stmt = (Select) CCJSqlParserUtil.parse(sql);

        PlainSelect plainSelect = (PlainSelect)stmt.getSelectBody();
        Expression whereExpression = plainSelect.getWhere();

        whereExpression = SqlParserUtils.andTenantIdExpression(whereExpression, 1L);
        whereExpression = SqlParserUtils.andDeletedExpression(whereExpression, false);

        plainSelect.setWhere(whereExpression);
        return plainSelect.toString();
    }

    private String getSqlByInvocation(Invocation invocation) {
        final Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        Object parameterObject = args[1];
        BoundSql boundSql = ms.getBoundSql(parameterObject);
        return boundSql.getSql();
    }

    private void resetSql2Invocation(Invocation invocation, String sql) throws SQLException {
        final Object[] args = invocation.getArgs();
        MappedStatement statement = (MappedStatement) args[0];
        Object parameterObject = args[1];
        BoundSql boundSql = statement.getBoundSql(parameterObject);
        MappedStatement newStatement = newMappedStatement(statement, new BoundSqlSqlSource(boundSql));
        MetaObject msObject = MetaObject.forObject(newStatement, new DefaultObjectFactory(),
                new DefaultObjectWrapperFactory(), new DefaultReflectorFactory());
        msObject.setValue("sqlSource.boundSql.sql", sql);
        args[0] = newStatement;
    }

    private MappedStatement newMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
        MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource,
                ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.keyGenerator(ms.getKeyGenerator());
        if (ms.getKeyProperties() != null && ms.getKeyProperties().length != 0) {
            StringBuilder keyProperties = new StringBuilder();
            for (String keyProperty : ms.getKeyProperties()) {
                keyProperties.append(keyProperty).append(",");
            }
            keyProperties.delete(keyProperties.length() - 1, keyProperties.length());
            builder.keyProperty(keyProperties.toString());
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(ms.getResultMaps());
        builder.resultSetType(ms.getResultSetType());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());

        return builder.build();
    }

    class BoundSqlSqlSource implements SqlSource {

        private BoundSql boundSql;

        public BoundSqlSqlSource(BoundSql boundSql) {
            this.boundSql = boundSql;
        }

        @Override
        public BoundSql getBoundSql(Object parameterObject) {
            return boundSql;
        }
    }
}

【UserMapper.java】

package com.chz.myMyBatisPlus.persistence.mapper;

@Mapper
public interface UserMapper extends BaseMapper<User>
{
}

【User.java】

package com.chz.myMyBatisPlus.persistence.po;

@Data
@TableName(value = "chz_user")
public class User 
{
    private Long id;
    private String name;
    private String sex;
    private Integer age;
    private String email;
    private Long tenantId;
    private Boolean deleted;
}

【SqlParserUtils.java】

package com.chz.myMyBatisPlus.utils;

@Slf4j
public class SqlParserUtils
{
    public static BinaryExpression andTenantIdExpression(Expression where, Long tenantId)
    {
        EqualsTo equalsTo = new EqualsTo();
        equalsTo.setLeftExpression(new Column("tenant_id"));
        equalsTo.setRightExpression(new LongValue(tenantId));
        if (null != where) {
            if (where instanceof OrExpression) {
                return new AndExpression(equalsTo, new Parenthesis(where));
            } else {
                return new AndExpression(equalsTo, where);
            }
        }
        return equalsTo;
    }

    public static Expression andDeletedExpression(Expression where, Boolean deleted)
    {
        IsBooleanExpression isBooleanExpression = new IsBooleanExpression();
        isBooleanExpression.setLeftExpression(new Column("deleted"));
        isBooleanExpression.setIsTrue(deleted);
        if (null != where) {
            if (where instanceof OrExpression) {
                return new AndExpression(isBooleanExpression, new Parenthesis(where));
            } else {
                return new AndExpression(isBooleanExpression, where);
            }
        }
        return isBooleanExpression;
    }
}

【MyMyBatisPlusTest.java】

package com.chz.myMyBatisPlus;

@SpringBootApplication
public class MyMyBatisPlusTest {

    public static void main(String[] args)
    {
        SpringApplication.run(MyMyBatisPlusTest.class, args);
    }
}

启动【MyMyBatisPlusTest】,然后访问【http://localhost:8080/mybatis/selectAllUser】
在这里插入图片描述

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈鸿圳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值