Flea-frame-db uses EntityManager to implement the addition, deletion, and modification of JPA sub-tables

Implementation of adding, deleting, modifying and querying JPA sub-tables based on EntityManager

This article uses EclipseLink's JPA implementation, please refer to my other blog posts for related JPA access .

First of all, let’s discuss what we need to do to implement the addition, deletion, modification, and query operation of JPA sub-tables:

  • Definition of sub-table rules (that is, the realization of the conversion from the main table to the sub-table)
  • Implementation of sub-table operation (that is, EntityManager operates specific sub-tables according to the sub-table rules)

EntityManager persistence operations

Common interface methods are as follows:

	// 新增
	void persist(Object var1);
	// 更新
    <T> T merge(T var1);
	// 删除
    void remove(Object var1);
	// 查找
    <T> T find(Class<T> var1, Object var2);

Let's analyze the implementation of the interface method of the above addition, deletion, modification, and check:

org.eclipse.persistence.internal.jpa.EntityManagerImpl

  • Persist input
    parameter: entity object instance output
    parameter: none
    Insert picture description here
    org.eclipse.persistence.internal.sessions.UnitOfWorkImpl
    Insert picture description here

  • Merge input
    parameter: entity object instance
    output parameter: entity object instance
    Insert picture description hereInsert picture description here

  • remove input
    parameter: entity object instance
    output parameter: none
    Insert picture description hereInsert picture description here

  • Find input
    parameters: entity class Class, entity class primary key
    output parameters: entity object instance
    Insert picture description here

Then we need to understand the specific implementation of the getDescriptor method:

org.eclipse.persistence.internal.sessions.AbstractSession
Insert picture description here
Insert picture description here
ClassDescriptor will eventually be cached to the lastDescriptorAccessed variable.

Finally, switch to the debug view, check the ClassDescriptor , from which you can see the DatabaseTable related to the actual table name .
Insert picture description here
At this point, we already know that the table name is stored in the DatabaseTable. If you want to implement sub-table operations, you must dynamically change the value here.

The solutions for the above-mentioned things we need to do are given below:

Definition of sub-table rules

The table name defined in the entity class can be understood as the main table name; the naming rule of the sub-table name needs to be determined first, and the following configuration is defined:

<?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>

For the implementation code related to the table splitting rule, you can move to GitHub to view TableSplitHelper

Sub-table operation realization

In the above definition of the sub-table rules, we can see that the sub-table name expression exp is composed of the main table name and sub-table fields, and the conversion implementation rules for sub-table fields are defined by split .
The sub-table processor implements 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());
        }
    }

The related code for adding , deleting, modifying and checking the JPA sub-table can be moved to GitHub to view AbstractFleaJPADAOImpl and EclipseLinkTableSplitHandler ; for the self-test class, you can view AuthSpringTest .

Guess you like

Origin blog.csdn.net/u012855229/article/details/101570812