通过手动创建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存储...以下省略...
});
2、通过jpa手动创建表
private void initEntityManager() {
Map<String, String> settings = new HashMap<>();
settings.put(AvailableSettings.DRIVER, "com.mysql.jdbc.Driver");
settings.put(AvailableSettings.DIALECT, "com.ut.msfw1a.common.core.hibernate.dialect.MsfwMySQLDialect");
settings.put(AvailableSettings.URL, "jdbc:mysql://127.0.0.1"); // 填入要还原的数据库jdbc信息
settings.put(AvailableSettings.USER, "root");
settings.put(AvailableSettings.PASS, "password");
settings.put(AvailableSettings.ORDER_INSERTS, "true");
settings.put(AvailableSettings.ORDER_UPDATES, "true");
settings.put(AvailableSettings.STATEMENT_BATCH_SIZE, "10000");
settings.put(AvailableSettings.SHOW_SQL, "false");
settings.put(AvailableSettings.BATCH_VERSIONED_DATA, "ture");
settings.put(AvailableSettings.HBM2DDL_AUTO, "update");
settings.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");// 表命名规则
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(settings).build();
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
entityTypes.forEach((EntityType<?> type) -> {//entityTpyes是备份的时候从entity中取到的
metadataSources.addAnnotatedClass(type.getJavaType()); // 添加要还原的entity
});
Metadata metadata = metadataSources.getMetadataBuilder().build(); // 创建hibernate工厂,这一步,会自动生成表
SessionFactory sessionFactory = metadata.buildSessionFactory();
sessionFactory.openSession();
entityManager = sessionFactory.createEntityManager(); // 这样就根据jdbc信息创建了一个自己的entityManager
}
3、还原数据
存数据的时候,json数据文件用表名存储
可以这样根据表名获取到对应的entity
Optional<EntityType<?>> entityTypeOptional = entityTypes.stream().filter(et -> et.getName().equals(tableName)).findFirst();
if (!entityTypeOptional.isPresent()) {
return;
}
EntityType<?> entityType = entityTypeOptional.get();
根据表名,和新创建的entityManager还原数据
SimpleJpaRepository simpleJpaRepository = new SimpleJpaRepository(entity.getJavaType(), entityManager);
simpleJpaRepository.batchSave(list)
通过手动创建hibernate工厂,自动生成表,完成数据库备份还原功能的更多相关文章
- hibernate不能自动生成表的原因总结
1. upate->create <property name="hbm2ddl.auto">create</property> 2. 2.Mappi ...
- hibernate如何配置自动生成表
hibernate自动生成表有两种方法: 1.直接写代码,通过方法来创建数据库表. 2.通过 hibernate.cfg.xml配置标签来创建数据表. 下面依次实现: 1.直接写代码,通过方法来创建数 ...
- Hibernate使用自定义脚本替换注解或者xml文件中的自动生成表结构
本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50534361 我们都清楚,可以使用hibernate的metada ...
- hibernate.hbm2ddl.auto=update不能自动生成表结构
在写上篇文章<spring整合springmvc和hibernate>的时候,曾遇到一个问题 INFO: Server startup in 8102 ms Hibernate: inse ...
- java自动生成表单简单实例
数据库表设置 tb_form(form表单) 字段 类型 约束 说明 Id Int 主键 主键 Formid Varchar2(20) 唯一 Form表单id的值 Action Varchar2(20 ...
- Eclipse中设置在创建新类时自动生成注释
方法一:Eclipse中设置在创建新类时自动生成注释 windows-->preference Java-->Code Style-->Code Templates code--&g ...
- 基于PHP和mysql的自动生成表单
开发背景:公司要求管理系统能够由管理员在前台页面管理系统表单,能够对表单进行增删改查基本操作,表单的各个字段都可以被修改.删除,可以添加新的字段,并且不影响系统正常运行,前台表单展示要由系统自动处理, ...
- 利用powerDesigner15.1连接oracle数据库并自动生成表结构
利用powerDesigner15.1连接oracle数据库并自动生成表结构 参考:http://blog.csdn.net/qq_24531461/article/details/76713802 ...
- IntelliJ IDEA 创建的文件自动生成 Author 注释 签名
IntelliJ IDEA 创建的文件自动生成 Author 注释 签名1.打开 File --> Setting2.找到 Editor --> File and Code Templat ...
- 用Django自动生成表遇到问题
因为以前在数据库中已经生成过Django 叫App01下的表,所以无法生成,在数据库中执行这个命令 DELETE FROM django_migrations WHERE app='App01';然后 ...
随机推荐
- VideoPipe可视化视频结构化框架更新总结(2022-12-9)
项目地址:https://github.com/sherlockchou86/video_pipe_c 往期文章:https://www.cnblogs.com/xiaozhi_5638/p/1685 ...
- go语言的grpc环境安装
本文直接用安装包的方式安装. 源码编译安装参考:https://www.cnblogs.com/abc36725612/p/14288333.html 环境 golang的docker image d ...
- Isaac Sim 机器人仿真器介绍、安装与 Docker [1]
前言与参考 此文书写于: January 6, 2023, 更新于 January 6, 2023 :可能会随着时间的变化 此教程会有过时概念哦 Isaac Sim 相关参考链接: 官方文档地址 官方 ...
- Java基础篇——Gui编程
AWT 抽象窗口工具 组件:按钮(button) 文本域(textarea) 标签(label) 容器(container)... Frame窗口 Frame frame = new Frame( ...
- [cocos2d-x]从源码角度思考convertToWorldSpace()与convertToWorldSpaceAR()坐标系的转换
convertToWorldSpace() 话不多说,先上源码,之后再慢慢讲解: (5和6图截图的时候重复了,这里就不弄出来了) 只要通过图1到图8中我写的注释进行分析(不懂的地方可以自己去翻一下co ...
- pytorch 配置详细过程
torch github 项目多 方便,api好调用 cpu版本 装torch 安装最新版本的就可以. torchvision 要版本对应 算法: torchvision版本号= torch版本号第一 ...
- 存储自定义类型元素-LinkedHashSet集合
存储自定义类型元素 HashSet存储自定义类型元素 set集合报错元素唯一: 存储的元素(String,Integer,...,Student,Person...),必须重写hashCode方法和e ...
- LinkedList集合-Vector集合
LinkedList集合 java.util.LinkedList集合数据存储的结构是链表结构.方便元素添加.删除的集合.LinkedList是一个双向链表,那么双向链表是什么样子的呢,我们用个图了解 ...
- DateFormat类&SimpleDateFrormat类介绍-Dateformat类的format方法parse方法
DateFormat类&SimpleDateFrormat类介绍 java.text.DateFormat是日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就 ...
- Jvm--MinorGC过程
第一次GC: 在不断创建对象的过程中,当Eden区域被占满,此时会开始做Young GC也叫Minor GC 1)第一次GC时Survivous中S0区和S1区都为空,将其中一个作为To Surviv ...