手写jpa自动创建数据库表

背景

最近用sqlite数据库开发本地应用,后端使用的springboot + jpa。现在遇到sqlite对单条sql中select union 最大限制为500,而jpa底层把所有表中的列作为 一个select union 查询并且超过了数据库的最大限制,为了方便以后的开发,运维,所以需要实现jpa自动创建表的功能,减少开发和运维的工作量。

实现逻辑

创建一个类,实现 BeanPostProcessor

为什么要实现BeanPostProcessor呢,因为spring在创建bean的时候,先创建的BFPP,再创建BPP,然后创建内部Bean,最后再创建工程中使用的Bean,使用BPP就是为了防止有冲突出现。

@Component
@Slf4j
@Order(Integer.MIN_VALUE)
public class ComplementBeanPostProcessor implements BeanPostProcessor {
   
   
在jpa的实体类上实现自定义接口

JpaEntryDefinition接口为一个空定义接口,只是为了标识JPA的实体,源码能力强的可以通过@Entity加@Table注解获取对应的实体类

@Data
@Entity
@Table(name = "table_name")
public class TableName implements JpaEntryDefinition{
   
   
}
创建@PostConstruct中的方法

@PostConstruct在ComplementBeanPostProcessor初始化的时候会被调用

@PostConstruct
public void init(){
   
   
	// 初始化数据库表
    verifyAndComplementTable();
}
增加列或者创建表

java类型与数据库类型关系映射

public static final Map<String,String> classTypeMappingColumnType = Maps.newHashMap();
static{
   
   
    classTypeMappingColumnType.put("int","integer");
    classTypeMappingColumnType.put("java.lang.Integer","integer");
    classTypeMappingColumnType.put("java.lang.String","varchar(255)");
    classTypeMappingColumnType.put("long","Long");
    classTypeMappingColumnType.put("java.lang.Long","Long");
}
private void verifyAndComplementTable() {
   
   
    log.info("start----------------->校验并完善数据库表结构");
    Set<Class<?>> tableList = ReflectUtils.getChildreClass(JpaEntryDefinition.class);
    validJpaEntryDefinition(tableList);
    //获取数据库中所有的表
    List<String> existTableNme = jdbcTemplate.queryForList("select name from sqlite_master where type='table' order by name ",String.class);
    Map<String, String> existTableNmeMap = existTableNme.stream().collect(Collectors.toMap(Function.identity(), Function.identity()));
    for(Class clazz : tableList){
   
   
        Table tableAnno = (Table)clazz.getAnnotation(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值