BG Development


Страници: (2) [1] 2   ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> jdbc драйвер за postgresql
thrawn
Публикувано на: 04-12-2019, 15:51
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2666
Регистриран на: 17.01.17



Настъпих мотика с официалния драйвер на postgresql и сега съм изправен пред дилема: дали да си парсвам сам параметрите или да ползвам друг драйвер.

pgjdbc-ng поддържа всичко каквото ми трябва (а то реално ми трябва само мапване на UDT) но до сега не съм го ползвал. Та ако някой го е ползвал, нека сподели впечатления.
PMEmail Poster
Top
thrawn
Публикувано на: 05-12-2019, 10:35
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2666
Регистриран на: 17.01.17



На първо четене всичко изглеждаше ОК, но нещо се дъни при вмъкване на вложени UDT.
Ето с това например се дъни при insert въпреки, че кодът е генериран с UDP генератора
CODE
public class Person implements SQLData {
   public static final String TYPE_NAME = "public.\"Person\"";

   public static final PGAnyType TYPE = new PGAnyType() {
       @Override
       public String getName() {
           return Person.TYPE_NAME;
       }

       @Override
       public String getVendor() {
           return "UDT Generated";
       }

       @Override
       public Integer getVendorTypeNumber() {
           return null;
       }

       @Override
       public Class getJavaType() {
           return Person.class;
       }
   };

   private String fName;
   private String lName;

   public Person() {
   }

   public Person(String fName, String lName) {
       this.fName = fName;
       this.lName = lName;
   }

   public String getfName() {
       return fName;
   }

   public void setfName(String fName) {
       this.fName = fName;
   }

   public String getlName() {
       return lName;
   }

   public void setlName(String lName) {
       this.lName = lName;
   }

   @Override
   public String getSQLTypeName() throws SQLException {
       return TYPE_NAME;
   }

   @Override
   public void readSQL(SQLInput stream, String typeName) throws SQLException {
       fName = stream.readString();
       lName = stream.readString();
   }

   @Override
   public void writeSQL(SQLOutput stream) throws SQLException {
       stream.writeString(fName);
       stream.writeString(lName);
   }

   @Override
   public String toString() {
       return "Person {" +
               "fName='" + fName + '\'' +
               ", lName='" + lName + '\'' +
               '}';
   }
}

CODE
public class Boss implements SQLData {
   public static final String TYPE_NAME = "public.\"Boss\"";

   public static final PGAnyType TYPE = new PGAnyType() {
       @Override
       public String getName() {
           return Boss.TYPE_NAME;
       }

       @Override
       public String getVendor() {
           return "UDT Generated";
       }

       @Override
       public Integer getVendorTypeNumber() {
           return null;
       }

       @Override
       public Class getJavaType() {
           return Boss.class;
       }
   };

   private Person person;
   private String comment;

   public Boss() {
   }

   public Boss(Person person, String comment) {
       this.person = person;
       this.comment = comment;
   }

   public Person getPerson() {
       return person;
   }

   public void setPerson(Person person) {
       this.person = person;
   }

   public String getComment() {
       return comment;
   }

   public void setComment(String comment) {
       this.comment = comment;
   }

   @Override
   public String getSQLTypeName() throws SQLException {
       return TYPE_NAME;
   }

   @Override
   public void readSQL(SQLInput stream, String typeName) throws SQLException {
       person = stream.readObject(Person.class);
       comment = stream.readString();
   }

   @Override
   public void writeSQL(SQLOutput stream) throws SQLException {
       stream.writeObject(person, Person.TYPE);
       stream.writeString(comment);
   }

   @Override
   public String toString() {
       return "Boss {" +
               "person=" + person +
               ", comment='" + comment + '\'' +
               '}';
   }
}


CODE
query = "insert into t3 values (?, ?)";
try(PreparedStatement statement = connection.prepareStatement(query)) {
    Person person = new Person("ng name 1", "ng name 2");
    Boss boss = new Boss(person, "ng comment");

    statement.setInt(1, 1);
    statement.setObject(2, boss);
    statement.execute();
}

QUOTE
Exception in thread "main" com.impossibl.postgres.jdbc.PGSQLSimpleException: wrong data type: 1043, expected 25


Но пък го чете коректно
CODE
query = "select * from t3";
try(PreparedStatement statement = connection.prepareStatement(query)) {
   try(ResultSet rs = statement.executeQuery()) {
       while (rs.next()) {
           System.out.println(rs.getInt(1));
           System.out.println(rs.getObject(2));
       }
   }
}


Искаше ми се да получа възможно най-пълна автоматизация. За частична не ми се рискува с друг драйвер, затова оставам с официалния.

Това мнение е било редактирано от thrawn на 05-12-2019, 10:36
PMEmail Poster
Top
Gamma Goblin
Публикувано на: 05-12-2019, 11:47
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3045
Регистриран на: 21.02.18



за какво са ти тези сложни работи, ползвай си само стандартните типове


