How do I persist database objects in Delphi?

6

Work with Delphi, but always procedurally and using Data-Aware components. I recently started reading a few things about working with POO in Delphi, and I've done some pretty basic examples, my doubts are these:

How can I work with a class (TClients for example) doing persistence in the database? How to restore this data for viewing using OO?
How are Data-Aware components?

    
asked by anonymous 09.02.2014 / 16:54

2 answers

4

The diagrams of your DB and its class diagram will be very similar, but be careful not to make confusion when implementing them, each works in a very different way from the other and the number of classes and tables are not necessarily the same .

Consider the following example for an assumed class Cliente :

public class Cliente{ private String nomeCliente; private String endereco; //supondo que cada cliente só possui um endereco private List<String> telefones = new ArrayList<String>(); //0..n telefones //construtor //getters and setters }

First question: do we have ArrayList in class Cliente , how do we store this in BD?

Do not even think about creating a zillion columns in the Clientes table in your DB, like this: telefone1 , telefone2 , telefone3 , ... , telefone1000 . So you have already created some problems like a lot of columns that most of the time will never be used, a horrible table to read and create a diagram, and a limited number of your client's phones (admittedly it's a high limit, but still a limit).

Correct is that you have two tables with the 1..n relationship, so you have one table for the customers and one for the clients' phones. By doing so there will be no records not used causing difficulties in reading them and there will be a limit on the number of phones of each client. The two are linked by a foreign key in the telephone table.

AnexampleimplementationofhowtoloadintoArrayListthephonesofeachclientwouldlooklikethis:

getClientmethod(StringclientName)

prestat = conn.prepareStatement("SELECT * FROM Clientes WHERE nomeCliente=?"); prestat.setString(1, nomeCliente); pw = prestat.executeQuery(); if (pw.next()) { //criando cliente cliente = new Cliente(pw.getString(2), pw.getString(3)); // incluindo telefone do cliente cliente.setTelefones(getTelefonesCliente(pw.getInt(1))); }

method getTelephoneCustomer (int idCustomer)

    List<TelefoneCliente> telefonesCliente = new ArrayList<TelefoneCliente>();

    //..

    prestat = conn.prepareStatement("SELECT * FROM TelefonesCliente WHERE idCliente=?");
    prestat.setInt(1, idCliente);
    pw = prestat.executeQuery();

    while (pw.next()) {
        telefonesCliente.add(pw.getString(3)));
    }

    //..

    return telefonesCliente;

And the problem is solved:)

This solution also makes it easy to expand your program. For example, suppose that once implemented there is a need for you to keep the operator of the customer's phone.

You have two options:

  • You can create another ArrayList in class Cliente , but in my opinion it would be a bit strange, and could even hurt the principle of single responsibility; or
  • You can do what I think is most natural, create a new class:

Note that you will now have two classes and two tables, but the procedure for loading the data into the objects of these classes is very similar to the one mentioned above. This is like homework ;-)

    
11.02.2014 / 11:23
4

You need a framework ORM for Delphi. You can develop yours or use a third party. Some options are:

  • TMS Aurelius (commercial, only supports newer versions of Delphi for using features like generics. The main developer is also Brazilian and can support you in Portuguese.)
  • tiOPF (open source, one of the oldest)
  • DORM (open source, a bit newer, I think it also only supports the newer versions of Delphi)
  • EntityDAC (commercial, announced these days, I think it's still in beta)
  • mORMot Synopsis (which always speak well to me, but seems to be a bit more than an ORM, to have the communication part together, and also never used)
10.02.2014 / 13:11