# 参考资料
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】