SlideShare a Scribd company logo
1 of 28
Download to read offline
DATABASE/SQL
• github.com/VividCortex
• @xaprb
• baron@vividcortex.com
• linkedin.com/in/xaprb
Optimization, Backups,
Replication, and more
Baron Schwartz,
Peter Zaitsev &
Vadim Tkachenko
High
Performance
MySQL
3rd
Edition
CoversVersion
5.5
ME
• Docs: golang.org/pkg/database/sql/
• Tutorial: go-database-sql.org/
• MySQL Driver: github.com/go-sql-driver/mysql/
RESOURCES
THINGS
DB
• Not a connection.
• Open() Close()
• Query() QueryRow() Exec()
ROWS
• Next()
• Scan()
PATTERNS
package main
import (
! _ "github.com/go-sql-driver/mysql"
! "database/sql"
! "log"
)
func main() {
! db, err := sql.Open("mysql",
! ! "user:password@tcp(127.0.0.1:3306)/test")
! if err != nil {
! ! log.Println(err)
! }
! // What do we have here?
! defer db.Close()
}
var str string
err = db.QueryRow(
"select hello from world where id = 1").
Scan(&str)
if err != nil && err != sql.ErrNoRows {
log.Println(err)
}
log.Println(str)
q := "select id, hello from world where id = ?"
rows, err := db.Query(q, 1)
if err != nil {
! log.Fatal(err)
}
defer rows.Close()
var id int
var str string
for rows.Next() {
! err = rows.Scan(&id, &str)
! if err != nil {
! ! log.Fatal(err)
! }
! // Use the variables scanned from the row
}
for rows.Next() {
! // scan
}
if err = rows.Err(); err != nil {
rows.Close()
log.Fatal(err)
}
stmt, err := db.Prepare(
! "select id, hello from world where id = ?")
if err != nil {
! log.Fatal(err)
}
defer stmt.Close()
rows, err := stmt.Query(1)
if err != nil {
! log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
! // ...
}
stmt, err := db.Prepare(
! "insert into world(hello) values(?)")
if err != nil {
! log.Fatal(err)
}
defer stmt.Close()
res, err := stmt.Exec("hello, Dolly")
if err != nil {
! log.Fatal(err)
}
THINGSTO KNOW
THINGSTO KNOW
• There is a connection pool.
• You can’t use uint64 with high bit set in parameters.
DON’T BE LAZY
// Don’t do this!
for i := 0; i < 50; i++ {
! _, err := db.Query("DELETE FROM hello.world")
}
// Use this instead!
for i := 0; i < 50; i++ {
! _, err := db.Exec("DELETE FROM hello.world")
}
MORE HELPFUL ADVICE
• Don’t defer() in long-running functions.
• Don’t use cxn state. UseTx to bind to a connection.
• Don’t use BEGIN and COMMIT via SQL.
SURPRISES
RETRY. RETRY. RETRY. RETRY. RETRY.
RETRY. RETRY. RETRY. RETRY. RETRY.
// Exec executes a query without returning any
rows.
// The args are for any placeholder parameters in
the query.
func (db *DB) Exec(query string,
args ...interface{}) (Result, error) {
! var res Result
! var err error
! for i := 0; i < 10; i++ {
! ! res, err = db.exec(query, args)
! ! if err != driver.ErrBadConn {
! ! ! break
! ! }
! }
! return res, err
}
PREPARED STATEMENTS
NULL
This page intentionally left blank.
var s sql.NullString
err := db.QueryRow(
"SELECT name FROM foo WHERE id=?",
id).Scan(&s)
if s.Valid {
// use s.String
} else {
// NULL value
}
CUSTOMTYPES
CUSTOMTYPES
• You can implement theValuer and Scanner interfaces.
• Why?Transparently transform data in <=> out of the DB.
• Compress and uncompress.
• Marshall/unmarshall JSON or another type.
• Encrypt and decrypt.
• See e.g. http://jmoiron.net/blog/built-in-interfaces/
RESOURCES
• http://golang.org/pkg/database/sql/
• http://go-database-sql.org/
• https://github.com/go-sql-driver/mysql
• http://jmoiron.net/blog/
• @VividCortex * not biased, not biased, not biased
IMAGE CREDITS
• http://www.flickr.com/photos/simens/6306917636/
• http://www.flickr.com/photos/dexxus/5794905716/
• http://www.flickr.com/photos/sebastian_bergmann/202396633/
• http://www.flickr.com/photos/doug88888/4794114114/
• http://www.flickr.com/photos/oatsy40/6443878013/
• http://www.sxc.hu/photo/1160562/
• Google Maps (screenshot)
• http://www.flickr.com/photos/estherase/13553883/
• http://www.flickr.com/photos/paperpariah/4150220583/
• http://www.flickr.com/photos/zooboing/4743616313/
• http://www.flickr.com/photos/dseneste/5912382808/
• http://www.flickr.com/photos/clickykbd/66165381/sizes/l/
• http://www.flickr.com/photos/mamnaimie/5576980406/
• https://www.flickr.com/photos/zachstern/87431231

More Related Content

What's hot

Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & Celery
Mauro Rocco
 
MongoDB: tips, trick and hacks
MongoDB: tips, trick and hacksMongoDB: tips, trick and hacks
MongoDB: tips, trick and hacks
Scott Hernandez
 
Real-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet ElasticsearchReal-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet Elasticsearch
Alexei Gorobets
 

What's hot (20)

Celery - A Distributed Task Queue
Celery - A Distributed Task QueueCelery - A Distributed Task Queue
Celery - A Distributed Task Queue
 
Why Task Queues - ComoRichWeb
Why Task Queues - ComoRichWebWhy Task Queues - ComoRichWeb
Why Task Queues - ComoRichWeb
 
Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & Celery
 
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJS
 
Scaling up task processing with Celery
Scaling up task processing with CeleryScaling up task processing with Celery
Scaling up task processing with Celery
 
MongoDB: tips, trick and hacks
MongoDB: tips, trick and hacksMongoDB: tips, trick and hacks
MongoDB: tips, trick and hacks
 
Got Logs? Get Answers with Elasticsearch ELK - PuppetConf 2014
Got Logs? Get Answers with Elasticsearch ELK - PuppetConf 2014Got Logs? Get Answers with Elasticsearch ELK - PuppetConf 2014
Got Logs? Get Answers with Elasticsearch ELK - PuppetConf 2014
 
Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queue
 
Performance and stability testing \w Gatling
Performance and stability testing \w GatlingPerformance and stability testing \w Gatling
Performance and stability testing \w Gatling
 
Introduction to PostgreSQL
Introduction to PostgreSQLIntroduction to PostgreSQL
Introduction to PostgreSQL
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Real-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet ElasticsearchReal-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet Elasticsearch
 
Ember background basics
Ember background basicsEmber background basics
Ember background basics
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniques
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
 
Asynchronous Task Queues with Celery
Asynchronous Task Queues with CeleryAsynchronous Task Queues with Celery
Asynchronous Task Queues with Celery
 

Viewers also liked

Fraser Graham Killer Robots
Fraser Graham Killer RobotsFraser Graham Killer Robots
Fraser Graham Killer Robots
Artem Kovardin
 
Best practices-for-production-environments
Best practices-for-production-environmentsBest practices-for-production-environments
Best practices-for-production-environments
Artem Kovardin
 

Viewers also liked (11)

Fraser Graham Killer Robots
Fraser Graham Killer RobotsFraser Graham Killer Robots
Fraser Graham Killer Robots
 
High Performance Systems in Go - GopherCon 2014
High Performance Systems in Go - GopherCon 2014High Performance Systems in Go - GopherCon 2014
High Performance Systems in Go - GopherCon 2014
 
A Channel Compendium
A Channel CompendiumA Channel Compendium
A Channel Compendium
 
Building A Relevancy Engine Using MongoDB and Go
Building A Relevancy Engine Using MongoDB and GoBuilding A Relevancy Engine Using MongoDB and Go
Building A Relevancy Engine Using MongoDB and Go
 
Best practices-for-production-environments
Best practices-for-production-environmentsBest practices-for-production-environments
Best practices-for-production-environments
 
Garbage collector и управление памятью в Go
Garbage collector и управление памятью в GoGarbage collector и управление памятью в Go
Garbage collector и управление памятью в Go
 
