Repositories¶
Declare a @Repository(generate=true) interface with @Query/@Exec
methods; goboot generates the implementation over a driver-neutral DB seam and
injects it with a db.DBProvider. The SQL is compiled for the configured
dialect — switching drivers changes nothing else.
// @Repository(generate=true, entity="User", table="users")
type UserRepository interface {
// @Query(`SELECT id, name, email FROM users WHERE id = :id`)
FindByID(ctx context.Context, id string) (*User, error)
// @Query(`SELECT id, name, email FROM users ORDER BY name`)
FindAll(ctx context.Context) ([]*User, error)
// @Exec(`INSERT INTO users (id, name, email) VALUES (:u.ID, :u.Name, :u.Email)`)
Insert(ctx context.Context, u User) error
// @Exec(`DELETE FROM users WHERE id = :id`)
Delete(ctx context.Context, id string) (int64, error)
}
Named parameters¶
:name binds a method argument; :arg.Field binds a struct field. They compile
to the dialect's placeholders ($1, ?, @p1, …). Field references keep call
sites tidy — pass the whole entity instead of many scalars.
Return shapes¶
| Signature | Behaviour |
|---|---|
(*T, error) |
single row; no rows → db.ErrNoRows |
([]*T, error) / ([]T, error) |
slice of rows |
(scalar, error) |
single column (int/string/bool/…) |
error (@Exec) |
run only |
(int64, error) (@Exec) |
rows affected |
@Batch and @Call¶
@Batchruns its statement once per element of a slice parameter; fields bind via the slice name (:users.ID). Returnserroror(int64, error).@Callinvokes a stored procedure/function — scanned like@Querywhen it returns a value, run like@Execwhen it returns onlyerror.
Dialects¶
Set generation.dialect in goboot.yaml or pass -dialect:
| Dialect | Placeholders | Drivers |
|---|---|---|
postgres (default) |
$1, $2 |
pgx, pq |
mysql / question |
? |
MySQL, SQLite |
sqlserver |
@p1, @p2 |
SQL Server |
oracle |
:1, :2 |
via the oracle plugin |
Transactions¶
Mark a service method @Transactional; the generated proxy runs it via the
configured TransactionManager, publishing the transaction on the context so the
repository joins it automatically. Provide a real manager from an
adapter: