Implementación de agregar, eliminar, modificar y consultar subtablas JPA basadas en EntityManager
Este artículo utiliza la implementación de JPA de EclipseLink; consulte las otras publicaciones de mi blog para obtener acceso a JPA relacionado .
En primer lugar, analicemos lo que debemos hacer para implementar la operación de adición, eliminación, modificación y consulta de las subtablas de JPA:
- Definición de reglas de subtabla (es decir, la realización de la conversión de la tabla principal a la subtabla)
- Implementación de operaciones de subtabla (es decir, EntityManager opera subtablas específicas de acuerdo con las reglas de subtabla)
Operaciones de persistencia de EntityManager
Los métodos de interfaz comunes son los siguientes:
// 新增
void persist(Object var1);
// 更新
<T> T merge(T var1);
// 删除
void remove(Object var1);
// 查找
<T> T find(Class<T> var1, Object var2);
Analicemos la implementación del método de interfaz de la adición, eliminación, modificación y verificación anterior:
org.eclipse.persistence.internal.jpa.EntityManagerImpl
-
Parámetro de entrada persistente :
parámetro de salida de instancia de objeto de entidad : ninguno
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl
-
Fusionar
parámetro de entrada : instancia de objeto de entidad
parámetro de salida: instancia de objeto de entidad
-
eliminar
parámetro de entrada : instancia de objeto de entidad
parámetro de salida: ninguno
-
Buscar
parámetros de entrada : clase de entidad Clase, clase de entidad
parámetros de salida de clave primaria : instancia de objeto de entidad
Entonces necesitamos entender la implementación específica del método getDescriptor:
org.eclipse.persistence.internal.sessions.AbstractSession
ClassDescriptor eventualmente se almacenará en caché en la variable lastDescriptorAccessed .
Finalmente, cambie a la vista de depuración, verifique el ClassDescriptor , desde el cual puede ver el DatabaseTable relacionado con el nombre real de la tabla .
En este punto, ya sabemos que el nombre de la tabla está almacenado en DatabaseTable. Si desea implementar operaciones de subtabla, debe cambiar dinámicamente el valor aquí.
Las soluciones para las cosas mencionadas anteriormente que debemos hacer se dan a continuación:
Definición de reglas de subtabla
El nombre de la tabla definido en la clase de entidad puede entenderse como el nombre de la tabla principal; primero se debe determinar la regla de nomenclatura del nombre de la subtabla y se define la siguiente configuración:
<?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>
Para el código de implementación relacionado con la regla de división de tablas, puede moverse a GitHub para ver TableSplitHelper
Realización de la operación de la sub-tabla
En la definición anterior de las reglas de la subtabla, podemos ver que la expresión del nombre de la subtabla exp está compuesta por el nombre de la tabla principal y los campos de la subtabla, y las reglas de implementación de conversión para los campos de la subtabla se definen por división .
El procesador de submesa implementa 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());
}
}
El código relevante para agregar , eliminar, modificar y verificar las subtablas JPA se puede encontrar en GitHub para ver AbstractFleaJPADAOImpl y EclipseLinkTableSplitHandler ; para clases de autoprueba, puede ver AuthSpringTest .