--------------------
https://www.rust-lang.org/
---
" Не може да си на висок пост без да си подкупен. Ще те махнат." - SuN Трола
PMEmail PosterUsers Website
Top
thrawn
Публикувано на: 05-12-2019, 12:44
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2666
Регистриран на: 17.01.17



За хистори данни. Например във фактура имаш доставчик и получател (фирма - булстат, ддс номер, адреси, банкови сметки). Имаш МОЛ, получател и съставил фактурата (човек - имена, адреси ...).

Според каноните на релационните бази данни това са отделни таблици. Но се получава проблем при извличане на данни (заради релациите). В горния документ трябва да се направят 5 join-a. А това спъва производителността.

Решението е денормализация и забиване на данните директно в таблицата. Но ако се ползват стандартните типове то полето "име" например ще се повтори 5 пъти (и съответно му трябват 5 различни перфикса например). И докато за една таблица това горе долу се ядва, то за много си е разправия за поддръжка.
UDT решава идеално тоя проблем, като забива всичко в едно поле но запазва възможността за директна работа с отделните "подполета". Демек, получаваш предимствата на документните nosql бази данни в релационна база данни.

От своя страна JDBC декларира интерфейси за работа с UDT. Но пък официалния драйвер на postgresql не имплементира тия екстри. Там единствения вариант за директна работа с такива данни е да се ползва PGobject който да се създава/чете с външен парсер.
PMEmail Poster
Top
40oz
Публикувано на: 05-12-2019, 13:29
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 347
Регистриран на: 23.05.13



json?
PMEmail Poster
Top
thrawn
Публикувано на: 05-12-2019, 13:42
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2666
Регистриран на: 17.01.17



По принцип става, но в java няма стандартен начин за парсване на json та пак стигаме да парсване на данните.
Предимството на UDT е, че можеш да го записваш/четеш и директно с примитиви.

Например
SQL
insert into t3 values (?, ?)

може да се замени с
SQL
insert into t3 values (?, (?, ?))


а четенето
SQL
select * from t3

с
SQL
select id, (p::Person).* from t3


Това мнение е било редактирано от thrawn на 05-12-2019, 13:43
PMEmail Poster
Top
40oz
Публикувано на: 05-12-2019, 14:07
Quote Post



Име:
Група: Потребител
Ранг: Редовен член

Мнения: 347
Регистриран на: 23.05.13



QUOTE (thrawn @ 05-12-2019, 13:42)
По принцип става, но в java няма стандартен начин за парсване на json та пак стигаме да парсване на данните.
Предимството на UDT е, че можеш да го записваш/четеш и директно с примитиви.

Ти искаш да не ползваш външни библиотеки ли? Аз не съм виждал някъде да се ползват тея UDT в продъкшън. Postgres-a задобря много с json в последните версии, така че прецени добре спрямо твоя случай. Също ако искаш да добавиш ново поленце на person, на колко места трябва да разбуташ с тоя подход?
PMEmail Poster
Top
Gamma Goblin
Публикувано на: 05-12-2019, 14:12
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3045
Регистриран на: 21.02.18



Какъв е проблема с 5тте джойна ? Правиш си правилните индекси и не ти пука.


--------------------
https://www.rust-lang.org/
---
" Не може да си на висок пост без да си подкупен. Ще те махнат." - SuN Трола
PMEmail PosterUsers Website
Top
thrawn
Публикувано на: 05-12-2019, 14:44
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2666
Регистриран на: 17.01.17



QUOTE (40oz @ 05-12-2019, 14:07)
QUOTE (thrawn @ 05-12-2019, 13:42)
По принцип става, но в java няма стандартен начин за парсване на json та пак стигаме да парсване на данните.
Предимството на UDT е, че можеш да го записваш/четеш и директно с примитиви.

Ти искаш да не ползваш външни библиотеки ли? Аз не съм виждал някъде да се ползват тея UDT в продъкшън. Postgres-a задобря много с json в последните версии, така че прецени добре спрямо твоя случай. Също ако искаш да добавиш ново поленце на person, на колко места трябва да разбуташ с тоя подход?

Само на едно - променяш дефиницията на типа, то това е и идеята. Да не говорим, че имаш стриктно типизиране на полето.
Иначе, като цяло не искам да ползвам външи библиотеки за форматиране на заявката към базата данни (с цел безопасност все пак). Държа да работя с prepared statement.

Макар че, в края на краищата дали ще е UDT или json все минава през prepared statement като стринг...

---
@Gamma Goblin, индексирането подобрява нещата. Но четенето без join винаги е по-бързо. Представи си 10 годишна база данни как ги свързва тия таблици, при положение, че винаги релацията им е 1:1. Това просто е излишна операция (5 излишни операции).

Това мнение е било редактирано от thrawn на 05-12-2019, 14:48
PMEmail Poster
Top
dvader
Публикувано на: 05-12-2019, 15:39
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 4638
Регистриран на: 12.07.05



Тя ако релацията е 1:1 то защо изобщо има външна таблица?
По-скоро е Х:1 та подозирам, излишните операции ще са добре кеширани...


--------------------
I find your lack of faith disturbing
PM
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (2) [1] 2  Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0