MyBatis-Plus动态更改查询的表名或字段名

2023-12-13 22:40:14

部分业务可能会需要根据参数不同而查询不同的表,或者查询不同的字段。使用MyBatis-Plus可以很方便地实现这种需求,甚至不需要使用.xml文件。
三张数据表user、user1、user2内容都如下:

idnameagesex
1张三181
2李四<null><null>
3<null><null><null>

方式一

UserMapper.java中使用@Select注解,动态改变要查询的表或字段:
UserMapper.java

public interface UserMapper extends BaseMapper<User> {
	@Select("select ${column1} from ${table1} where ${column2} = #{variable1}")
	String test(@Param("column1") String column1,
	            @Param("table1") String table1,
	            @Param("column2") String column2,
	            @Param("variable1") String variable1);
}

使用Test调用测试,service层实现类的代码如下:

@Override
public String test() {
	return baseMapper.test("name", "user", "id", "1");
}

得到控制台打印输出:

JDBC Connection [HikariProxyConnection@530131514 wrapping com.mysql.cj.jdbc.ConnectionImpl@30bf26df] will not be managed by Spring
==>  Preparing: select name from user where id = ?
==> Parameters: 1(String)
<==    Columns: name
<==        Row: 张三
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f362135]
张三

这种方式实现了动态更改要查询的表名或字段,但是必须要注意

  • @Select注解中如果将表名、字段名作为传参,必须使用$不能使用#,因为#会给传递的参数带上引号导致sql语法错误
  • @Param只有在仅一个参数且名称相同时可以省略,否则必须带上

方式二

使用拦截器的方式,将表名修改掉。在任意位置建一个MyBatis-Plus的配置类:

package cn.ly.mptest.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author : Liuyuan
 */
@Configuration
public class MybatisPlusConfig {
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
		dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
			String newTable = "user1";
			return newTable;
		});
		interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
		return interceptor;
	}
}

改变返回的newTable的值,即可更换查询的表。在Test中调用:

@Test
void test() {
	User byId = userService.getById(1);
	System.out.println(byId.getName());
}

可以看到输出台打印的真正查询语句:

JDBC Connection [HikariProxyConnection@1958242673 wrapping com.mysql.cj.jdbc.ConnectionImpl@1f9d4b0e] will not be managed by Spring
==>  Preparing: SELECT id,name,age,sex FROM user1 WHERE id=?
==> Parameters: 1(Integer)
<==    Columns: id, name, age, sex
<==        Row: 1, 张三1, null, null
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7d979d34]
张三1

可以看到虽然使用的是User实体类,但是依然查询的from user1
这种方式不同MyBatis-Plus版本会有不同写法,可以参考这两篇博客:
博客1
博客2

文章来源:https://blog.csdn.net/lxyker/article/details/134829282
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。