最近做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工厂,自动生成表,完成数据库备份还原功能的更多相关文章

  1. hibernate不能自动生成表的原因总结

    1. upate->create <property name="hbm2ddl.auto">create</property> 2. 2.Mappi ...

  2. hibernate如何配置自动生成表

    hibernate自动生成表有两种方法: 1.直接写代码,通过方法来创建数据库表. 2.通过 hibernate.cfg.xml配置标签来创建数据表. 下面依次实现: 1.直接写代码,通过方法来创建数 ...

  3. Hibernate使用自定义脚本替换注解或者xml文件中的自动生成表结构

    本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50534361 我们都清楚,可以使用hibernate的metada ...

  4. hibernate.hbm2ddl.auto=update不能自动生成表结构

    在写上篇文章<spring整合springmvc和hibernate>的时候,曾遇到一个问题 INFO: Server startup in 8102 ms Hibernate: inse ...

  5. java自动生成表单简单实例

    数据库表设置 tb_form(form表单) 字段 类型 约束 说明 Id Int 主键 主键 Formid Varchar2(20) 唯一 Form表单id的值 Action Varchar2(20 ...

  6. Eclipse中设置在创建新类时自动生成注释

    方法一:Eclipse中设置在创建新类时自动生成注释 windows-->preference Java-->Code Style-->Code Templates code--&g ...

  7. 基于PHP和mysql的自动生成表单

    开发背景:公司要求管理系统能够由管理员在前台页面管理系统表单,能够对表单进行增删改查基本操作,表单的各个字段都可以被修改.删除,可以添加新的字段,并且不影响系统正常运行,前台表单展示要由系统自动处理, ...

  8. 利用powerDesigner15.1连接oracle数据库并自动生成表结构

    利用powerDesigner15.1连接oracle数据库并自动生成表结构 参考:http://blog.csdn.net/qq_24531461/article/details/76713802 ...

  9. IntelliJ IDEA 创建的文件自动生成 Author 注释 签名

    IntelliJ IDEA 创建的文件自动生成 Author 注释 签名1.打开 File --> Setting2.找到 Editor --> File and Code Templat ...

  10. 用Django自动生成表遇到问题

    因为以前在数据库中已经生成过Django 叫App01下的表,所以无法生成,在数据库中执行这个命令 DELETE FROM django_migrations WHERE app='App01';然后 ...

随机推荐

  1. VideoPipe可视化视频结构化框架更新总结(2022-12-9)

    项目地址:https://github.com/sherlockchou86/video_pipe_c 往期文章:https://www.cnblogs.com/xiaozhi_5638/p/1685 ...

  2. go语言的grpc环境安装

    本文直接用安装包的方式安装. 源码编译安装参考:https://www.cnblogs.com/abc36725612/p/14288333.html 环境 golang的docker image d ...

  3. Isaac Sim 机器人仿真器介绍、安装与 Docker [1]

    前言与参考 此文书写于: January 6, 2023, 更新于 January 6, 2023 :可能会随着时间的变化 此教程会有过时概念哦 Isaac Sim 相关参考链接: 官方文档地址 官方 ...

  4. Java基础篇——Gui编程

    AWT 抽象窗口工具 组件:按钮(button) 文本域(textarea) ​ 标签(label) 容器(container)... Frame窗口 Frame frame = new Frame( ...

  5. [cocos2d-x]从源码角度思考convertToWorldSpace()与convertToWorldSpaceAR()坐标系的转换

    convertToWorldSpace() 话不多说,先上源码,之后再慢慢讲解: (5和6图截图的时候重复了,这里就不弄出来了) 只要通过图1到图8中我写的注释进行分析(不懂的地方可以自己去翻一下co ...

  6. pytorch 配置详细过程

    torch github 项目多 方便,api好调用 cpu版本 装torch 安装最新版本的就可以. torchvision 要版本对应 算法: torchvision版本号= torch版本号第一 ...

  7. 存储自定义类型元素-LinkedHashSet集合

    存储自定义类型元素 HashSet存储自定义类型元素 set集合报错元素唯一: 存储的元素(String,Integer,...,Student,Person...),必须重写hashCode方法和e ...

  8. LinkedList集合-Vector集合

    LinkedList集合 java.util.LinkedList集合数据存储的结构是链表结构.方便元素添加.删除的集合.LinkedList是一个双向链表,那么双向链表是什么样子的呢,我们用个图了解 ...

  9. DateFormat类&SimpleDateFrormat类介绍-Dateformat类的format方法parse方法

    DateFormat类&SimpleDateFrormat类介绍 java.text.DateFormat是日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就 ...

  10. Jvm--MinorGC过程

    第一次GC: 在不断创建对象的过程中,当Eden区域被占满,此时会开始做Young GC也叫Minor GC 1)第一次GC时Survivous中S0区和S1区都为空,将其中一个作为To Surviv ...