因产品存在支持多种数据库平台的需求,采用JPA方式可以有效屏蔽不同数据库的语法差异,尤其是分页查询场景。
但访问异构数据源时,需要基于数据库连接信息动态构造JPA上下文,基于大模型查询了几种实现并进行验证可行的方式如下:
当前需求仅是写标准SQL使用JPA的Query对象以native方式执行即可满足,实际上JPA上下文也可以通过PersistenceUnitInfo 的entityClasses加载实体类,进而使用JPA实体方式访问数据库。
import javax.persistence.*; import javax.persistence.spi.*; import javax.sql.DataSource; import java.net.URL; import java.util.*; import java.util.stream.Collectors;/*** 动态构造JPA上下文的工具类*/ public class DynamicJpaContext {// 线程安全的EntityManagerFactory缓存private static final Map<String, EntityManagerFactory> emfCache = new HashMap<>();public static void main(String[] args) {// 1. 数据库连接信息String driverClass = "com.mysql.cj.jdbc.Driver";String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC";String username = "tkk";String password = "tkk123A?";String dialect = "org.hibernate.dialect.MySQL8Dialect";EntityManager em = DynamicJpaContext2.createEntityManager("dynamic-unit-mysql", driverClass, url, username, password, dialect);try {Query query = em.createNativeQuery("select * from tb1");List list = query.setFirstResult(1).setMaxResults(10).getResultList();EntityTransaction transaction = em.getTransaction();try {transaction.begin();Query upd = em.createNativeQuery("update tb1 set vname = :v1 where oid = :o1");String p1 = "v1";String p2 = "o1";upd.setParameter(p1, "sss");upd.setParameter(p2, 2);int cnt = upd.executeUpdate();transaction.commit();} catch (Exception e) {if (transaction.isActive()) {transaction.rollback();}e.printStackTrace();}} catch (Exception e) {} finally {if (em != null && em.isOpen()) {em.close();}}// 应用关闭时清理资源//Runtime.getRuntime().addShutdownHook(new Thread(DynamicJpaContext::closeAll)); }/*** 根据数据库连接信息创建EntityManager** @param driverClass 数据库驱动类* @param url 数据库连接URL* @param username 数据库用户名* @param password 数据库密码* @param dialect 数据库方言* @return EntityManager实例*/public static EntityManager createEntityManager(String persistenceUnitName,String driverClass,String url,String username,String password,String dialect) {// 创建唯一标识,用于缓存EntityManagerFactoryString cacheKey = generateCacheKey(url, username);// 检查缓存中是否已有对应的EntityManagerFactoryEntityManagerFactory emf = emfCache.get(cacheKey);if (emf == null || emf.isOpen() == false) {// 配置JPA属性Map<String, Object> properties = configureJpaProperties(driverClass, url, username, password, dialect);//// 创建EntityManagerFactory//emf = new HibernatePersistenceProvider()// .createContainerEntityManagerFactory(// new DynamicPersistenceUnitInfo("dynamic-unit"),// properties); PersistenceProviderResolver resolver = PersistenceProviderResolverHolder.getPersistenceProviderResolver();List<PersistenceProvider> providers = resolver.getPersistenceProviders();for (PersistenceProvider provider : providers) {emf = provider.createContainerEntityManagerFactory(new DefaultPersistenceUnitInfo(persistenceUnitName), properties);if (emf != null) {break;}}if (emf == null) {throw new PersistenceException("No Persistence provider for EntityManager named " + persistenceUnitName);}// 存入缓存 emfCache.put(cacheKey, emf);}return emf.createEntityManager();}/*** 配置JPA属性*/private static Map<String, Object> configureJpaProperties(String driverClass, String url, String username, String password, String dialect) {Map<String, Object> properties = new HashMap<>();// 数据库连接配置properties.put("javax.persistence.jdbc.driver", driverClass);properties.put("javax.persistence.jdbc.url", url);properties.put("javax.persistence.jdbc.user", username);properties.put("javax.persistence.jdbc.password", password);// Hibernate配置properties.put("hibernate.dialect", dialect);return properties;}/*** 生成缓存键,基于URL和用户名*/private static String generateCacheKey(String url, String username) {return url + "_" + username;}/*** 关闭所有缓存的EntityManagerFactory*/public static void closeAll() {for (EntityManagerFactory emf : emfCache.values()) {if (emf.isOpen()) {emf.close();}}emfCache.clear();}// 内部类:默认实现private static class DefaultPersistenceUnitInfo implements PersistenceUnitInfo {private final String unitName;private final PersistenceUnitTransactionType transactionType = PersistenceUnitTransactionType.RESOURCE_LOCAL;private final List<Class<?>> entityClasses = new ArrayList<>();private final Properties properties= new Properties();public DefaultPersistenceUnitInfo(String unitName) {this.unitName = unitName;this.properties.put("hibernate.hbm2ddl.auto", "none"); // 自动更新表结构this.properties.put("hibernate.show_sql", "false"); // 显示SQL语句this.properties.put("hibernate.format_sql", "false"); // 格式化SQL语句this.properties.put("hibernate.connection.autocommit", "false"); // 关闭自动提交 }@Overridepublic String getPersistenceUnitName() {return unitName;}@Overridepublic String getPersistenceProviderClassName() {return null;}@Overridepublic PersistenceUnitTransactionType getTransactionType() {return transactionType;}@Overridepublic DataSource getJtaDataSource() {return null;}@Overridepublic DataSource getNonJtaDataSource() {return null;}@Overridepublic List<String> getManagedClassNames() {return entityClasses.stream().map(Class::getName).collect(Collectors.toList());}// 以下为固定默认实现 @Overridepublic List<String> getMappingFileNames() {return new ArrayList<>();}@Overridepublic List<URL> getJarFileUrls() {return new ArrayList<>();}@Overridepublic URL getPersistenceUnitRootUrl() {return null;}@Overridepublic boolean excludeUnlistedClasses() {return false;}@Overridepublic SharedCacheMode getSharedCacheMode() {return SharedCacheMode.UNSPECIFIED;}@Overridepublic ValidationMode getValidationMode() {return ValidationMode.AUTO;}@Overridepublic Properties getProperties() {return properties;}@Overridepublic String getPersistenceXMLSchemaVersion() {return "2.2";}@Overridepublic ClassLoader getClassLoader() {return Thread.currentThread().getContextClassLoader();}@Overridepublic void addTransformer(ClassTransformer transformer) {}@Overridepublic ClassLoader getNewTempClassLoader() {return null;}} }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/920738.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
做社情网站犯法怎么办网络门店管理系统登录入口
首先需要在设置中使能 ,添加或修改逻辑选项。 添加或删除器件,点击logic-part,选择需要添加或删除的器件,这里的器件必须是PCB中已经有的器件,Refdes中输入添加或删除的器件标号,点击Add添加。 添加完成后就会显示在R1…
如何做视频播放网站我有域名怎么做网站
SQLAlchemy 的缓存机制主要涉及两个层面:会话(Session)缓存和查询缓存。这两种缓存机制对于提升应用性能和数据一致性都非常重要。下面详细解释这两种缓存机制:
1. 会话(Session)缓存
会话缓存是 SQLAlch…
Ansible + Docker 部署 MinIO 集群
Ansible + Docker 部署 MinIO 集群1. 准备工作
1.1 主机列表IP
主机名
内存(GB)
CPU核数
磁盘
操作系统
CPU 架构10.0.0.13
arc-pro-dc01my.registry.com
16
1
500GB
CentOS 7.9.2009
x86_6410.0.0.16
arc-pro-dc04
…
万用表与电流探头测量电流信号的技术对比分析
万用表与电流探头在电流测量中各有优势:万用表适合小电流、精度高,但需断电;电流探头非接触、适合大电流和高频信号。在电子测量领域,电流测量是电路调试、性能评估和故障诊断的基础工作。万用表和电流探头作为两种…
WPF Canvas mark triangle, circle, and retangle, then save the whole canvas as jpg file
Install-Package Wpf.Prism; private void SaveAsJpgCommandExecuted(){var dpi=VisualTreeHelper.GetDpi(this);RenderTargetBitmap rtb=new RenderTargetBitmap((int)(cvs.ActualWidth*dpi.DpiScaleY), (int)(cvs.Ac…
网站开发毕业设计周志wordpress sae 主题
BP神经网络 答案:是的,BP神经网络需要像深度学习一次次的迭代训练。总结(BP神经网络和深度学习在本质上有以下区别) 答案:是的,BP神经网络需要像深度学习一次次的迭代训练。
BP神经网络(误差反…
北京牛鼻子网站建设公司m3u8插件 wordpress
重点:
1.程序项目做出来了,需要打包发布给用户。如何打包是关键。
2.采用InstallShield软件进行发布。
步骤一:创建一个依赖三方库配置环境的bat文件的项目。 (主要测试三方库打包 和如果有bat文件,需要先创建环境&…
自动遍历测试利器:开源工具AppCrawler 配置全解析
Appcrawler是一个基于自动遍历的App爬虫工具,支持Android和IOS,支持真机和模拟器。最大的特点是灵活性高,可通过配置来设定遍历的规则。
配置文件格式
执行参数与配置文件
capability设置:与appium完全一致
testca…
得帆云ETL全新版本升级驱动数据高效流转
在数字化浪潮持续深化的背景下,数据已成为企业核心战略资产,高效的数据处理与集成能力,更是企业在数据驱动时代构筑竞争优势的关键支撑。
得帆云基于对技术创新的持续深耕及客户业务需求的深度洞察,正式推出ETL系统…
集成微信的企业网站管理系统凌河建设网站
一、Hadoop 1.x 和 2.x 的区别 二、HDFS架构
1)NameNode(nn):存储文件的元数据,如文件名,文件目录结构,文件属性(生成时间、副本数、文件权限),以及每个文件…
挖同行墙脚!有稳定供应商的客户怎么下手构建?
挖同行墙脚!有稳定供应商的客户怎么下手构建?pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…
兰州网站优化服务企业建立网站
闭包是功能性自包含模块,可以在代码中被传递和使用。 Swift 中的闭包与 C 和 Objective-C 中的 blocks 以及其他一些编程语言中的 lambdas 比较相似。 闭包的形式主要有三种: 1. 全局函数是一个有名字但不会捕获任何值的闭包 2. 嵌套函数是一个有名字并可以捕获其封…
开源技术崛起:中国如何构建数字经济时代的创新基础设施
开源技术崛起:中国如何构建数字经济时代的创新基础设施
在数字经济成为全球竞争新赛道的今天,开源技术已从单纯的软件开发模式跃升为国家战略级创新基础设施。中国开发者群体规模突破900万大关,本土代码托管平台通过…
解析网站dnshtml5做网站心得体会
232.用栈实现队列
232. 用栈实现队列
简单
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾int pop() 从队列…
北京做网站比较好的公司兼容ie8的网站模板
文章目录 1 SQLite1.1 世界上最流行的数据库1.1 SQLite简介1.2 插入语句1.3 查询数据1.4 更新数据1.5 删除数据2 DuckDB2.1 DuckDB简介2.2 DuckDB与Python结合使用2.2.1 创建表2.2.2 分析语句2.2.3 导出为parquet文件2.3 Windows中使用DuckDB3 参考附录1 SQLite
Python的一个特…
DevOps平台选型指南:数字化转型中的技术决策关键
DevOps平台选型指南:数字化转型中的技术决策关键
在数字化转型浪潮席卷全球的当下,DevOps平台已经从单纯的技术工具演变为企业技术架构的战略性组成部分。随着云计算、微服务架构和持续交付理念的普及,企业面临着如…