C-spirit reborn: why Go was bound to be created
C-spirit reborn: why Go was bound to be createdC-spirit reborn: why Go was bound to be created
C-spirit reborn: why Go was bound to be created
 
Anthony Starks - deck
Anthony Starks - deckAnthony Starks - deck
Anthony Starks - deck
 
OOP в Go
OOP в GoOOP в Go
OOP в Go
 
Talknoteとgolangと私
Talknoteとgolangと私Talknoteとgolangと私
Talknoteとgolangと私
 
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
 

Similar to Go database/sql

How to Troubleshoot & Optimize Database Query Performance for Your Application
How to Troubleshoot  & Optimize Database Query Performance for Your ApplicationHow to Troubleshoot  & Optimize Database Query Performance for Your Application
How to Troubleshoot & Optimize Database Query Performance for Your Application
Dynatrace
 
Ruby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrādeRuby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrāde
Raimonds Simanovskis
 
Different waysconnect
Different waysconnectDifferent waysconnect
Different waysconnect
myrajendra
 

Similar to Go database/sql (20)

SQL Injection Defense in Python
SQL Injection Defense in PythonSQL Injection Defense in Python
SQL Injection Defense in Python
 
Python with MySql.pptx
Python with MySql.pptxPython with MySql.pptx
Python with MySql.pptx
 
Scrap your query boilerplate with specql
Scrap your query boilerplate with specqlScrap your query boilerplate with specql
Scrap your query boilerplate with specql
 
Java OOP Programming language (Part 8) - Java Database JDBC
Java OOP Programming language (Part 8) - Java Database JDBCJava OOP Programming language (Part 8) - Java Database JDBC
Java OOP Programming language (Part 8) - Java Database JDBC
 
Es6 hackathon
Es6 hackathonEs6 hackathon
Es6 hackathon
 
How to Troubleshoot & Optimize Database Query Performance for Your Application
How to Troubleshoot  & Optimize Database Query Performance for Your ApplicationHow to Troubleshoot  & Optimize Database Query Performance for Your Application
How to Troubleshoot & Optimize Database Query Performance for Your Application
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
 
Ruby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrādeRuby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrāde
 
Jdbc
JdbcJdbc
Jdbc
 
Python database access
Python database accessPython database access
Python database access
 
Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
 
Different waysconnect
Different waysconnectDifferent waysconnect
Different waysconnect
 
Building node.js applications with Database Jones
Building node.js applications with Database JonesBuilding node.js applications with Database Jones
Building node.js applications with Database Jones
 
Jdbc
JdbcJdbc
Jdbc
 
Java JDBC
Java JDBCJava JDBC
Java JDBC
 
ABRIDGED VERSION - Joys & frustrations of putting 34,000 lines of Haskell in...
 ABRIDGED VERSION - Joys & frustrations of putting 34,000 lines of Haskell in... ABRIDGED VERSION - Joys & frustrations of putting 34,000 lines of Haskell in...
ABRIDGED VERSION - Joys & frustrations of putting 34,000 lines of Haskell in...
 
Scala active record
Scala active recordScala active record
Scala active record
 
Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
MYSQL Query Anti-Patterns That Can Be Moved to SphinxMYSQL Query Anti-Patterns That Can Be Moved to Sphinx
MYSQL Query Anti-Patterns That Can Be Moved to Sphinx
 
PHP with MySQL
PHP with MySQLPHP with MySQL
PHP with MySQL
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 

