You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在多个含重复代码的Java方法中实现代码复用?附数据库查询代码

解决Java多方法间数据库代码复用的实用方案

针对你在多个包含重复数据库查询逻辑的Java方法里实现代码复用的需求,我整理了几个适配不同场景的方案,你可以根据项目的Java版本和架构来选择:

方案1:利用Java 9+接口私有方法(最推荐)

从Java 9开始,接口支持私有方法,刚好适合把你接口里重复的数据库连接、资源初始化这类逻辑抽出来,既保证复用性,又不会对外暴露这些内部逻辑。

比如修改你的MapReduceDAO接口:

public interface MapReduceDAO {
    String host = "mysql";
    int port = 3306;
    String user = "root";
    String password = "root";
    String dbName = "customers";

    default String customersMysqlUrl(String name) {
        return getDocker().containers().container(name).port(port).inFormat("$HOST:$EXTERNAL_PORT");
    }

    default void checkTableHasData(Duration atMost, String tableName) throws Exception {
        // 直接调用私有复用方法获取查询实例
        try (MysqlQuery mysqlQuery = createMysqlQuery()) {
            // 这里写你的表数据检查逻辑
            // 比如:mysqlQuery.query("SELECT COUNT(*) FROM " + tableName)...
        }
    }

    // 新增私有方法,封装重复的JDBC连接逻辑
    private MysqlQuery createMysqlQuery() throws Exception {
        String jdbcUrl = "jdbc:mysql://" + customersMysqlUrl(host) + "/" + dbName;
        return new MysqlQuery(jdbcUrl, user, password);
    }
}

这样不管后续再新增多少个数据库操作的默认方法,都可以复用createMysqlQuery()的逻辑,不用重复写连接代码。

方案2:抽象类封装通用逻辑(兼容Java 8及以下)

如果你的项目还在使用Java 8,接口不支持私有方法,那可以把通用的常量和复用逻辑放到抽象类里,让DAO实现类继承它:

// 抽象基类,封装所有DAO通用的数据库配置和方法
public abstract class BaseDBDAO {
    protected String host = "mysql";
    protected int port = 3306;
    protected String user = "root";
    protected String password = "root";
    protected String dbName = "customers";

    protected String customersMysqlUrl(String name) {
        return getDocker().containers().container(name).port(port).inFormat("$HOST:$EXTERNAL_PORT");
    }

    protected MysqlQuery createMysqlQuery() throws Exception {
        String jdbcUrl = "jdbc:mysql://" + customersMysqlUrl(host) + "/" + dbName;
        return new MysqlQuery(jdbcUrl, user, password);
    }

    // 定义抽象方法,保持原有业务契约
    public abstract void checkTableHasData(Duration atMost, String tableName) throws Exception;
}

// 你的DAO实现类继承抽象类并实现业务逻辑
public class MapReduceDAOImpl extends BaseDBDAO implements MapReduceDAO {
    @Override
    public void checkTableHasData(Duration atMost, String tableName) throws Exception {
        try (MysqlQuery mysqlQuery = createMysqlQuery()) {
            // 具体的表数据检查逻辑
        }
    }
}

这种方式既兼容低版本Java,又能让所有DAO类复用通用逻辑,避免代码冗余。

方案3:独立工具类抽离通用操作

如果不想改动现有接口或类的继承结构,也可以把通用的数据库操作封装到一个静态工具类里,供所有需要的地方调用:

// 数据库工具类,封装无状态的通用操作
public class DBCommonUtils {
    private static final String host = "mysql";
    private static final int port = 3306;
    private static final String user = "root";
    private static final String password = "root";
    private static final String dbName = "customers";

    public static String getCustomersMysqlUrl(String name) {
        return getDocker().containers().container(name).port(port).inFormat("$HOST:$EXTERNAL_PORT");
    }

    public static MysqlQuery createMysqlQuery() throws Exception {
        String jdbcUrl = "jdbc:mysql://" + getCustomersMysqlUrl(host) + "/" + dbName;
        return new MysqlQuery(jdbcUrl, user, password);
    }
}

// 在你的接口里直接调用工具类方法
public interface MapReduceDAO {
    default void checkTableHasData(Duration atMost, String tableName) throws Exception {
        try (MysqlQuery mysqlQuery = DBCommonUtils.createMysqlQuery()) {
            // 具体逻辑
        }
    }
}

工具类适合那种无状态、通用型极强的逻辑,调用起来简单直接,不过要注意如果涉及到共享资源,要保证线程安全。

总结

  • 如果你用的是Java 9+,优先选接口私有方法,最贴合你现有接口的结构;
  • 低版本Java选抽象类,兼顾兼容性和复用性;
  • 通用逻辑跨多个模块的话,选工具类更灵活。

内容的提问来源于stack exchange,提问作者Saffik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:25:43