mirror of
https://github.com/PowerJob/PowerJob.git
synced 2025-07-17 00:00:04 +08:00
[Feature] add table prefix
This commit is contained in:
parent
9ac3929a8e
commit
d159654fc6
@ -1,6 +1,9 @@
|
||||
package com.github.kfcfans.powerjob.server.persistence.config;
|
||||
|
||||
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
@ -15,6 +18,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -39,6 +44,9 @@ public class CoreJpaConfig {
|
||||
@Resource(name = "omsCoreDatasource")
|
||||
private DataSource omsCoreDatasource;
|
||||
|
||||
@Resource
|
||||
private PowerJobPhysicalNamingStrategy powerJobPhysicalNamingStrategy;
|
||||
|
||||
public static final String CORE_PACKAGES = "com.github.kfcfans.powerjob.server.persistence.core";
|
||||
|
||||
/**
|
||||
@ -49,7 +57,7 @@ public class CoreJpaConfig {
|
||||
*
|
||||
* @return 配置Map
|
||||
*/
|
||||
private static Map<String, Object> genDatasourceProperties() {
|
||||
private Map<String, Object> genDatasourceProperties() {
|
||||
|
||||
JpaProperties jpaProperties = new JpaProperties();
|
||||
jpaProperties.setOpenInView(false);
|
||||
@ -57,7 +65,14 @@ public class CoreJpaConfig {
|
||||
|
||||
HibernateProperties hibernateProperties = new HibernateProperties();
|
||||
hibernateProperties.setDdlAuto("update");
|
||||
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
|
||||
|
||||
// 配置JPA自定义表名称策略
|
||||
HibernateSettings hibernateSettings = new HibernateSettings();
|
||||
List<HibernatePropertiesCustomizer> customizers = new ArrayList<>();
|
||||
customizers.add(
|
||||
new NamingStrategiesHibernatePropertiesCustomizer(powerJobPhysicalNamingStrategy, null));
|
||||
hibernateSettings.hibernatePropertiesCustomizers(customizers);
|
||||
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), hibernateSettings);
|
||||
}
|
||||
|
||||
@Primary
|
||||
@ -79,4 +94,31 @@ public class CoreJpaConfig {
|
||||
return new JpaTransactionManager(Objects.requireNonNull(initCoreEntityManagerFactory(builder).getObject()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 参考 HibernateJpaConfiguration.NamingStrategiesHibernatePropertiesCustomizer
|
||||
*/
|
||||
private static class NamingStrategiesHibernatePropertiesCustomizer implements HibernatePropertiesCustomizer {
|
||||
|
||||
private final PhysicalNamingStrategy physicalNamingStrategy;
|
||||
|
||||
private final ImplicitNamingStrategy implicitNamingStrategy;
|
||||
|
||||
NamingStrategiesHibernatePropertiesCustomizer(PhysicalNamingStrategy physicalNamingStrategy,
|
||||
ImplicitNamingStrategy implicitNamingStrategy) {
|
||||
this.physicalNamingStrategy = physicalNamingStrategy;
|
||||
this.implicitNamingStrategy = implicitNamingStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(Map<String, Object> hibernateProperties) {
|
||||
if (this.physicalNamingStrategy != null) {
|
||||
hibernateProperties.put("hibernate.physical_naming_strategy", this.physicalNamingStrategy);
|
||||
}
|
||||
if (this.implicitNamingStrategy != null) {
|
||||
hibernateProperties.put("hibernate.implicit_naming_strategy", this.implicitNamingStrategy);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,113 @@
|
||||
package com.github.kfcfans.powerjob.server.persistence.config;
|
||||
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 自定义表前缀,配置项 oms.table-prefix 不配置时,不增加表前缀。
|
||||
* 参考实现:{@link org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy}
|
||||
* <p>
|
||||
* 1. 继承 PhysicalNamingStrategy 类,实现自定义表前缀;
|
||||
* </p>
|
||||
* <p>
|
||||
* 2. 修改@Query(nativeQuery = true)和其SQL,用对象名和属性名代替表名和数据库字段名。
|
||||
* </p>
|
||||
*
|
||||
* @author songyinyin
|
||||
* @date 2020/7/18 下午 11:01
|
||||
* @since 3.1.4
|
||||
*/
|
||||
@Component
|
||||
public class PowerJobPhysicalNamingStrategy implements PhysicalNamingStrategy, Serializable {
|
||||
|
||||
@Value("${oms.table-prefix:}")
|
||||
private String tablePrefix;
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 映射物理表名称,如:把实体表 AppInfoDO 的 DO 去掉,再加上表前缀
|
||||
*
|
||||
* @param name 实体名称
|
||||
* @param jdbcEnvironment jdbc环境变量
|
||||
* @return 映射后的物理表
|
||||
*/
|
||||
@Override
|
||||
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
Identifier identifier = apply(name, jdbcEnvironment);
|
||||
|
||||
String text = identifier.getText();
|
||||
String noDOText = StringUtils.endsWithIgnoreCase(text, "do") ? text.substring(0, text.length() - 2) : text;
|
||||
String newText = StringUtils.hasLength(tablePrefix) ? tablePrefix + noDOText : noDOText;
|
||||
return new Identifier(newText, identifier.isQuoted());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
return apply(name, jdbcEnvironment);
|
||||
}
|
||||
|
||||
private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
|
||||
for (int i = 1; i < builder.length() - 1; i++) {
|
||||
if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) {
|
||||
builder.insert(i++, '_');
|
||||
}
|
||||
}
|
||||
return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an identifier for the specified details. By default this method will return an
|
||||
* identifier with the name adapted based on the result of
|
||||
* {@link #isCaseInsensitive(JdbcEnvironment)}
|
||||
*
|
||||
* @param name the name of the identifier
|
||||
* @param quoted if the identifier is quoted
|
||||
* @param jdbcEnvironment the JDBC environment
|
||||
* @return an identifier instance
|
||||
*/
|
||||
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
|
||||
if (isCaseInsensitive(jdbcEnvironment)) {
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
return new Identifier(name, quoted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the database is case sensitive.
|
||||
*
|
||||
* @param jdbcEnvironment the JDBC environment which can be used to determine case
|
||||
* @return true if the database is case insensitive sensitivity
|
||||
*/
|
||||
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isUnderscoreRequired(char before, char current, char after) {
|
||||
return Character.isLowerCase(before) && Character.isUpperCase(current) && Character.isLowerCase(after);
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ import java.util.Date;
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "app_info", uniqueConstraints = {@UniqueConstraint(name = "appNameUK", columnNames = {"appName"})})
|
||||
@Table(uniqueConstraints = {@UniqueConstraint(name = "appNameUK", columnNames = {"appName"})})
|
||||
public class AppInfoDO {
|
||||
|
||||
@Id
|
||||
|
@ -13,7 +13,7 @@ import java.util.Date;
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "container_info", indexes = {@Index(columnList = "appId")})
|
||||
@Table(indexes = {@Index(columnList = "appId")})
|
||||
public class ContainerInfoDO {
|
||||
|
||||
@Id
|
||||
|
@ -18,7 +18,7 @@ import java.util.Date;
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "instance_info", indexes = {@Index(columnList = "jobId"), @Index(columnList = "appId"), @Index(columnList = "instanceId")})
|
||||
@Table(indexes = {@Index(columnList = "jobId"), @Index(columnList = "appId"), @Index(columnList = "instanceId")})
|
||||
public class InstanceInfoDO {
|
||||
|
||||
@Id
|
||||
|
@ -18,7 +18,7 @@ import java.util.Date;
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "job_info", indexes = {@Index(columnList = "appId")})
|
||||
@Table(indexes = {@Index(columnList = "appId")})
|
||||
public class JobInfoDO {
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ import java.util.Date;
|
||||
@Data
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Table(name = "oms_lock", uniqueConstraints = {@UniqueConstraint(name = "lockNameUK", columnNames = {"lockName"})})
|
||||
@Table(uniqueConstraints = {@UniqueConstraint(name = "lockNameUK", columnNames = {"lockName"})})
|
||||
public class OmsLockDO {
|
||||
|
||||
@Id
|
||||
|
@ -15,7 +15,7 @@ import java.util.Date;
|
||||
@Data
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Table(name = "server_info", uniqueConstraints = {@UniqueConstraint(columnNames = "ip")})
|
||||
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "ip")})
|
||||
public class ServerInfoDO {
|
||||
|
||||
@Id
|
||||
|
@ -13,7 +13,7 @@ import java.util.Date;
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "user_info")
|
||||
@Table
|
||||
public class UserInfoDO {
|
||||
|
||||
@Id
|
||||
|
@ -17,7 +17,7 @@ import java.util.Date;
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "workflow_info", indexes = {@Index(columnList = "appId")})
|
||||
@Table(indexes = {@Index(columnList = "appId")})
|
||||
public class WorkflowInfoDO {
|
||||
|
||||
@Id
|
||||
|
@ -17,7 +17,7 @@ import java.util.Date;
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "workflow_instance_info")
|
||||
@Table
|
||||
public class WorkflowInstanceInfoDO {
|
||||
|
||||
@Id
|
||||
|
@ -37,19 +37,19 @@ public interface InstanceInfoRepository extends JpaRepository<InstanceInfoDO, Lo
|
||||
@Transactional
|
||||
@Modifying
|
||||
@CanIgnoreReturnValue
|
||||
@Query(value = "update instance_info set status = ?2, running_times = ?3, actual_trigger_time = ?4, finished_time = ?5, task_tracker_address = ?6, result = ?7, instance_params = ?8, gmt_modified = ?9 where instance_id = ?1", nativeQuery = true)
|
||||
@Query(value = "update InstanceInfoDO set status = ?2, runningTimes = ?3, actualTriggerTime = ?4, finishedTime = ?5, taskTrackerAddress = ?6, result = ?7, instanceParams = ?8, gmtModified = ?9 where instanceId = ?1")
|
||||
int update4TriggerFailed(long instanceId, int status, long runningTimes, long actualTriggerTime, long finishedTime, String taskTrackerAddress, String result, String instanceParams, Date modifyTime);
|
||||
|
||||
@Transactional
|
||||
@Modifying
|
||||
@CanIgnoreReturnValue
|
||||
@Query(value = "update instance_info set status = ?2, running_times = ?3, actual_trigger_time = ?4, task_tracker_address = ?5, instance_params = ?6, gmt_modified = ?7 where instance_id = ?1", nativeQuery = true)
|
||||
@Query(value = "update InstanceInfoDO set status = ?2, runningTimes = ?3, actualTriggerTime = ?4, taskTrackerAddress = ?5, instanceParams = ?6, gmtModified = ?7 where instanceId = ?1")
|
||||
int update4TriggerSucceed(long instanceId, int status, long runningTimes, long actualTriggerTime, String taskTrackerAddress, String instanceParams, Date modifyTime);
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
@CanIgnoreReturnValue
|
||||
@Query(value = "update instance_info set status = ?2, running_times = ?3, gmt_modified = ?4 where instance_id = ?1", nativeQuery = true)
|
||||
@Query(value = "update InstanceInfoDO set status = ?2, runningTimes = ?3, gmtModified = ?4 where instanceId = ?1")
|
||||
int update4FrequentJob(long instanceId, int status, long runningTimes, Date modifyTime);
|
||||
|
||||
// 状态检查三兄弟,对应 WAITING_DISPATCH 、 WAITING_WORKER_RECEIVE 和 RUNNING 三阶段
|
||||
@ -64,13 +64,13 @@ public interface InstanceInfoRepository extends JpaRepository<InstanceInfoDO, Lo
|
||||
long countByAppIdAndStatus(long appId, int status);
|
||||
long countByAppIdAndStatusAndGmtCreateAfter(long appId, int status, Date time);
|
||||
|
||||
@Query(value = "select job_id from instance_info where job_id in ?1 and status in ?2", nativeQuery = true)
|
||||
@Query(value = "select jobId from InstanceInfoDO where jobId in ?1 and status in ?2")
|
||||
List<Long> findByJobIdInAndStatusIn(List<Long> jobIds, List<Integer> status);
|
||||
|
||||
// 删除历史数据,JPA自带的删除居然是根据ID循环删,2000条数据删了几秒,也太拉垮了吧...
|
||||
// 结果只能用 int 接收
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query(value = "delete from instance_info where gmt_modified < ?1", nativeQuery = true)
|
||||
@Query(value = "delete from InstanceInfoDO where gmtModified < ?1")
|
||||
int deleteAllByGmtModifiedBefore(Date time);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public interface JobInfoRepository extends JpaRepository<JobInfoDO, Long> {
|
||||
// 调度专用
|
||||
List<JobInfoDO> findByAppIdInAndStatusAndTimeExpressionTypeAndNextTriggerTimeLessThanEqual(List<Long> appIds, int status, int timeExpressionType, long time);
|
||||
|
||||
@Query(value = "select id from job_info where app_id in ?1 and status = ?2 and time_expression_type in ?3", nativeQuery = true)
|
||||
@Query(value = "select id from JobInfoDO where appId in ?1 and status = ?2 and timeExpressionType in ?3")
|
||||
List<Long> findByAppIdInAndStatusAndTimeExpressionTypeIn(List<Long> appIds, int status, List<Integer> timeTypes);
|
||||
|
||||
Page<JobInfoDO> findByAppIdAndStatusNot(Long appId, int status, Pageable pageable);
|
||||
|
@ -17,7 +17,7 @@ public interface OmsLockRepository extends JpaRepository<OmsLockDO, Long> {
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query(value = "delete from oms_lock where lock_name = ?1", nativeQuery = true)
|
||||
@Query(value = "delete from OmsLockDO where lockName = ?1")
|
||||
int deleteByLockName(String lockName);
|
||||
|
||||
OmsLockDO findByLockName(String lockName);
|
||||
|
@ -24,7 +24,7 @@ public interface WorkflowInstanceInfoRepository extends JpaRepository<WorkflowIn
|
||||
// 结果只能用 int 接收
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query(value = "delete from workflow_instance_info where gmt_modified < ?1", nativeQuery = true)
|
||||
@Query(value = "delete from WorkflowInstanceInfoDO where gmtModified < ?1")
|
||||
int deleteAllByGmtModifiedBefore(Date time);
|
||||
|
||||
int countByWorkflowIdAndStatusIn(Long workflowId, List<Integer> status);
|
||||
|
@ -15,4 +15,6 @@ spring.servlet.multipart.max-request-size=209715200
|
||||
# akka ActorSystem 服务端口
|
||||
oms.akka.port=10086
|
||||
# 报警服务 bean名称
|
||||
oms.alarm.bean.names=omsDefaultMailAlarmService
|
||||
oms.alarm.bean.names=omsDefaultMailAlarmService
|
||||
# 表前缀
|
||||
#oms.table-prefix=pj_
|
@ -14,6 +14,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
@ -41,6 +42,7 @@ public class RepositoryTest {
|
||||
* 需要证明批量写入失败后会回滚
|
||||
*/
|
||||
@Test
|
||||
@Transactional
|
||||
public void testBatchLock() {
|
||||
|
||||
List<OmsLockDO> locks = Lists.newArrayList();
|
||||
@ -59,6 +61,7 @@ public class RepositoryTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testUpdate() {
|
||||
InstanceInfoDO updateEntity = new InstanceInfoDO();
|
||||
updateEntity.setId(22L);
|
||||
@ -68,6 +71,7 @@ public class RepositoryTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testExecuteLogUpdate() {
|
||||
instanceInfoRepository.update4TriggerFailed(1586310414570L, 2, 100, System.currentTimeMillis(), System.currentTimeMillis(), "192.168.1.1", "NULL", "", new Date());
|
||||
instanceInfoRepository.update4FrequentJob(1586310419650L, 2, 200, new Date());
|
||||
|
@ -33,4 +33,6 @@ oms.log.retention.local=0
|
||||
oms.log.retention.remote=0
|
||||
oms.container.retention.local=0
|
||||
oms.container.retention.remote=0
|
||||
oms.instanceinfo.retention=0;
|
||||
oms.instanceinfo.retention=0;
|
||||
# 表前缀
|
||||
#oms.table-prefix=pj_
|
Loading…
x
Reference in New Issue
Block a user