{"id":630,"date":"2020-09-06T19:05:49","date_gmt":"2020-09-06T17:05:49","guid":{"rendered":"http:\/\/www.valeriofinazzo.it\/wordpress\/?p=630"},"modified":"2020-10-30T17:40:05","modified_gmt":"2020-10-30T16:40:05","slug":"tutorial-go-gestione-del-database","status":"publish","type":"post","link":"http:\/\/www.valeriofinazzo.it\/wordpress\/2020\/09\/tutorial-go-gestione-del-database\/","title":{"rendered":"TUTORIAL GO &#8211; GESTIONE DEL DATABASE"},"content":{"rendered":"\n<p>Nell&#8217;articolo di oggi vedremo come integrare un database oracle e come effettuare le operazione di lettua e scrittura.<\/p>\n\n\n\n<p>Prima di tutto introduciamo il package per la gestione del db database\/sql e insieme al package dobbiamo importare il driver specifico per il database cui connettersi. L&#8217;elenco dei driver disponibili e le relative basi di dati supportati sono disponibili al link <a href=\"https:\/\/github.com\/golang\/go\/wiki\/SQLDrivers\">https:\/\/github.com\/golang\/go\/wiki\/SQLDrivers<\/a>. Per lavoro uso Oracle, pertanto nell&#8217;esempio integro il driver godror. Per poter usare questo driver occorre installarlo e configurarlo nell&#8217;ambiente go tramite la direttiva:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">go get github.com\/godror\/godror<\/pre>\n\n\n\n<p>Il driver \u00e8 realizzato in cgo pertanto \u00e8 richiesta la presenza di un gcc compiler, nel mio caso ho utilizzato quello disponibile all&#8217;indirizzo <a href=\"https:\/\/jmeubank.github.io\/tdm-gcc\/\">https:\/\/jmeubank.github.io\/tdm-gcc\/<\/a>. Maggiori informazioni su godror sono disponibili al l&#8217;url <a href=\"https:\/\/github.com\/godror\/godror\">https:\/\/github.com\/godror\/godror<\/a><\/p>\n\n\n\n<p>Dopo aver installato gcc e godror possiamo finalmente definire l&#8217;import<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import (\n\t\"database\/sql\"\n\t\"fmt\"\n\t_ \"github.com\/godror\/godror\"\n)<\/pre>\n\n\n\n<p>Per la connessione al db il comando da usare \u00e8 Open del package db<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\tdb, err := sql.Open(\"godror\", \"ldc\/ldc@localhost:1521\/xe\")\n\tif err != nil {\n\t\tpanic(err)\n\t}<\/pre>\n\n\n\n<p>Il primo parametro della Open \u00e8 il nome del driver e a seguire la stringa di connessione verso il db nel formato username@password@ip:port:sid<\/p>\n\n\n\n<p>La funzione restituisce una istanza db e come secondo parametro un oggetto error che potr\u00e0 essere gestito tramite la funzione panic.<\/p>\n\n\n\n<p>Vediamo subito come effettuare una operazione di scrittura tramite la funzione Exec<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\ttx, _ := db.Begin()\n\trowsDeleted, err := db.Exec(\"delete from audit_obj where id=1\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(\"rowsDeleted: \", rowsDeleted)\n\n\trowsInserted, err := db.Exec(\"insert into audit_obj (id, dataora, operazione) values(1, sysdate, 'insert')\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(\"rowsInserted: \", rowsInserted)\n\ttx.Commit()<\/pre>\n\n\n\n<p>Nell&#8217;esempio tramite la funzione Begin ho avviato una transazione con commit previsto a fine operazioni di scrittura. Nel caso specifico sto facendo la cancellazione di un record dalla tabella di audit e successivo inserimento  La funzione Exec ritorna un oggetto Result che rappresenta l&#8217;esito di una qualsiasi chiamata al db mostrando quante righe sono state coinvolte e l&#8217;id dell&#8217;ultimo inserimento.<\/p>\n\n\n\n<p>Se volessi leggere i dati mi viene in aiuto la funzione Query che restituisce un cursore che scorre sulle righe selezionate<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\trows, err := db.Query(\"select id, dataora, operazione  from audit_obj\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer rows.Close()\n\n\tvar id int\n\tvar dataora time.Time\n\tvar operazione string\n\tfor rows.Next() {\n\t\trows.Scan(&amp;id, &amp;dataora, &amp;operazione)\n\t\tfmt.Println(id, dataora, operazione)\n\t}\n\tdb.Close()<\/pre>\n\n\n\n<p>Nell&#8217;esempio sto leggenda dalla tabella audit tutti i record e tramite la funzione Scan dell&#8217;oggetto Rows la assegna a delle variabili per stamparne successivamente il valore. Con il comando defer chiudo il cursore alla fine di tutte le operazioni.<\/p>\n\n\n\n<p>Per semplificare il lavoro con il db ci vengono in soccorso altri package che consentono di velocizzare il lavoro. Oggi introduco il package sqlx disponibile all&#8217;url <a href=\"https:\/\/jmoiron.github.io\/sqlx\/\">https:\/\/jmoiron.github.io\/sqlx\/<\/a><\/p>\n\n\n\n<p>Per installarlo il comando \u00e8<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">go get github.com\/jmoiron\/sqlx<\/pre>\n\n\n\n<p>ad installazione effettuata pu\u00f2 essere importato con la direttiva github.com\/jmoiron\/sqlx&#8221;. Questo package consente di mappare le query direttamente su struct senza dover ricorrere al comando Scan.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">type Audit struct {\n\tID      uint64    `db:\"ID\"`\n\tDATAORA time.Time `db:\"DATAORA\"`\n}<\/pre>\n\n\n\n<p>Ho definito una struct Audit che presenta i parametri ID e dataora, ne ho definito il tipo e tramite il thick ho definito il mapping, tramite la regola del contesto:nomecolonna.<\/p>\n\n\n\n<p>A questo punto ottengo il gioco \u00e8 fatto<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\tdbx, err := sqlx.Open(\"godror\", \"ldc\/ldc@localhost:1521\/xe\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar audit Audit\n\terr = dbx.Get(&amp;audit, \"select id, dataora from audit_obj where id = 1\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(audit)\n\n\taudits := []Audit{}\n\tdbx.Select(&amp;audits, \"select id, dataora  from audit_obj\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(audits)<\/pre>\n\n\n\n<p>Con la Open ottengo un riferimento al db che mi espone le funzioni Get per il recupero del singolo oggetto e Select per il recupero di un set di righe,<\/p>\n\n\n\n<p>Alla prossima<\/p>\n\n\n\n<p>ps. per i pigri a seguire l&#8217;intero codice<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">package main\n\nimport (\n\t\"database\/sql\"\n\t\"fmt\"\n\t\"time\"\n\n\t_ \"github.com\/godror\/godror\"\n\t\"github.com\/jmoiron\/sqlx\"\n)\n\ntype Audit struct {\n\tID      uint64    `db:\"ID\"`\n\tDATAORA time.Time `db:\"DATAORA\"`\n}\n\nfunc main() {\n\n\tfmt.Println(\"Start\")\n\n\tdb, err := sql.Open(\"godror\", \"ldc\/ldc@localhost:1521\/xe\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\ttx, _ := db.Begin()\n\tresult, err := db.Exec(\"delete from audit_obj where id=1\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(\"rowsDeleted: \", result)\n\n\tresult, err = db.Exec(\"insert into audit_obj (id, dataora, operazione) values(1, sysdate, 'insert')\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(\"rowsInserted: \", result)\n\ttx.Commit()\n\n\trows, err := db.Query(\"select id, dataora, operazione  from audit_obj\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer rows.Close()\n\n\tvar id int\n\tvar dataora time.Time\n\tvar operazione string\n\tfor rows.Next() {\n\t\trows.Scan(&amp;id, &amp;dataora, &amp;operazione)\n\t\tfmt.Println(id, dataora, operazione)\n\t}\n\tdb.Close()\n\n\tdbx, err := sqlx.Open(\"godror\", \"ldc\/ldc@localhost:1521\/xe\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar audit Audit\n\terr = dbx.Get(&amp;audit, \"select id, dataora from audit_obj where id = 1\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(audit)\n\n\taudits := []Audit{}\n\tdbx.Select(&amp;audits, \"select id, dataora  from audit_obj\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(audits)\n\n\tdbx.Close()\n\tfmt.Println(\"End\")\n\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Nell&#8217;articolo di oggi vedremo come integrare un database oracle e come effettuare le operazione di lettua e scrittura. Prima di tutto introduciamo il package per la gestione del db database\/sql e insieme al package dobbiamo importare il driver specifico per il database cui connettersi. L&#8217;elenco dei driver disponibili e le relative basi di dati supportati &hellip; <a href=\"http:\/\/www.valeriofinazzo.it\/wordpress\/2020\/09\/tutorial-go-gestione-del-database\/\" class=\"more-link\">Continua la lettura di <span class=\"screen-reader-text\">TUTORIAL GO &#8211; GESTIONE DEL DATABASE<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[148],"tags":[135,134,132,133],"_links":{"self":[{"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/posts\/630"}],"collection":[{"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/comments?post=630"}],"version-history":[{"count":1,"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/posts\/630\/revisions"}],"predecessor-version":[{"id":632,"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/posts\/630\/revisions\/632"}],"wp:attachment":[{"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/media?parent=630"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/categories?post=630"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.valeriofinazzo.it\/wordpress\/wp-json\/wp\/v2\/tags?post=630"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}