java读取配置文件例子(多线程更新表数据)

 

config.properties

# config.properties
db.url=jdbc:mysql://192.168.1.14:3306/db_admin?useSSL=false
db.username=root
db.password=123456

 

存放路径

 

LoadConfig.java

package org.hxl.rds;


import java.io.InputStream;
import java.util.Properties;

public class LoadConfig {
    private static String url;
    private static String username;
    private static String password;


    public LoadConfig(){
        LoadConfigData();
    }


    public static void LoadConfigData() {
        try (InputStream input = LoadConfig.class.getClassLoader()
                .getResourceAsStream("config.properties")) {

            Properties prop = new Properties();
            if (input == null) {
                throw new RuntimeException("配置文件 db.properties 未找到");
            }
            prop.load(input);
            url = prop.getProperty("db.url");
            username = prop.getProperty("db.username");
            password = prop.getProperty("db.password");

        } catch (Exception e) {
            throw new RuntimeException("配置文件加载失败", e);
        }
    }

    public String getDbUrl() {
        return url;
    }

    public String getDbUsername() {
        return username;
    }

    public String getDbPassword() {
        return password;
    }

 }

 

DatabaseConnectionPool.java

package org.hxl.rds;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class DatabaseConnectionPool {

    private static final int THREAD_POOL_SIZE = 16;     // 建议CPU核心数*2
    private static HikariDataSource dataSource;

    static LoadConfig lcdata = new LoadConfig();
    static String url = lcdata.getDbUrl();
    static String username = lcdata.getDbUsername();
    static String password = lcdata.getDbPassword();

    static {
        HikariConfig config = new HikariConfig();
        //config.setJdbcUrl("jdbc:mysql://192.168.1.14:3306/db_admin?useSSL=false");
        //config.setUsername("root");
        //config.setPassword("yeemiao1117");

        config.setJdbcUrl(url);
        config.setUsername(username);
        config.setPassword(password);
        config.setMaximumPoolSize(THREAD_POOL_SIZE + 5); // 预留额外连接
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        dataSource = new HikariDataSource(config);
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

 

多线程代码处理

MassiveDataProcessor.java

package org.hxl.rds;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class MassiveDataProcessor {

    private static final String TABLE_NAME = "user";

    //线程与分片配置
    private static final int THREAD_POOL_SIZE = 16;     // 建议CPU核心数*2
    private static final long BATCH_SIZE = 5000;        // 每批次处理量
    private static final int UPDATE_BATCH_SIZE = 1000;   // 批量更新大小

    // 获取主键范围
    private static long[] getIdRange() throws SQLException {

        long IdRange[] = new long[2];
        try {
            Connection conn = DatabaseConnectionPool.getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(
                    "SELECT MIN(id) as min_id, MAX(id) as max_id FROM " + TABLE_NAME);
            if (rs.next()) {
                IdRange[0] = rs.getLong("min_id");
                IdRange[1] = rs.getLong("max_id");
                //return new long[]{rs.getLong("min_id"), rs.getLong("max_id")};
            }
        } catch (SQLException e) {
            throw new RuntimeException("No data in table");
        }
        return IdRange;
    }


    // 数据处理任务
    static class DataProcessTask implements Runnable {
        private final long startId;
        private final long endId;



        public DataProcessTask(long startId, long endId) throws SQLException {
            this.startId = startId;
            this.endId = endId;
        }

        @Override
        public void run() {

            Connection conn = null;
            try {
                conn = DatabaseConnectionPool.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }

            try {

                // 1. 分页查询数据
                String selectSQL = "SELECT id, name FROM " + TABLE_NAME +
                        " WHERE id >= ? AND id<= ? ORDER BY id";

                String updateSQL = "UPDATE " + TABLE_NAME +
                        " SET name = ? WHERE id = ?";


                conn.setAutoCommit(false); // 开启事务

                PreparedStatement selectStmt = conn.prepareStatement(
                        selectSQL, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
                selectStmt.setLong(1, startId);
                selectStmt.setLong(2, endId);

                selectStmt.setFetchSize(1000); // 流式读取防止OOM
                ResultSet rs = selectStmt.executeQuery();


                PreparedStatement updateStmt = conn.prepareStatement(updateSQL);
                int batchCount = 0;
                while (rs.next()) {
                    long id = rs.getLong("id");
                    String data = rs.getString("name");

                    // 3. 业务处理(示例:转换为大写)
                    String processedData = processData(data);

                    // 4. 设置更新参数
                    updateStmt.setString(1, processedData);
                    updateStmt.setLong(2, id);
                    updateStmt.addBatch();

                    // 5. 批量提交
                    if (++batchCount % UPDATE_BATCH_SIZE == 0) {
                        updateStmt.executeBatch();
                        conn.commit();
                        System.out.println("commit ok!");
                    }
                }
                // 提交剩余批次
                updateStmt.executeBatch();
                conn.commit();

            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                  try {
                      conn.close();
                  } catch (SQLException e) {
                      throw new RuntimeException(e);
                  }
              }
        }

        // 示例数据处理函数(需替换实际业务逻辑)
        private String processData(String data) {
            // 实际业务处理逻辑
            //return data != null ? data.toUpperCase() : null;
            return data != null ? "VVVV" : null;
        }
    }

    public static void main(String[] args) {

        Date startDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTime = sdf.format(startDate);
        System.out.println("开始时间:" + startTime);

        try {
            // 1. 获取主键范围
            long[] idRange = getIdRange();
            long minId = idRange[0];
            long maxId = idRange[1];
            System.out.printf("ID Range: %d - %d%n", minId, maxId);

            // 2. 计算分片数量
            long totalRecords = maxId - minId + 1;

            int shards = (int) Math.ceil((double) totalRecords / BATCH_SIZE);

            System.out.println(shards);

            // 3. 创建线程池
            ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);

            // 4. 提交分片处理任务
            for (int i = 0; i < shards; i++) {
                long startId = minId + (i * BATCH_SIZE);
                long endId = Math.min(startId + BATCH_SIZE - 1, maxId);

                System.out.println("startId=" + startId + ",endId=" + endId);

                executor.submit(new DataProcessTask(startId, endId));
                //System.out.println(executor.toString());
            }

            // 5. 优雅关闭
            executor.shutdown();
            executor.awaitTermination(1, TimeUnit.HOURS);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Date endDate = new Date();
        String endTime = sdf.format(endDate);
        System.out.println("结束时间:" + endTime);
    }

}

 

posted @ 2025-06-18 14:08  slnngk  阅读(14)  评论(0)    收藏  举报