本文采用 EclipseLink的JPA實現,相關JPA接入使用請移步個人另外幾篇博文。html
首先仍是討論一下,實現JPA分表的增刪改查操做,咱們須要作什麼:java
經常使用接口方法以下:git
// 新增 void persist(Object var1); // 更新 <T> T merge(T var1); // 刪除 void remove(Object var1); // 查找 <T> T find(Class<T> var1, Object var2);
下面來分析一下上述增刪改查的接口方法實現:github
org.eclipse.persistence.internal.jpa.EntityManagerImpl數據庫
而後咱們須要瞭解下getDescriptor方法的具體實現 :緩存
org.eclipse.persistence.internal.sessions.AbstractSession
ClassDescriptor 最後都會被緩存到 lastDescriptorAccessed 變量。session
最後切到debug視圖,查看一下 ClassDescriptor,從中能夠看到 與實際表名相關的 DatabaseTable。
到了這一步,咱們已經知道了表名存儲在DatabaseTable中,要想實現分表操做,勢必須要動態改變這裏的值。app
下面給出上述咱們須要作的事情的解決方案:eclipse
實體類中定義的表名,咱們能夠理解爲主表名;分表名的命名規則首先須要肯定一下,定義以下配置:ide
<?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
在上述分表規則定義中, 咱們能夠看到分表名錶達式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;
自測類能夠查看 LoginLogAuthTest。
@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); } }
@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); } }
@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); } }
@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); } }