Commit 29626cdd by 刘栋

更新代码

parent 6d04a535
......@@ -13,6 +13,8 @@ import net.sf.jsqlparser.expression.LongValue;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component
public class CustomTenantHandler implements TenantLineHandler {
......@@ -21,6 +23,9 @@ public class CustomTenantHandler implements TenantLineHandler {
// 假设有一个租户上下文,能够从中获取当前用户的租户
Long identityId = SpringContextUtils.getIdentityId();
// 返回租户ID的表达式
if(Objects.isNull(identityId)){
return new LongValue(0);
}
return new LongValue(identityId);
}
......@@ -38,6 +43,9 @@ public class CustomTenantHandler implements TenantLineHandler {
if(StringUtils.equals("udi_user",tableName)){
return true;
}
if(StringUtils.equals("sys_file",tableName)){
return true;
}
return false;
}
......
package com.infynova.udi.config.mybatis;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
......@@ -41,16 +42,19 @@ public class MybatisPlusConfig {
return interceptor;
}
// @Bean
// public ISqlInjector sqlInjector() {
// return new DefaultSqlInjector() {
// @Override
// public List<AbstractMethod> getMethodList(org.apache.ibatis.session.Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
// List<AbstractMethod> methodList = super.getMethodList(configuration,mapperClass,tableInfo);
// methodList.add(new InsertBatchSomeColumn());
// methodList.add(new AlwaysUpdateSomeColumnById());
// return methodList;
// }
// };
// }
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
// 添加 InsertBatchSomeColumn 方法,跳过 FieldFill.UPDATE 或 FieldFill.DEFAULT 的字段
methodList.add(new InsertBatchSomeColumn(column -> column.getFieldFill() != FieldFill.UPDATE));
return methodList;
}
}
@Bean
public MySqlInjector sqlInjector() {
return new MySqlInjector();
}
}
......@@ -17,7 +17,7 @@ import javax.servlet.http.HttpServletResponse;
@Slf4j
@RestController
@RequestMapping("oss")
@RequestMapping("/oss")
@Api(tags = "图片上传")
public class OSSController {
......@@ -28,7 +28,7 @@ public class OSSController {
private LocalFileStorage localFileStorage;
@ApiOperation(value = "下载文件")
@GetMapping(value = "downloadFile")
@GetMapping(value = "/downloadFile")
@SneakyThrows
public void downloadFile(@RequestParam("fileId") Long fileId, HttpServletResponse response) {
SysFile sysFile = sysFileService.getById(fileId);
......
......@@ -73,6 +73,8 @@ public class IdentityFilter implements Filter {
Map<String, String> headers = new HashMap<>();
Set<String> configPathList = new HashSet<>();
configPathList.add("/udi/user/token");
configPathList.add("/udi/match/task/template");
configPathList.add("/udi/oss/downloadFile");
if (!checkPath(httpRequest.getRequestURI(), configPathList)) {
if (StrUtil.isBlank(token)) {
throw new SaasException(CommonExceptionCode.JWT_ILLEGAL_ARGUMENT);
......
......@@ -59,7 +59,7 @@ public class FileStorageProperties {
/**
* 下载接口地址
*/
private String downloadUrl = "";
private String downloadUrl = "http://127.0.0.1/api/udi/oss/downloadFile";
/**
* 存储空间
*/
......
package com.infynova.udi.service.helper;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class UdiDataMigrator {
// 数据库配置
private static final String SOURCE_JDBC_URL = "jdbc:mysql://rm-wz92456b388ahxujbuo.mysql.rds.aliyuncs.com:3306/saas_base_test?useCursorFetch=true";
private static final String SOURCE_USER = "saas_test";
private static final String SOURCE_PASSWORD = "qjCEgXg2z9U5mjL7";
private static final String TARGET_JDBC_URL = "jdbc:mysql://localhost:3306/saas_udi?rewriteBatchedStatements=true";
private static final String TARGET_USER = "root";
private static final String TARGET_PASSWORD = "Xhe6aiNgi8ehaZgh";
// 分批参数
private static final int ID_RANGE_SIZE = 50000; // ID范围分片大小
private static final int INSERT_BATCH_SIZE = 2000; // 插入批次大小
private HikariDataSource sourceDataSource;
private HikariDataSource targetDataSource;
public static void main(String[] args) {
UdiDataMigrator migrator = new UdiDataMigrator();
try {
migrator.initialize();
migrator.migrate();
} catch (Exception e) {
e.printStackTrace();
} finally {
migrator.shutdown();
}
}
private void initialize() {
// 初始化源数据库连接池
HikariConfig sourceConfig = new HikariConfig();
sourceConfig.setJdbcUrl(SOURCE_JDBC_URL);
sourceConfig.setUsername(SOURCE_USER);
sourceConfig.setPassword(SOURCE_PASSWORD);
sourceConfig.setMaximumPoolSize(10);
sourceConfig.setConnectionTimeout(TimeUnit.SECONDS.toMillis(30));
sourceDataSource = new HikariDataSource(sourceConfig);
// 初始化目标数据库连接池
HikariConfig targetConfig = new HikariConfig();
targetConfig.setJdbcUrl(TARGET_JDBC_URL);
targetConfig.setUsername(TARGET_USER);
targetConfig.setPassword(TARGET_PASSWORD);
targetConfig.setMaximumPoolSize(20);
targetConfig.setConnectionTimeout(TimeUnit.SECONDS.toMillis(30));
targetDataSource = new HikariDataSource(targetConfig);
}
private void migrate() throws SQLException {
long[] minMaxIds = getMinMaxIds();
long minId = minMaxIds[0];
long maxId = minMaxIds[1];
System.out.printf("开始数据迁移,ID范围: %d - %d (共%d条)%n",
minId, maxId, maxId - minId + 1);
for (long currentStart = minId; currentStart <= maxId; currentStart += ID_RANGE_SIZE) {
long currentEnd = Math.min(currentStart + ID_RANGE_SIZE - 1, maxId);
processIdRange(currentStart, currentEnd);
System.out.printf("已完成ID范围: %d - %d%n", currentStart, currentEnd);
}
}
private long[] getMinMaxIds() throws SQLException {
try (Connection conn = sourceDataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT MIN(id) AS min_id, MAX(id) AS max_id FROM product")) {
if (rs.next()) {
return new long[]{rs.getLong("min_id"), rs.getLong("max_id")};
}
throw new SQLException("无法获取最小/最大ID");
}
}
private void processIdRange(long startId, long endId) {
String querySql = "SELECT * FROM product WHERE id BETWEEN ? AND ?";
try (Connection sourceConn = sourceDataSource.getConnection();
PreparedStatement queryStmt = sourceConn.prepareStatement(
querySql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
queryStmt.setFetchSize(1000);
queryStmt.setLong(1, startId);
queryStmt.setLong(2, endId);
try (ResultSet rs = queryStmt.executeQuery()) {
processResultSet(rs);
}
} catch (SQLException e) {
throw new RuntimeException("处理ID范围失败: " + startId + "-" + endId, e);
}
}
private void processResultSet(ResultSet rs) throws SQLException {
try (Connection targetConn = targetDataSource.getConnection()) {
targetConn.setAutoCommit(false);
List<Udi> batch = new ArrayList<>(INSERT_BATCH_SIZE);
String insertSql = buildInsertSql(rs.getMetaData());
try (PreparedStatement insertStmt = targetConn.prepareStatement(insertSql)) {
while (rs.next()) {
batch.add(extractUdi(rs));
if (batch.size() >= INSERT_BATCH_SIZE) {
executeBatchInsert(insertStmt, batch);
targetConn.commit();
batch.clear();
}
}
// 插入剩余记录
if (!batch.isEmpty()) {
executeBatchInsert(insertStmt, batch);
targetConn.commit();
}
} catch (SQLException e) {
targetConn.rollback();
throw e;
}
}
}
private String buildInsertSql(ResultSetMetaData meta) throws SQLException {
StringBuilder sql = new StringBuilder("INSERT INTO product (");
// 构建列名部分
sql.append("id, udi_code, yi_bao_one_code, yi_bao_two_code, yi_bao_code, ")
.append("yi_bao_code_prefix, company_name, brand_name, registry_no, ")
.append("registry_name, registry_start_time, registry_end_time, registry, ")
.append("product_code, product_factory_code, infynova_code, product_name, ")
.append("product_type, specification, model, material, aseptic_packaging, ")
.append("before_sterilize, sterilization_method, yj_foreign_id, yb_foreign_id, ")
.append("source_name, create_time, update_time, version) ");
// 构建VALUES部分
sql.append("VALUES (");
for (int i = 1; i <= 30; i++) { // 共30个字段
sql.append("?");
if (i < 30) sql.append(",");
}
sql.append(")");
return sql.toString();
}
private Udi extractUdi(ResultSet rs) throws SQLException {
Udi udi = new Udi();
// 设置基本字段
udi.setId(rs.getLong("id"));
udi.setUdiCode(rs.getString("udi_code"));
udi.setYiBaoOneCode(rs.getString("yi_bao_one_code"));
udi.setYiBaoTwoCode(rs.getString("yi_bao_two_code"));
udi.setYiBaoCode(rs.getString("yi_bao_code"));
udi.setYiBaoCodePrefix(rs.getString("yi_bao_code_prefix"));
udi.setCompanyName(rs.getString("company_name"));
udi.setBrandName(rs.getString("brand_name"));
udi.setRegistryNo(rs.getString("registry_no"));
udi.setRegistryName(rs.getString("registry_name"));
// 处理日期字段
Date registryStartDate = rs.getDate("registry_start_time");
if (registryStartDate != null) {
udi.setRegistryStartTime(registryStartDate.toLocalDate());
}
Date registryEndDate = rs.getDate("registry_end_time");
if (registryEndDate != null) {
udi.setRegistryEndTime(registryEndDate.toLocalDate());
}
udi.setRegistry(rs.getString("registry"));
udi.setProductCode(rs.getString("product_code"));
udi.setProductFactoryCode(rs.getString("product_factory_code"));
udi.setInfynovaCode(rs.getString("infynova_code"));
udi.setProductName(rs.getString("product_name"));
udi.setProductType(rs.getString("product_type"));
udi.setSpecification(rs.getString("specification"));
udi.setModel(rs.getString("model"));
udi.setMaterial(rs.getString("material"));
// 处理布尔字段
udi.setAsepticPackaging(rs.getBoolean("aseptic_packaging"));
if (rs.wasNull()) udi.setAsepticPackaging(null);
udi.setBeforeSterilize(rs.getBoolean("before_sterilize"));
if (rs.wasNull()) udi.setBeforeSterilize(null);
udi.setSterilizationMethod(rs.getString("sterilization_method"));
udi.setYjForeignId(rs.getString("yj_foreign_id"));
udi.setYbForeignId(rs.getString("yb_foreign_id"));
udi.setSourceName(rs.getString("source_name"));
// 处理时间戳字段
Timestamp createTimestamp = rs.getTimestamp("create_time");
if (createTimestamp != null) {
udi.setCreateTime(createTimestamp.toLocalDateTime());
}
Timestamp updateTimestamp = rs.getTimestamp("update_time");
if (updateTimestamp != null) {
udi.setUpdateTime(updateTimestamp.toLocalDateTime());
}
udi.setVersion(rs.getString("version"));
return udi;
}
private void executeBatchInsert(PreparedStatement stmt, List<Udi> batch)
throws SQLException {
for (Udi udi : batch) {
int paramIndex = 1;
stmt.setLong(paramIndex++, udi.getId());
setStringOrNull(stmt, paramIndex++, udi.getUdiCode());
setStringOrNull(stmt, paramIndex++, udi.getYiBaoOneCode());
setStringOrNull(stmt, paramIndex++, udi.getYiBaoTwoCode());
setStringOrNull(stmt, paramIndex++, udi.getYiBaoCode());
setStringOrNull(stmt, paramIndex++, udi.getYiBaoCodePrefix());
setStringOrNull(stmt, paramIndex++, udi.getCompanyName());
setStringOrNull(stmt, paramIndex++, udi.getBrandName());
setStringOrNull(stmt, paramIndex++, udi.getRegistryNo());
setStringOrNull(stmt, paramIndex++, udi.getRegistryName());
setDateOrNull(stmt, paramIndex++, udi.getRegistryStartTime());
setDateOrNull(stmt, paramIndex++, udi.getRegistryEndTime());
setStringOrNull(stmt, paramIndex++, udi.getRegistry());
setStringOrNull(stmt, paramIndex++, udi.getProductCode());
setStringOrNull(stmt, paramIndex++, udi.getProductFactoryCode());
setStringOrNull(stmt, paramIndex++, udi.getInfynovaCode());
setStringOrNull(stmt, paramIndex++, udi.getProductName());
setStringOrNull(stmt, paramIndex++, udi.getProductType());
setStringOrNull(stmt, paramIndex++, udi.getSpecification());
setStringOrNull(stmt, paramIndex++, udi.getModel());
setStringOrNull(stmt, paramIndex++, udi.getMaterial());
setBooleanOrNull(stmt, paramIndex++, udi.getAsepticPackaging());
setBooleanOrNull(stmt, paramIndex++, udi.getBeforeSterilize());
setStringOrNull(stmt, paramIndex++, udi.getSterilizationMethod());
setStringOrNull(stmt, paramIndex++, udi.getYjForeignId());
setStringOrNull(stmt, paramIndex++, udi.getYbForeignId());
setStringOrNull(stmt, paramIndex++, udi.getSourceName());
setTimestampOrNull(stmt, paramIndex++, udi.getCreateTime());
setTimestampOrNull(stmt, paramIndex++, udi.getUpdateTime());
setStringOrNull(stmt, paramIndex++, udi.getVersion());
stmt.addBatch();
}
stmt.executeBatch();
}
// 辅助方法:处理可能为null的字符串
private void setStringOrNull(PreparedStatement stmt, int index, String value)
throws SQLException {
if (value != null) {
stmt.setString(index, value);
} else {
stmt.setNull(index, Types.VARCHAR);
}
}
// 辅助方法:处理可能为null的日期
private void setDateOrNull(PreparedStatement stmt, int index, LocalDate date)
throws SQLException {
if (date != null) {
stmt.setDate(index, Date.valueOf(date));
} else {
stmt.setNull(index, Types.DATE);
}
}
// 辅助方法:处理可能为null的布尔值
private void setBooleanOrNull(PreparedStatement stmt, int index, Boolean value)
throws SQLException {
if (value != null) {
stmt.setBoolean(index, value);
} else {
stmt.setNull(index, Types.BOOLEAN);
}
}
// 辅助方法:处理可能为null的时间戳
private void setTimestampOrNull(PreparedStatement stmt, int index, LocalDateTime dateTime)
throws SQLException {
if (dateTime != null) {
stmt.setTimestamp(index, Timestamp.valueOf(dateTime));
} else {
stmt.setNull(index, Types.TIMESTAMP);
}
}
private void shutdown() {
if (sourceDataSource != null && !sourceDataSource.isClosed()) {
sourceDataSource.close();
}
if (targetDataSource != null && !targetDataSource.isClosed()) {
targetDataSource.close();
}
}
// 简化的Udi类,仅包含字段和getter/setter
static class Udi {
private Long id;
private String udiCode;
private String yiBaoOneCode;
private String yiBaoTwoCode;
private String yiBaoCode;
private String yiBaoCodePrefix;
private String companyName;
private String brandName;
private String registryNo;
private String registryName;
private LocalDate registryStartTime;
private LocalDate registryEndTime;
private String registry;
private String productCode;
private String productFactoryCode;
private String infynovaCode;
private String productName;
private String productType;
private String specification;
private String model;
private String material;
private Boolean asepticPackaging;
private Boolean beforeSterilize;
private String sterilizationMethod;
private String yjForeignId;
private String ybForeignId;
private String sourceName;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private String version;
// Getter和Setter方法
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUdiCode() { return udiCode; }
public void setUdiCode(String udiCode) { this.udiCode = udiCode; }
public String getYiBaoOneCode() { return yiBaoOneCode; }
public void setYiBaoOneCode(String yiBaoOneCode) { this.yiBaoOneCode = yiBaoOneCode; }
public String getYiBaoTwoCode() { return yiBaoTwoCode; }
public void setYiBaoTwoCode(String yiBaoTwoCode) { this.yiBaoTwoCode = yiBaoTwoCode; }
public String getYiBaoCode() { return yiBaoCode; }
public void setYiBaoCode(String yiBaoCode) { this.yiBaoCode = yiBaoCode; }
public String getYiBaoCodePrefix() { return yiBaoCodePrefix; }
public void setYiBaoCodePrefix(String yiBaoCodePrefix) { this.yiBaoCodePrefix = yiBaoCodePrefix; }
public String getCompanyName() { return companyName; }
public void setCompanyName(String companyName) { this.companyName = companyName; }
public String getBrandName() { return brandName; }
public void setBrandName(String brandName) { this.brandName = brandName; }
public String getRegistryNo() { return registryNo; }
public void setRegistryNo(String registryNo) { this.registryNo = registryNo; }
public String getRegistryName() { return registryName; }
public void setRegistryName(String registryName) { this.registryName = registryName; }
public LocalDate getRegistryStartTime() { return registryStartTime; }
public void setRegistryStartTime(LocalDate registryStartTime) { this.registryStartTime = registryStartTime; }
public LocalDate getRegistryEndTime() { return registryEndTime; }
public void setRegistryEndTime(LocalDate registryEndTime) { this.registryEndTime = registryEndTime; }
public String getRegistry() { return registry; }
public void setRegistry(String registry) { this.registry = registry; }
public String getProductCode() { return productCode; }
public void setProductCode(String productCode) { this.productCode = productCode; }
public String getProductFactoryCode() { return productFactoryCode; }
public void setProductFactoryCode(String productFactoryCode) { this.productFactoryCode = productFactoryCode; }
public String getInfynovaCode() { return infynovaCode; }
public void setInfynovaCode(String infynovaCode) { this.infynovaCode = infynovaCode; }
public String getProductName() { return productName; }
public void setProductName(String productName) { this.productName = productName; }
public String getProductType() { return productType; }
public void setProductType(String productType) { this.productType = productType; }
public String getSpecification() { return specification; }
public void setSpecification(String specification) { this.specification = specification; }
public String getModel() { return model; }
public void setModel(String model) { this.model = model; }
public String getMaterial() { return material; }
public void setMaterial(String material) { this.material = material; }
public Boolean getAsepticPackaging() { return asepticPackaging; }
public void setAsepticPackaging(Boolean asepticPackaging) { this.asepticPackaging = asepticPackaging; }
public Boolean getBeforeSterilize() { return beforeSterilize; }
public void setBeforeSterilize(Boolean beforeSterilize) { this.beforeSterilize = beforeSterilize; }
public String getSterilizationMethod() { return sterilizationMethod; }
public void setSterilizationMethod(String sterilizationMethod) { this.sterilizationMethod = sterilizationMethod; }
public String getYjForeignId() { return yjForeignId; }
public void setYjForeignId(String yjForeignId) { this.yjForeignId = yjForeignId; }
public String getYbForeignId() { return ybForeignId; }
public void setYbForeignId(String ybForeignId) { this.ybForeignId = ybForeignId; }
public String getSourceName() { return sourceName; }
public void setSourceName(String sourceName) { this.sourceName = sourceName; }
public LocalDateTime getCreateTime() { return createTime; }
public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
public LocalDateTime getUpdateTime() { return updateTime; }
public void setUpdateTime(LocalDateTime updateTime) { this.updateTime = updateTime; }
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
}
}
......@@ -30,6 +30,7 @@ docker创建服务需要注意网关设置
docker run -d --name es -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" -e "discovery.type=single-node" --privileged --net esnet -p 9200:9200 -p 9300:9300 elasticsearch:7.12.1
docker run -d --name kibana -e ELASTICSEARCH_HOSTS=http://es:9200 --net esnet -p 5601:5601 kibana:7.12.1
```
## Linux创建注意
......@@ -46,6 +47,9 @@ curl 127.0.0.1:9200
linux安装要确认好是否提供外部服务
---
ik分词安装注意事项
与es版本对齐,在对应的文件夹plugins创建ik文件夹,然后上传zip,解压即可;
---
## 创建索引
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment