springboot~mybatis-plus的DynamicTableNameInnerInterceptor实现分表

Posted 敢于对过去告一个段落,才有信心掀开新的篇章!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot~mybatis-plus的DynamicTableNameInnerInterceptor实现分表相关的知识,希望对你有一定的参考价值。

超轻量级

DynamicTableNameInnerInterceptor是mybatis-plug的一个拦截器插件,可以自己定义需要拦截的表单,然后对它进行加工,这时mybatis-plus就会把SQL代码的表名加上你的这个装饰。

封装的思想

我们通常把mybatis做成一个包,公司其它同事直接使用咱们的包,包里会统一定义数据基类数据分页数据脱敏、审计字段填充等特性,开发人员不需要关注这些内容,这些内容会被自己注册;或者人开发人员可以直接继承它们,直接使用即可。

  • 插件注册器
@Configuration
public class MybatisPlusConfig implements ApplicationContextAware 

	ApplicationContext applicationContext;

	/**
	 * 拦截器
	 */
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() 
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		// 分页插件, 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型
		interceptor.addInnerInterceptor(new LindPaginationInnerInterceptor());
		// 防止全表更新与删除
		interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
		// 加载个性化的分表配置,它可能是用户在当前项目定义的,然后我们统一对它们进行装配
		Optional.ofNullable(applicationContext.getBeanNamesForType(DynamicTableNameInnerInterceptor.class))
				.ifPresent(o -> 
					for (String beanName : o) 
						DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = applicationContext
								.getBean(beanName, DynamicTableNameInnerInterceptor.class);
						interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
					
				);
		return interceptor;
	
.....

通过上面的代码我们知道,在外部定义的DynamicTableNameInnerInterceptor对象,会被自动的注册到mybatis-plus的组件中,开发人员在具体项目里不需要再次注册。

  • 开发人员在项目中定义一个t_log表,按时间进行分表
	@Bean
	public DynamicTableNameInnerInterceptor tableNamePlusInterceptor() 
		DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
		HashMap<String, TableNameHandler> map = new HashMap<String, TableNameHandler>();

		map.put("t_log", new DaysTableNameParser());

		dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
		return dynamicTableNameInnerInterceptor;
	

代码的测试

	@Test(expected = BadSqlGrammarException.class)
	public void insertLog() 
		TLog log = new TLog();
		log.setMessage("测试");
		logDao.insert(log);
	

生成的sql代码如下

[main] DEBUG com.lind.mybatis.dao.LogDao.insert - ==>  Preparing: INSERT INTO t_log_20230524 ( id, message, create_by, create_time, update_by, update_time, del_flag ) VALUES ( ?, ?, ?, ?, ?, ?, ? )

需要注意的是,无论是sharding-jdbc还是mybatis-plus-DynamicTableNameInnerInterceptor组成的分表,咱们都需要提前把数据表建立出来,他们这些组件是不会自动建表的。

SpringBoot使用·下篇(SpringBoot集成MyBatis+日志打印+MyBatis-plus)

文章目录

SpringBoot的使用

我们在SpringBoot使用·上篇说到了SpringBoot注解、SpringBoot集成JDBC、SpringBoot集成druid(德鲁伊)数据源和sql监控,这篇文章我们会写到SpringBoot和MyBatis的故事。

SpringBoot集成MyBatis

1.首先我们要在SpringBoot的基础上集成MyBatis的相关jar

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>

2.在application文件中配置数据源信息

#MyBtais配置
mybatis:
  type-aliases-package: com.cwd.springboot.bean #开启别名扫描
  mapper-locations: classpath:mapper/*Mapper.xml
  configuration:
    map-underscore-to-camel-case: true #开启驼峰转换
    cache-enabled: true #开启二级缓存

这时我们就可以使用MyBatis了。一个查询的案例奉上:

(1)创建一个t_user表

CREATE TABLE `t_user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8

(2)创建一个User的实体类,并加上相关的注解

import org.apache.ibatis.type.Alias;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
@Alias("User")
public class User 
    private Integer id;
    private String name;
    private Integer age;
    private Date birthday;

    public Integer getId() 
        return id;
    

    public void setId(Integer id) 
        this.id = id;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public Integer getAge() 
        return age;
    

    public void setAge(Integer age) 
        this.age = age;
    

    public Date getBirthday() 
        return birthday;
    

    public void setBirthday(Date birthday) 
        this.birthday = birthday;
    

    @Override
    public String toString() 
        return "User" +
                "id=" + id +
                ", name='" + name + '\\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '';
    

(3)创建查询的dao/mapper接口以及sql映射文件

import com.cwd.SpringBootDemo.bean.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserDao 
    User findUserById(int id);

<?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:接口存放路径 类路径-->
<mapper namespace="com.cwd.SpringBootDemo.dao.UserDao">

    <select id="findUserById" resultType="com.cwd.SpringBootDemo.bean.User">
        select name,age,birthday from t_user where id = #id
    </select>
</mapper>

(4)在主类(SpringBoot启动类)上加入一个@MapperScan的注解,它的作用是指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类。

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.cwd.SpringBootDemo.dao")
public class SpringBootDemoApplication 

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


(5)创建调用接口的服务层

import com.cwd.SpringBootDemo.bean.User;
import com.cwd.SpringBootDemo.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Transactional/*开启事务管理*/
public class UserService 
    @Autowired
    UserDao userDao;

    public User findUserById(int id) 
        return userDao.findUserById(id);
    

(6)测试

import com.cwd.SpringBootDemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringBootDemoApplicationTests 

	@Autowired
	UserService userService;

	@Test
	void contextLoads() 
		System.out.println(userService.findUserById(3));
	


日志打印

在application文件中加入日志的配置即可

#日志打印
logging:
  level:
    com.cwd.SpringBootDemo.dao: trace  #等级 只打印操作数据的接口相关日志
  file:
    name: E:\\\\log\\\\log.log #日志存放的位置

MyBatis-plus的简单搭建

关于MyBtais-plus的详细学习最好还是依赖官方文档进行MyBatis-plus官网这里我们只完成一个简单的搭建。我们还是使用上面MyBtais的类和表,MyBtais的所有东西都不用动,当然MyBatis-plus是包含了MyBatis的一切的。

1.导入MyBatis-plus的相关jar。

<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.4.1</version>
</dependency>

2.用dao接口类继承BaseMapper,泛型是实体类。

@Repository
public interface UserDao extends BaseMapper<User> 


3.如果要操作的表名和类名不一致,我们需要通过@TableName注解解决

@Component
@Alias("User")
@TableName("t_user")
public class User
    

4.调用接口类,MyBatis-plus封装了很多的操作数据库的sql语句,基本都是单张表操作,直接调用即可。

@Service
@Transactional/*开启事务管理*/
public class UserService 
    @Autowired
    UserDao userDao;

    public List<User> findUser() 
        return userDao.selectList(null);
    

5.测试

@SpringBootTest
class SpringBootDemoApplicationTests 

	@Autowired
	UserService userService;

	@Test
	void contextLoads() 
		System.out.println(userService.findUser());
	


重要得事情再说一遍:MyBatis-plus的学习最好按照官网的文档学习!!!

以上是关于springboot~mybatis-plus的DynamicTableNameInnerInterceptor实现分表的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 整合 MyBatis-Plus 入门体验

Mybatis-Plus

如何整合 springboot + mybatis-plus(系列一)

SpringBoot使用·下篇(SpringBoot集成MyBatis+日志打印+MyBatis-plus)

SpringBoot使用·下篇(SpringBoot集成MyBatis+日志打印+MyBatis-plus)

springboot整合mybatis-plus