flea-frame-db使用之基于EntityManager实现JPA分表的数据库操作
基于EntityManager实现JPA分表的数据库操作
本文采用 EclipseLink的JPA实现,相关JPA接入使用请移步我的另外几篇博文。
首先还是讨论一下,实现JPA分表的增删改查操作,我们需要做什么:
- 分表规则定义(即从主表到分表的转换实现)
- 分表操作实现(即EntityManager根据分表规则操作具体分表)
1. EntityManager持久化操作
常用接口方法如下:
// 新增 void persist(Object var1); // 更新 <T> T merge(T var1); // 删除 void remove(Object var1); // 查找 <T> T find(Class<T> var1, Object var2);
下面来分析一下上述增删改查的接口方法实现:
org.eclipse.persistence.internal.jpa.EntityManagerImpl
- persist
入参 : 实体对象实例
出参 : 无
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl - merge
入参 : 实体对象实例
出参 : 实体对象实例 - remove
入参 : 实体对象实例
出参 : 无 - find
入参 : 实体类Class, 实体类主键
出参 : 实体对象实例
然后我们需要了解下getDescriptor方法的具体实现 :
org.eclipse.persistence.internal.sessions.AbstractSession
ClassDescriptor 最后都会被缓存到 lastDescriptorAccessed 变量。
最后切到debug视图,查看一下 ClassDescriptor,从中可以看到 与实际表名相关的 DatabaseTable。
到了这一步,我们已经知道了表名存储在DatabaseTable中,要想实现分表操作,势必需要动态改变这里的值。
下面给出上述我们需要做的事情的解决方案:
2. 分表规则定义
实体类中定义的表名,我们可以理解为主表名;分表名的命名规则首先需要确定一下,定义如下配置:
<?xml version="1.0" encoding="UTF-8"?> <tables> <!-- 定义分表配置 name : 分表对应的主表名 exp : 分表名表达式 (FLEA_TABLE_NAME)_(列名大写)_(列名大写) --> <table name="flea_login_log" exp="(FLEA_TABLE_NAME)_(CREATE_DATE)" desc="Flea登录日志表分表规则"> <splits> <!-- 定义分表后缀 key : 分表类型关键字 (可查看 com.huazie.frame.db.common.table.split.TableSplitEnum ) column : 分表属性列字段名 implClass : 分表后缀转换实现类 --> <split key="yyyymm" column="create_date" implClass="com.huazie.frame.db.common.table.split.impl.YYYYMMTableSplitImpl"/> </splits> </table> </tables>
分表规则相关实现代码,可以移步 GitHub 查看 TableSplitHelper
3. 分表操作实现
在上述分表规则定义中, 我们可以看到分表名表达式exp是由 主表名 和 分表字段 组成,分表字段的转换实现规则由split定义。
分表处理者实现 EclipseLinkTableSplitHandler
@Override public void handle(EntityManager entityManager, Object entity, boolean isRead) throws Exception { if (ObjectUtils.isEmpty(entityManager) || ObjectUtils.isEmpty(entity)) { return; } // 获取分表信息(包括主表名 和 分表名 【如果存在分表返回】) SplitTable splitTable = EntityUtils.getSplitTable(entity); // 存在分表,则需要操作具体分表 if (StringUtils.isNotBlank(splitTable.getSplitTableName())) { // 获取可用的数据库会话对象 AbstractSession session; if (isRead) { session = entityManager.unwrap(AbstractSession.class); } else { session = entityManager.unwrap(RepeatableWriteUnitOfWork.class); } // 重新设置 查询的分表表名 session.getDescriptor(entity.getClass()).setTableName(splitTable.getSplitTableName()); } }
JPA分表的增删改查操作相关代码可以 移步 GitHub 查看 AbstractFleaJPADAOImpl 和 EclipseLinkTableSplitHandler;
4. 自测
自测类可以查看 LoginLogAuthTest。
4.1 新增数据
@Test public void testFleaLoginLogInsert() { try { IFleaLoginLogSV fleaLoginLogSV = (IFleaLoginLogSV) applicationContext.getBean("fleaLoginLogSV"); FleaLoginLog fleaLoginLog = new FleaLoginLog(); fleaLoginLog.setAccountId(1000000L); fleaLoginLog.setSystemAccountId(2000L); fleaLoginLog.setLoginIp4("127.0.0.1"); fleaLoginLog.setLoginState(1); fleaLoginLog.setLoginTime(DateUtils.getCurrentTime()); fleaLoginLog.setCreateDate(DateUtils.getCurrentTime()); Long fleaLoginId = fleaLoginLogSV.getFleaNextValue(fleaLoginLog); fleaLoginLog.setLoginLogId(fleaLoginId); // 保存至分表 fleaLoginLogSV.save(fleaLoginLog); } catch (Exception e) { LOGGER.error("Exception:", e); } }
4.2 查询数据
@Test public void testFleaLoginLogQuery() { try { IFleaLoginLogSV fleaLoginLogSV = (IFleaLoginLogSV) applicationContext.getBean("fleaLoginLogSV"); FleaLoginLog fleaLoginLog = new FleaLoginLog(); fleaLoginLog.setCreateDate(DateUtils.getCurrentTime()); fleaLoginLog = fleaLoginLogSV.queryNew(1L, fleaLoginLog); LOGGER.debug("FleaLoginLog = {}", fleaLoginLog); } catch (Exception e) { LOGGER.error("Exception:", e); } }
4.3 更新数据
@Test public void testFleaLoginLogUpdate() { try { IFleaLoginLogSV fleaLoginLogSV = (IFleaLoginLogSV) applicationContext.getBean("fleaLoginLogSV"); FleaLoginLog fleaLoginLog = new FleaLoginLog(); fleaLoginLog.setCreateDate(DateUtils.getCurrentTime()); fleaLoginLog = fleaLoginLogSV.queryNew(1L, fleaLoginLog); LOGGER.debug("FleaLoginLog = {}", fleaLoginLog); // 更新记录(分表) fleaLoginLog.setLogoutTime(DateUtils.getCurrentTime()); fleaLoginLog.setDoneDate(DateUtils.getCurrentTime()); fleaLoginLog.setLoginState(2); fleaLoginLog.setRemarks("用户退出登陆"); fleaLoginLogSV.update(fleaLoginLog); } catch (Exception e) { LOGGER.error("Exception:", e); } }
4.4 删除数据
@Test public void testFleaLoginLogDelete() { try { IFleaLoginLogSV fleaLoginLogSV = (IFleaLoginLogSV) applicationContext.getBean("fleaLoginLogSV"); FleaLoginLog fleaLoginLog = new FleaLoginLog(); fleaLoginLog.setCreateDate(DateUtils.getCurrentTime()); fleaLoginLogSV.removeNew(1L, fleaLoginLog); } catch (Exception e) { LOGGER.error("Exception:", e); } }
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
华为帐号服务学习笔记(三):10分钟完成Authorization Code模式客户端Demo开发
Demo开发准备 1、 安装Android Studio 3.5及以上版本;2、 安装JDK 1.8 及以上;3、 使用Android SDK Platform 19及以上;4、 使用Gradle 4.6及以上;5、 在华为开发者联盟注册成为华为开发者,如已注册,请跳过此步骤; 运行环境配置 之前按照华为帐号的官方指导试过demo开发,发现前期接入华为开发者联盟的各种步骤有点繁琐,各种界面来回切换,后来在Android Studio上发现HMS提供了一个IDE插件,可以帮忙快速集成。本次文章主要就介绍通过这个IDE插件来快速创建一个华为帐号demo。如果想自己手动按照步骤创建帐号的demo,可以直接查看这个官方指导:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/dev-process-0000001050443773IDE插件安装 这个工具叫HMS Toolkit,后来发现华为官方也有介绍,大家有兴趣的可以去它们主页了解下:https://developer.huawei.com/c...
- 下一篇
WeiboEmoji v.3.5.3 发布,收集微博 APP 的 emoji
WeiboEmoji v.3.5.3 已经发布,此版本更新内容包括: 注意 压缩包“WeiboEmoji_V3.5.3.zip”中的所有图片均为PNG格式,禁止将它们用于商业用途。更多信息请参见README。 特性 添加一个清明节相关表情(雏菊)。 添加一个未包含的旧的表情(小丑)。 变化 调整分类。 详情查看:https://gitee.com/ArvinZJC/WeiboEmoji/releases/v.3.5.3
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Red5直播服务器,属于Java语言的直播服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8编译安装MySQL8.0.19
- CentOS关闭SELinux安全模块
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作