通过手动创建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';然后 ...
随机推荐
- express 为所有路由添加 405 method not allowd 响应
背景知识 HTTP Status Code 405 405 Method not allowed The resource was requested using a method that is n ...
- CTF隐写术总结
CTF隐写术总结 1.查看图像属性及详细信息 或者查看图像的高度,利用winhex等工具改变图像宽度或高度,查看是否有隐藏信息. 2.利用winhex或nodepad++打开搜索ctf,flag,ke ...
- Burpsuite2022.1详细图文安装教程(含工具链接)
应用概述: Burp Suite 是用于攻击web 应用程序的集成平台,包含了许多工具.Burp Suite为这些工具设计了许多接口,以加快攻击应用程序的过程.所有工具都共享一个请求,并能处理对应 ...
- 第一百一十四篇: JS数组Array(三)数组常用方法
好家伙,本篇为<JS高级程序设计>第六章"集合引用类型"学习笔记 1.数组的复制和填充 批量复制方法 copyWithin(),以及填充数组方法fill(). 这两 ...
- java Jdbc 简单方法
1.注册驱动(第一种方法) Class.forName(com.mysql.jdbc.Driver"); 2.获得连接DriverManager.getConnection(url,user ...
- UOJ33 [UR#2] 树上 GCD
UOJ33 [UR#2] 树上 GCD 简要题意: 给定一棵有根树,对于每个 \(i \in [1,n)\),求出下式的值: \[Ans[i] = \sum_{u<v} \gcd({\rm{di ...
- 激光炸弹【算法竞赛进阶指南, HNOI2003】
激光炸弹 地图上有 \(N\) 个目标,用整数 \(Xi,Yi\)表示目标在地图上的位置,每个目标都有一个价值 \(Wi\). 注意:不同目标可能在同一位置. 现在有一种新型的激光炸弹,可以摧毁一个包 ...
- [深度学习]Keras利用VGG进行迁移学习模板
# -*- coding: UTF-8 -*- import keras from keras import Model from keras.applications import VGG16 fr ...
- [cocos2d-x]关于声音和音效
使用声音音效 CocosDesion实现了简单易用的SimpleAudioEngine类,为了使用它,我们只需引入他的头文件即可: #include "SimpleAudioEngine.h ...
- pytest框架的简介
概念:是一款基于python语言的单元测试框架 用途:用于发现测试用例.执行测试用例.判断测试结果.生成测试报告的一款框架 测试用例的规则: 测试文件必须与test开头,或_test结尾 类文件必须T ...