GoLang : Using sqlx for record mapping into Structs
When working with GoLang and retrieving records from a database, this is typically done by retrieving a row and then parsing it to extract the various attributes and then in turn mapping them to variables to to a struct. For example, the following code shows the executing a query and then parsing the rows to process the returned attributes and assigning them to a variable.
import ( "fmt" "time" "database/sql" godror "github.com/godror/godror" ) func main(){ username := <username>; password := <password>; host := <host>:<port>; database := <database name>; <code to create the connection - didn't include to save space> dbQuery := "select table_name, tablespace_name from user_tables where table_name not like 'DM$%' and table_name not like 'ODMR$%'" rows, err := db.Query(dbQuery) if err != nil { fmt.Println(".....Error processing query") fmt.Println(err) return } defer rows.Close() fmt.Println("... Parsing query results") var tableName string for rows.Next() { rows.Scan(&tableName) fmt.Println(tableName) } <code to close the connection - didn't include to save space> }
As you can see this can add additional lines of code and corresponding debugging.
With the sqlx golang package, we can use their functionality to assign the query results to a struct. This simplifies the coding. The above code becomes the following:
import (
"fmt"
"time"
"database/sql"
godror "github.com/godror/godror"
"github.com/jmoiron/sqlx"
)
type TableDetails struct {
Table string 'db:"TABLE_NAME"'
Tablespace string 'db:"TABLESPACE_NAME"'
}
func main(){
username := <username>;
password := <password>;
host := <host>:<port>;
database := <database name>;
<code to create the connection - didn't include to save space - this time connect using sqlx>
// select all the rows and load into the struct, in one step
dbQuery := "select table_name, tablespace_name from user_tables where table_name not like 'DM$%' and table_name not like 'ODMR$%'"
table_rec := []TableDetails{}
db.Select(&tanle_rec, dbQuery)
// load each row separately
table_rec := []TableDetails{}
rows, err := db.Queryx(dbQuery)
for rows.next() {
// loads the current row into the struct
err := rows.StructScan(&table_rec)
fmt.Printf("%+v\n", table_rec)
}
<code to close the connection - didn't include to save space>
}