SpringBoot-JPA 支持分表

简介

- JPA Entity对象继承,通过@Inheritance配置,有三种方式SINGLE_TABLE、TABLE_PER_CLASS、JOINED,这里不作赘述。
- Entity对象的分库分表操作
    - 分库,为了管理DB的连接数,建议通过入口的分流,将不同DB的数据分流到不同的应用;
    - 分表,这是本文关注的主要问题,目标是调用JPA时不需要关心是否分表以及映射的规则,即分表对于Entity操作层是透明的;主要的步骤如下:
          - 对象声明
          - 实现JPA interceptor 拦截器
          - 加载拦截器

对象声明

- 数据对象的基类,引入了@MappedSuperclass,如下面的样例
@MappedSuperclass
class UserBase {

	@Id
	private Long id;

	private String name;

	private int age;
... ... 
}
- 数据对象,继承基类,使用[@Entity](https://my.oschina.net/u/1260961),如下面的样例
 //模板表,用于JPA代码编写
@Entity
@Table(name = "t_user")
public class User extends UserBase { ... ...}
 //id是0或者偶数的数据分表,用于配置了hibernate.ddl-auto时维护库表结构,不会出现在JPA相关代码中
@Entity
@Table(name = "t_user_0")
public class User0 extends UserBase { ... ...}
//与User0对应,id是奇数的数据分表
@Entity
@Table(name = "t_user_1")
public class User1 extends UserBase { ... ...}
// 数据对象操作类声明
public interface UserDao extends CrudRepository<User, Long> {}

JPA interceptor 拦截器

- 声明
import org.hibernate.EmptyInterceptor;

public class MyInterceptor extends EmptyInterceptor {
- 推荐使用ThreadLocal缓存业务对象类型和ID
static class Cached {
	Class<?> clazz;
	Serializable id;
	Cached(Class<?> clazz, Serializable id) {
		super();
		this.clazz = clazz;
		this.id = id;
	}
 ... ... //自动生成的hashCode、equals方法
}
- 重载如下的方法onLoad、onSave、getEntity,调用ThreadLocal.set
- 重载onPrepareStatement方法,示意代码如下
Cached id = threadLocal.get();
threadLocal.remove();
if(id == null) {
	return sql;
}
if(id.clazz == User.class) {
	long offset = ((Long)id.id).longValue() / 2;
	return sql.replace("t_user", "t_user_" + offset);
}

加载拦截器 Application.yml

spring:
    jpa:
        properties:
               hibernate:
                      ejb:
                            interceptor: [拦截器类名]

转载于:https://my.oschina.net/u/1053238/blog/1611773

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值