潮州人医患者基础信息同步程序初始化

master
linjj 2 months ago
commit d6adfb1b44

38
.gitignore vendored

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chaozhou</groupId>
<artifactId>emr_sync_czry</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer />
<transformer>
<mainClass>com.chaozhou.ArchiveSync</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chaozhou</groupId>
<artifactId>emr_sync_czry</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Oracle JDBC 核心驱动 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.database.nls/orai18n -->
<dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
<version>21.3.0.0</version>
</dependency>
<!-- SQL Server JDBC -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>11.2.1.jre8</version>
</dependency>
<!-- Lombok@Slf4j-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!-- LogbackSLF4J 实现)-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<!-- 打胖 jar含依赖 + Main-Class并修复 SPI + 去签名 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- 合并 META-INF/services 防止 JDBC SPI 丢失 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<!-- 指定启动类 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.chaozhou.ArchiveSync</mainClass>
</transformer>
</transformers>
<!-- 剔除签名文件,避免 SecurityException -->
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,167 @@
package com.chaozhou;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
/**
* @ClassName ArchiveSync
* @Description
* @Author linjj
* @Date 2025/9/26 16:17
* @Version 1.0
*/
@Slf4j
public class ArchiveSync {
/* 读取当天全部病例 */
private static final String SQL_ORA_TODAY =
"SELECT ID号,住院号,住院次数,姓名,性别,入院时间,入院科室编码," +
"主管医生工号,年龄,身份证号,出院日期,当前科室编码 " +
"FROM PORTAL_HIS.V_WZHGD_HZJCXX h " +
"WHERE 出院日期 >= TRUNC(SYSDATE) " + // 今天 00:00:00
"AND 出院日期 < TRUNC(SYSDATE) + 1"; // 明天 00:00:00不含
// /* 读取 9 月 25 日到今天的全部病例 */
// private static final String SQL_ORA_TODAY =
// "SELECT ID号,住院号,住院次数,姓名,性别,入院时间,入院科室编码," +
// " 主管医生工号,年龄,身份证号,出院日期,当前科室编码 " +
// "FROM PORTAL_HIS.V_WZHGD_HZJCXX h " +
// "WHERE 出院日期 >= TO_DATE('2025-09-25', 'YYYY-MM-DD') " +
// "AND 出院日期 <= TRUNC(SYSDATE)";
/* SQL Server当天已归档主键 */
private static final String SQL_MSS_TODAY_KEYS =
"SELECT inp_no + '|' + CAST(visit_id AS VARCHAR) AS key1 " +
"FROM archive_master " +
"WHERE CONVERT(date, discharge_date_time) = CONVERT(date, GETDATE())";
// /* SQL Server9 月 25 日到今天已归档主键 */
// private static final String SQL_MSS_TODAY_KEYS =
// "SELECT inp_no + '|' + CAST(visit_id AS VARCHAR) AS key1 " +
// "FROM archive_master " +
// "WHERE CONVERT(date, discharge_date_time) >= '2025-09-25' " +
// "AND CONVERT(date, discharge_date_time) <= CONVERT(date, GETDATE())";
/* 写入 SQL Server */
private static final String SQL_MSS_INSERT =
"INSERT INTO archive_master " +
"(id, patient_id, inp_no, visit_id, name, sex, dept_admission_to, " +
" admission_date_time, discharge_date_time, DOCTOR_IN_CHARGE, SubAssort, ID_NO, " +
" dept_name,id_card,ArchiveState,C1) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, '64','ljj')";
/* 当前最大 id */
private static final String SQL_MAX_ID = "SELECT ISNULL(MAX(id), 0) FROM archive_master";
public static void main(String[] args) throws Exception {
Properties cfg = new Properties();
try (InputStream in = ArchiveSync.class.getResourceAsStream("/application.properties")) {
cfg.load(in);
}
while (true) {
try (Connection ora = getConn(cfg, "oracle");
Connection mss = getConn(cfg, "sqlserver");
PreparedStatement psOra = ora.prepareStatement(SQL_ORA_TODAY);
PreparedStatement psKeys = mss.prepareStatement(SQL_MSS_TODAY_KEYS);
PreparedStatement psMaxId = mss.prepareStatement(SQL_MAX_ID);
PreparedStatement psIns = mss.prepareStatement(SQL_MSS_INSERT)) {
/*取 SQL Server 当天已归档主键 */
Set<String> archivedToday = new HashSet<>();
try (ResultSet rs = psKeys.executeQuery()) {
while (rs.next()) archivedToday.add(rs.getString(1));
}
log.info("SQL Server 当天已存在 {} 条", archivedToday.size());
/* 获取当前最大 id */
ResultSet rsMax = psMaxId.executeQuery();
rsMax.next();
long baseId = rsMax.getLong(1);
rsMax.close();
/*查询 Oracle 缺失数据 */
ResultSet rs = psOra.executeQuery();
int total = 0, insert = 0;
while (rs.next()) {
total++;
String key = rs.getString("住院号") + "|" + rs.getString("住院次数");
if (archivedToday.contains(key)) continue; // 已归档,跳过
psIns.setLong(1, baseId + (++insert)); // id
psIns.setString(2, rs.getString("ID号")); // patient_id
psIns.setString(3, rs.getString("住院号")); // inp_no
psIns.setString(4, rs.getString("住院次数")); // visit_id
psIns.setNString(5, rs.getString("姓名")); // name
// 取出 Oracle 值
String sexOra = rs.getString("性别");
// 字典转换
String sexMss;
if (sexOra == null || sexOra.trim().isEmpty()) {
sexMss = "不详";
} else if ("1".equals(sexOra)) {
sexMss = "男";
} else if ("2".equals(sexOra)) {
sexMss = "女";
} else {
sexMss = sexOra;
}
psIns.setNString(6, sexMss); // 对应 archive_master.sex
psIns.setNString(7, rs.getString("入院科室编码")); // dept_admission_to
psIns.setTimestamp(8, rs.getTimestamp("入院时间")); // admission_date_time
psIns.setTimestamp(9, rs.getTimestamp("出院日期")); // discharge_date_time
psIns.setString(10, rs.getString("主管医生工号")); // DOCTOR_IN_CHARGE
psIns.setNString(11, rs.getString("年龄")); // SubAssort
psIns.setString(12, rs.getString("身份证号")); // id_card
psIns.setString(13, rs.getString("当前科室编码")); // dept_name
psIns.setString(14, rs.getString("身份证号")); // ID_NO
psIns.addBatch();
if (insert % 1000 == 0) psIns.executeBatch();
}
if (insert % 1000 != 0) psIns.executeBatch();
mss.commit();
log.info("Oracle 当天共 {} 条,缺失 {} 条,已插入 {} 条", total, insert, insert);
} catch (SQLException e) {
log.error("同步异常", e);
Thread.sleep(5000);
}
Thread.sleep(Integer.parseInt(System.getProperty("poll.interval", "30")) * 1000L);
}
}
/* 工具:根据前缀拿连接 */
private static Connection getConn(Properties cfg, String db) throws SQLException {
String url = cfg.getProperty(db + ".url");
String user = cfg.getProperty(db + ".user");
String pwd = cfg.getProperty(db + ".password");
return DriverManager.getConnection(url, user, pwd);
}
}

@ -0,0 +1,7 @@
package com.chaozhou;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

@ -0,0 +1,11 @@
oracle.url=jdbc:oracle:thin:@//172.16.11.110:1521/bsrun
oracle.user=wzhgd_js
oracle.password=cz3261
sqlserver.url=jdbc:sqlserver://localhost:1433;databaseName=emr_record;encrypt=false
sqlserver.user=sa
sqlserver.password=docus@702
#???????
poll.interval=300

@ -0,0 +1,13 @@
<configuration>
<!-- 控制台彩色输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 根日志级别 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Loading…
Cancel
Save