代码之家  ›  专栏  ›  技术社区  ›  Steve De Caux

查找已安装的JDBC驱动程序

  •  7
  • Steve De Caux  · 技术社区  · 15 年前

    我在Java中编写一个数据库验证工具,并有偏好屏幕,这样用户就可以定义他们的数据库连接。该工具至少应能处理DB2、Oracle、PostgreSQL和MySQL。

    我真正想要的是能够向用户提供他们安装的JDBC驱动程序列表,作为这个过程的一部分。

    有人能提供一个代码片段来发现已安装的JDBC驱动程序吗?

    3 回复  |  直到 14 年前
        1
  •  9
  •   BalusC    14 年前

    到目前为止,您需要扫描整个类路径(和子文件夹)以查找实现类的类 java.sql.Driver . 这样,您还可以了解 由手动加载 Class#forName() 或自动 META-INF/services .

    下面是一个基本示例:

    public static void main(String[] args) throws Exception {
        List<Class<Driver>> drivers = findClassesImplementing(Driver.class);
        System.out.println(drivers);
    }        
    
    public static <T extends Object> List<Class<T>> findClassesImplementing(Class<T> cls) throws IOException {
        List<Class<T>> classes = new ArrayList<Class<T>>();
    
        for (URL root : Collections.list(Thread.currentThread().getContextClassLoader().getResources(""))) {
            for (File file : findFiles(new File(root.getFile()), ".+\\.jar$")) {
                JarFile jarFile = new JarFile(file);
                for (JarEntry jarEntry : Collections.list(jarFile.entries())) {
                    String name = jarEntry.getName();
                    if (name.endsWith(".class")) try {
                        Class<?> found = Class.forName(name.replace("/", ".").replaceAll("\\.class$", ""));
                        if (cls.isAssignableFrom(found)) {
                            classes.add((Class<T>) found);
                        }
                    } catch (Throwable ignore) {
                        // No real class file, or JAR not in classpath, or missing links.
                    }
                }
            }
        }
    
        return classes;
    }
    
    public static List<File> findFiles(File directory, final String pattern) throws IOException {
        File[] files = directory.listFiles(new FileFilter() {
            public boolean accept(File file) {
                return file.isDirectory() || file.getName().matches(pattern);
            }
        });
    
        List<File> found = new ArrayList<File>(files.length);
    
        for (File file : files) {
            if (file.isDirectory()) {
                found.addAll(findFiles(file, pattern));
            } else {
                found.add(file);
            }
        }
    
        return found;
    }
    

    相反,您也可以考虑使用 Google Reflections API 这一切都在一行中完成:

    Set<Class<? extends Driver>> drivers = reflections.getSubTypesOf(Driver.class);
    
        2
  •  3
  •   Kico Lobo    15 年前

    这将有助于:

    java.sql.DriverManager.getDrivers()
    
        3
  •  3
  •   PeterMmm    15 年前
    java.sql.DriverManager.getDrivers()
    

    并不是全部。

    作为 doc

    检索包含所有 当前加载的JDBC驱动程序 当前呼叫方可以访问的。

    这意味着加载的驱动程序(带有class.forname())没有安装(比如说通过jar可用)。

    通常,您会将您的软件与您的程序可以工作的所有JDBC驱动JAR一起交付。取决于用户将连接到什么(Oracle、Access、DB2),程序必须加载适当的驱动程序。