通过手动创建hibernate工厂,自动生成表,完成数据库备份还原功能
最近做toB、toG业务,普遍要去适配各种国产数据库,所以不得不用hibernate,过去这么多年一直都是用mybatis+mysql,现在重拾hibernate,专注跨数据库,感兴趣的加关注。
需求背景:
最近做一个数据库备份还原功能,需要支持跨库同步,比如mysql的数据及表结构整库批量同步到SqlServer(虽然Navicat有此功能,但是Navicat不支持一些新的国产数据库,况且,这个Navicat不能集成到项目里,用户使用不方便)。
功能分析:
1、需要同步表结构,不同的数据库DDL语句不兼容性。但是,hibernate框架中,entity已经定义了表结构,hibernate会帮我们适配各种数据库,所以不用备份表结构(sql: create table xxx …),直接通过hibernate在数据库生成表;
2、常见的数据备份是备份insert into table … 这样的sql语句。这样做,备份文件体积大,且不是批量插入,性能一般,特殊格式的字段在不同数据库还存在兼容问题。所以我们可以通过hibernate,只备份数据,将数据转为json格式存储,然后用hibernate将数据入库。
实现思路:
1、通过entityManager获取实体entity;
2、通过entity查询对应表所有数据;
3、解析前端传参,组装新的数据库链接;
4、根据数据库链接和获取到的实体,创建hibernate工厂(通过entity创建表);
5、再次通过遍历实体,组装批量insert sql(ps:hibernate批量插入性能很差,原则是还是saveOrUpdate);
6、从创建的hibernate工厂获取sessionFactory,执行批量插入sql;
关键代码:
1、通过批量jpa备份数据
@Resource private EntityManager entityManager; //注入entityManager // --------------------------------- // 通过entityManager获取所有实体 Set<EntityType<?>> entityTypes = entityManager.getMetamodel().getEntities(); // 遍历实体 entityTypes.parallelStream().forEach((EntityType<?> entity) -> { // 根据实体创建 JpaRepository SimpleJpaRepository simpleJpaRepository = new SimpleJpaRepository(entity.getJavaType(), entityManager); // 直接读表数据 List<?> list = simpleJpaRepository.findAll();
// 可以将list转为json存储...以下省略... });