( El proyecto beedb no es más mantenido, pero el código sigue aun allí )
beedb es un ORM, "Object Relational Mapping", que se desarrolló en Go por mí. Utiliza el estilo de Go para operar con las base de datos, implementando struct para realizar el mapeo de los registros de la base de datos. Es un framework ORM ligero en Go, el propósito de desarrollar este ORM es ayudar a las personas a aprender cómo escribir un ORM, y que encuentre un buen equilibrio entre las funciones y el rendimiento.
beedb es un proyecto de código abierto, y soporta las funciones básicas de un ORM, pero no admite querys asociadas.
Debido a que beedb soporta la interfaz estándar database/sql
, cualquier driver compatible con esta interfaz se pueden utilizar en beedb, yo he probado los siguientes drivers:
Mysql: github.com/ziutek/mymysql/godrv
Mysql: code.google.com/p/go-mysql-driver
PostgreSQL: github.com/bmizerany/pq
SQLite: github.com/mattn/go-sqlite3
MS ADODB: github.com/mattn/go-adodb
ODBC: bitbucket.org/miquella/mgodbc
Puede usar go get
para instalar beedb en su computadora.
go get github.com/astaxie/beedb
En primer lugar, usted tiene que importar todos los paquetes correspondientes de la siguiente manera:
import (
"database/sql"
"github.com/astaxie/beedb"
_ "github.com/ziutek/mymysql/godrv"
)
Luego hay que abrir una conexión de base de datos y crear un objeto beedb (en este ejemplo MySQL):
db, err := sql.Open("mymysql", "test/xiemengjun/123456")
if err != nil {
panic(err)
}
orm := beedb.New(db)
beedb.New()
en realidad tiene dos argumentos, el primero es para el requisito estándar, y el segundo es para indicar el motor de base de datos, pero si usted está utilizando MySQL/SQLite, puede saltarse el segundo.
De otra forma, usted tendrá que inicializarlo, como con SQLServer:
orm = beedb.New(db, "mssql")
PostgreSQL:
orm = beedb.New(db, "pg")
beedb soporta depuración, para permitirlo use el siguiente código:
beedb.OnDebug=true
Ahora tenemos un struct para la tabla de la base de datos Userinfo
que hemos utilizado en las secciones anteriores.
type Userinfo struct {
Uid int `PK` // si la clave principal no es id, es necesario agregar el tag `PK` para su clave primaria personalizada.
Username string
Departname string
Created time.Time
}
Tenga en cuenta que beedb auto-convert usa su estilo camel para nombrar las tablas y campos con guiones bajos y letras minúsculas. Por ejemplo, tenemos UserInfo
como el nombre del struct, y será user_info
en la base de datos, la misma regla para los nombres de campos.
El siguiente ejemplo muestra cómo utilizar beedb para salvar el struct en lugar de comandos SQL y utilizar el método Save para aplicar el cambio.
var saveone Userinfo
saveone.Username = "Test Add User"
saveone.Departname = "Test Add Departname"
saveone.Created = time.Now()
orm.Save(&saveone)
Y puede comprobar saveone.Uid
después de haberlo insertado, su valor de ID es auto incremental, el método Save hizo este trabajo por usted.
beedb proporciona otra forma de insertar los datos, que es utilizando map.
add := make(map[string]interface{})
add["username"] = "astaxie"
add["departname"] = "cloud develop"
add["created"] = "2012-12-02"
orm.SetTable("userinfo").Insert(add)
Insertar datos múltiples:
addslice := make([]map[string]interface{}, 10)
add:=make(map[string]interface{})
add2:=make(map[string]interface{})
add["username"] = "astaxie"
add["departname"] = "cloud develop"
add["created"] = "2012-12-02"
add2["username"] = "astaxie2"
add2["departname"] = "cloud develop2"
add2["created"] = "2012-12-02"
addslice =append(addslice, add, add2)
orm.SetTable("userinfo").InsertBatch(addslice)
La forma que te mostré arriba es como una chain query, debe estar familiarizado si sabe de jQuery. Este devuelve el objeto ORM original después de las llamadas y sigue haciendo otros trabajos.
El metodo SetTable
le dice al ORM que queremos insertar los datos de la tabla userinfo
.
Siga el ejemplo anterior, para ver cómo actualizar los datos. Ahora tenemos el valor de clave principal de saveone(UID), por lo que beedb ejecuta la operación de actualización en lugar de insertar nuevo registro.
saveone.Username = "Update Username"
saveone.Departname = "Update Departname"
saveone.Created = time.Now()
orm.Save(&saveone) // update
Usted también puede utilizar map para la actualización de datos:
t := make(map[string]interface{})
t["username"] = "astaxie"
orm.SetTable("userinfo").SetPK("uid").Where(2).Update(t)
Voy a explicar algunos de los métodos que hemos utilizado anteriormente:
.SetPK()
le dice al ORM queuid
es la clave principal de la tablauserinfo
..Where()
establece las condiciones, soporta múltiples argumentos, si el primer argumento es un número entero, una forma corta deWhere("<primary key>=?", <value>)
..Update()
este método acepta map y actualiza la base de datos.
La interfaz de consulta de beedb es muy flexible, veamos algunos ejemplos:
Ejemplo 1, consulta por clave principal:
var user Userinfo
// Where acepta dos argumentos, suporta enteros
orm.Where("uid=?", 27).Find(&user)
Ejemplo 2:
var user2 Userinfo
orm.Where(3).Find(&user2) // forma corta que omite la clave primaria
Ejemplo 3, otras condiciones en la consulta:
var user3 Userinfo
// Where acepta dos argumentos, soporta el tipo char.
orm.Where("name = ?", "john").Find(&user3)
Ejemplo 4, condiciones más complejas:
var user4 Userinfo
// Where acepta tres argumentos
orm.Where("name = ? and age < ?", "john", 88).Find(&user4)
Ejemplos para conseguir varios registros:
Ejemplo 1, recibe 10 registros donde id> 3 y se inicia con la posición 20:
var allusers []Userinfo
err := orm.Where("id > ?", "3").Limit(10,20).FindAll(&allusers)
Ejemplo 2, omite el segundo argumento del límite, por lo que empieza con 0 y recibe 10 registros:
var tenusers []Userinfo
err := orm.Where("id > ?", "3").Limit(10).FindAll(&tenusers)
Ejemplo 3, consigue todos los registros:
var everyone []Userinfo
err := orm.OrderBy("uid desc,username asc").FindAll(&everyone)
Como puede ver, el método límite es para limitar el número de resultados.
.Limit()
admite dos argumentos, que son el número de resultados y la posición de inicio. 0 es el valor predeterminado de la posición de inicio..OrderBy()
es para ordenar los resultados, los argumentos son la condición del orden.
Todos los ejemplos que se ven son mapeados a struct y también se puede simplemente poner los datos en un map de la siguiente manera:
a, _ := orm.SetTable("userinfo").SetPK("uid").Where(2).Select("uid,username").FindMap()
.Select()
le dice a beedb cuántos campos desea obtener de la tabla de base de datos, devuelve todos los campos por defecto..FindMap()
devuelve el tipo[]map[string][]byte
, entonces necesita convertirlos a otros tipos por usted mismo.
beedb proporciona muchos métodos para eliminar datos.
Ejemplo 1, eliminar un solo registro:
// saveone es uno de los ejemplos anteriores.
orm.Delete(&saveone)
Ejemplo 2, eliminar varios registros:
// alluser es una lista que contiene multiples registros
orm.DeleteAll(&alluser)
Ejemplo 3, eliminar registros mediante SQL:
orm.SetTable("userinfo").Where("uid>?", 3).DeleteRow()
beedb no soporta join entre struct. Sin embargo, ya que algunas aplicaciones necesitan esta característica, aquí hay una implementacion:
a, _ := orm.SetTable("userinfo").Join("LEFT", "userdetail", "userinfo.uid=userdetail.uid")
.Where("userinfo.uid=?", 1).Select("userinfo.uid,userinfo.username,userdetail.profile").FindMap()
Vemos un nuevo método llamado .Join()
, tiene tres argumentos:
- El primer argumento: Tipo of Join; INNER, LEFT, OUTER, CROSS, etc.
- El segundo argumento: la tabla con la que desea que se una.
- El tercer argumento: la condición para el join.
beedb también tiene una implementacion de group by
y having
.
a, _ := orm.SetTable("userinfo").GroupBy("username").Having("username='astaxie'").FindMap()
.GroupBy()
indica el campo por el que se va a agrupar..Having()
indica la condición del having.
He recibido muchos comentarios de muchas personas de todo el mundo, y estoy pensando en la reconfiguración en los siguientes aspectos:
- Implementar un diseño de interfaz como
database/sql/driver
con el fin de implementar las operaciones CRUD correspondientes. - Implementar el diseño de base de datos relacional, uno a uno, uno a muchos, muchos a muchos, aquí están algunas muestras:
type Profile struct {
Nickname string
Mobile string
}
type Userinfo struct {
Uid int
PK_Username string
Departname string
Created time.Time
Profile HasOne
}
- Auto-crear tablas e índices.
- Implementar pool de conexiones a través goroutine.
- Indice
- Sección anterior: PostgreSQL
- Siguiente sección: Base de datos NoSQL