通过手动创建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';然后 ...
随机推荐
- Spring框架之IOC入门
1.开发环境 IDEA版本: 2022.1.4 Maven版本:3.8.6 Spring版本:6.0.2 2.案例分析 2.1 自定义Man类 2.2 自定义Company类 2.3 自定义Compa ...
- ArcObjects SDK 012 PageLayout和Page
1.从ArcMap角度看结构 一个Mxd文件包含一个PageLayout对象和一个多多个Map对象,每个Map会被包成MapFrame,添加到PageLayout中.我们用ArcMap打开一个mxd文 ...
- day34-JSON&Ajax02
JSON&Ajax02 1.Ajax基本介绍 1.1Ajax是什么 AJAX 即"Asynchronous JavaScript And XML"(异步JavaScript ...
- 【Java】各种数据类型的元素数量
容易混,就算写多了也容易混... 数据类型 元素个数写法 备注 Stack s s.size() s的元素个数 二维数组m[][] m.length m的行数 二维数组m[][] m[0].lengt ...
- 深度学习GPU加速配置方法
深度学习GPU加速配置方法 一.英伟达官方驱动及工具安装 首先检查自己的电脑驱动版本,未更新至最新建议先将驱动更新至最新,然后点击Nvidia控制面板 2.在如下界面中点击系统信息,点击显示可以看见当 ...
- python 之异常捕获及处理(try--except)
在python中,至少有两类错误,一种是程序语法错误,一种是程序异常. 所谓的语法错误是指你未按规定格式书写导致的错误,如:定义函数时,括号后面要紧跟英文冒号,若缺失则不能识别与运行,并抛出 Synt ...
- Clickhouse表引擎探究-ReplacingMergeTree
作者:耿宏宇 1 表引擎简述 1.1 官方描述 MergeTree 系列的引擎被设计用于插入极大量的数据到一张表当中.数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合 ...
- Android的诞生
Android操作系统最初由Andy Rubin开发,刚开始主要支持手机,被Google收购后,对Android进行了改良,使其可以用于平板电脑等其它领域. 1.1.1 Android的发展史Andr ...
- [cocos2d-x]飞机大战 遇到的bug和总结(二)
第一点 声音文件最好不要使用mp3格式,因为我在同时使用背景音乐和playeffect()的时候,出现了bug,两者的音效不能同时出现(应该是格式问题),并且声音在windows上运行的时候加载非常慢 ...
- Word 交叉引用 给参考文献、图片题注添加引用
参考文献引用 假如想在红色[1]处添加引用,实现点击[1]跳到参考文献[1]. 首先需要将参考文献进行编号. 在需要插入引用的地方,选择插入-->交叉引用 点击插入 最后可以把[1]调成上标 上 ...