Go database/sql

  • 2. • github.com/VividCortex • @xaprb • baron@vividcortex.com • linkedin.com/in/xaprb Optimization, Backups, Replication, and more Baron Schwartz, Peter Zaitsev & Vadim Tkachenko High Performance MySQL 3rd Edition CoversVersion 5.5 ME
  • 3. • Docs: golang.org/pkg/database/sql/ • Tutorial: go-database-sql.org/ • MySQL Driver: github.com/go-sql-driver/mysql/ RESOURCES
  • 5. DB • Not a connection. • Open() Close() • Query() QueryRow() Exec()
  • 8. package main import ( ! _ "github.com/go-sql-driver/mysql" ! "database/sql" ! "log" ) func main() { ! db, err := sql.Open("mysql", ! ! "user:password@tcp(127.0.0.1:3306)/test") ! if err != nil { ! ! log.Println(err) ! } ! // What do we have here? ! defer db.Close() }
  • 9. var str string err = db.QueryRow( "select hello from world where id = 1"). Scan(&str) if err != nil && err != sql.ErrNoRows { log.Println(err) } log.Println(str)
  • 10. q := "select id, hello from world where id = ?" rows, err := db.Query(q, 1) if err != nil { ! log.Fatal(err) } defer rows.Close() var id int var str string for rows.Next() { ! err = rows.Scan(&id, &str) ! if err != nil { ! ! log.Fatal(err) ! } ! // Use the variables scanned from the row }
  • 11. for rows.Next() { ! // scan } if err = rows.Err(); err != nil { rows.Close() log.Fatal(err) }
  • 12. stmt, err := db.Prepare( ! "select id, hello from world where id = ?") if err != nil { ! log.Fatal(err) } defer stmt.Close() rows, err := stmt.Query(1) if err != nil { ! log.Fatal(err) } defer rows.Close() for rows.Next() { ! // ... }
  • 13. stmt, err := db.Prepare( ! "insert into world(hello) values(?)") if err != nil { ! log.Fatal(err) } defer stmt.Close() res, err := stmt.Exec("hello, Dolly") if err != nil { ! log.Fatal(err) }
  • 15. THINGSTO KNOW • There is a connection pool. • You can’t use uint64 with high bit set in parameters.
  • 17. // Don’t do this! for i := 0; i < 50; i++ { ! _, err := db.Query("DELETE FROM hello.world") } // Use this instead! for i := 0; i < 50; i++ { ! _, err := db.Exec("DELETE FROM hello.world") }
  • 18. MORE HELPFUL ADVICE • Don’t defer() in long-running functions. • Don’t use cxn state. UseTx to bind to a connection. • Don’t use BEGIN and COMMIT via SQL.
  • 20. RETRY. RETRY. RETRY. RETRY. RETRY. RETRY. RETRY. RETRY. RETRY. RETRY.
  • 21. // Exec executes a query without returning any rows. // The args are for any placeholder parameters in the query. func (db *DB) Exec(query string, args ...interface{}) (Result, error) { ! var res Result ! var err error ! for i := 0; i < 10; i++ { ! ! res, err = db.exec(query, args) ! ! if err != driver.ErrBadConn { ! ! ! break ! ! } ! } ! return res, err }
  • 24. var s sql.NullString err := db.QueryRow( "SELECT name FROM foo WHERE id=?", id).Scan(&s) if s.Valid { // use s.String } else { // NULL value }
  • 26. CUSTOMTYPES • You can implement theValuer and Scanner interfaces. • Why?Transparently transform data in <=> out of the DB. • Compress and uncompress. • Marshall/unmarshall JSON or another type. • Encrypt and decrypt. • See e.g. http://jmoiron.net/blog/built-in-interfaces/
  • 27. RESOURCES • http://golang.org/pkg/database/sql/ • http://go-database-sql.org/ • https://github.com/go-sql-driver/mysql • http://jmoiron.net/blog/ • @VividCortex * not biased, not biased, not biased
  • 28. IMAGE CREDITS • http://www.flickr.com/photos/simens/6306917636/ • http://www.flickr.com/photos/dexxus/5794905716/ • http://www.flickr.com/photos/sebastian_bergmann/202396633/ • http://www.flickr.com/photos/doug88888/4794114114/ • http://www.flickr.com/photos/oatsy40/6443878013/ • http://www.sxc.hu/photo/1160562/ • Google Maps (screenshot) • http://www.flickr.com/photos/estherase/13553883/ • http://www.flickr.com/photos/paperpariah/4150220583/ • http://www.flickr.com/photos/zooboing/4743616313/ • http://www.flickr.com/photos/dseneste/5912382808/ • http://www.flickr.com/photos/clickykbd/66165381/sizes/l/ • http://www.flickr.com/photos/mamnaimie/5576980406/ • https://www.flickr.com/photos/zachstern/87431231