29 Ağustos 2023 Salı

JDBC DatabaseMetaData.getTables metodu

Giriş
docker-compose.yml şöyle. Yani veri tabanı ismi db
version: '3.9'
services:
  postgresql:
    image: postgres
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: db
    ports:
      - 5432:5432
    volumes:
      - ./postgresql_schema.sql:/docker-entrypoint-initdb.d/postgresql_schema.sql
PostgreSQL açısından bir veri tabanı şeklen şöyle
db
  Schemas
    information_schema <-- Schema ama listelenmiyor
    pg_catalog         <-- Schema ama listelenmiyor
    public
      Tables
        myworker  <-- Ben yarattım
      Views
      Materialized Views
      Indexes
      Functions
      Sequences
      Data types
      Aggregate functions
    myschema
      Tables
        myworker  <-- Ben yarattım
      Views
      Materialized Views
      Indexes
      Functions
      Sequences
      Data types
      Aggregate functions  
public schema altındaki tabloyu yaratmak için şöyle yaptım
CREATE TABLE IF NOT EXISTS myworker (...);
myschema schema altındaki tabloyu yaratmak için şöyle yaptım. Burada DBeaver ile bağlanırken URL olarak jdbc:postgresql://localhost:5432/db verdim.
CREATE SCHEMA myschema

CREATE TABLE IF NOT EXISTS myschema.myworker (...);
Burada önemli bir şey var. public schema için DDL şöyle
CREATE SCHEMA public AUTHORIZATION pg_database_owner;
myschema için DDL şöyle. Yani admin kullanıcısı bu schema'nın sahibi değil
CREATE SCHEMA myschema AUTHORIZATION myuser;
Örnek - catalog değeri geç
Elimizde şöyle bir kod olsun
try (Connection connection = ...;
  ResultSet tables = connection.getMetaData().getTables( connection.getCatalog(),
        null,
        null,
        new String[]{"TABLE", "VIEW"})) {
  ...
}
1. Eğer bağlantı şöyle ise yani veri tabanı belirtilmemişse 
jdbc:postgresql://localhost:5432/
connection.getCatalog() çağrısı "postgres" döner
connection.getSchema() çağrısı "public" döner
ResultSet te boş geliyor. Çünkü postgres diye bir veri tabanı var ama boş

2. Eğer bağlantı şöyle ise yani veri tabanı belirtilmişse
jdbc:postgresql://localhost:5432/db
connection.getCatalog() çağrısı db döner
connection.getSchema() çağrısı "public" döner
ResultSet dolu gelir ve içinde public + myschema schema altında yarattığım tabloları görürüm

Örnek - catalog değeri geçme
Elimizde şöyle bir kod olsun
try (Connection connection = ...;
  ResultSet tables = connection.getMetaData().getTables( null,
        null,
        null,
        new String[]{"TABLE", "VIEW"})) {
  ...
}
Yukarıdaki durumun aynı çıktısını alırım. Yani PostgreSQL açısından catalog belirtilse de belirtilmese de  aynı

Örnek - Veri tabanındaki Tüm Tablolar Yani Database Discovery
Şöyle yaparız. Burada catalog ve schema ve tablaneNamePattern parametreleri belirtilmediği için tüm PostgreSQL schemalarındaki tüm tabloları buluyor. Tabloları buluyor çünkü Types olarak TABLE belirtilmiş. 

İlginç olan şey rs.getString("TABLE_CAT") yapsak bile sonucun null gelmesi. Yani Postgres bir şekilde catalog ismini döndürmüyor
try(ResultSet rs = conn.getMetaData().getTables(null,null,null,new String[] {"TABLE"})) { while (rs.next()) { System.out.println(rs.getString("TABLE_SCHEM") + "." + rs.getString("TABLE_NAME")); } } // Output app96.t1 app96.t2 public.administration$account public.appmodule$uploadedfile public.audittrail$audittrailsuperclass





Hiç yorum yok:

Yorum Gönder