Basic CURD

Overview

We can get a sqlx.SqlConn at to create a link and then we can complete various database operations. We strongly recommend using goctl model to generate sql code automatically, without manual entry.

SqlConn 基本的方法如下

  1. type (
  2. // SqlConn only stands for raw connections, so Transact method can be called.
  3. SqlConn interface {
  4. Session
  5. // RawDB is for other ORM to operate with, use it with caution.
  6. // Notice: don't close it.
  7. RawDB() (*sql.DB, error)
  8. Transact(fn func(Session) error) error
  9. TransactCtx(ctx context.Context, fn func(context.Context, Session) error) error
  10. }
  11. // StmtSession interface represents a session that can be used to execute statements.
  12. StmtSession interface {
  13. Close() error
  14. Exec(args ...any) (sql.Result, error)
  15. ExecCtx(ctx context.Context, args ...any) (sql.Result, error)
  16. QueryRow(v any, args ...any) error
  17. QueryRowCtx(ctx context.Context, v any, args ...any) error
  18. QueryRowPartial(v any, args ...any) error
  19. QueryRowPartialCtx(ctx context.Context, v any, args ...any) error
  20. QueryRows(v any, args ...any) error
  21. QueryRowsCtx(ctx context.Context, v any, args ...any) error
  22. QueryRowsPartial(v any, args ...any) error
  23. QueryRowsPartialCtx(ctx context.Context, v any, args ...any) error
  24. }
  25. )

ExecCtx

We have provided ExecCtx methods to complete various additions and deletions. Simple Example:

  1. var conn sqlx.SqlConn // should be created by NewConn
  2. r, err := conn.ExecCtx(context.Background(), "delete from user where `id` = ?", 1)

Normally we use the input parameters placeholder ? 占位,接着通过 args 传入,这样可以有效防止 sql 注入等问题。

This method will also trigger melting if an error occurs with the sql executed.There is also a mechanism for automatic release once the service has returned to normal.See melting for details.

QueryRowCtx

We provided QueryRowCtx for normal query, Simple Example:

  1. type User struct {
  2. Id int64 `db:"id"`
  3. Name string `db:"name"`
  4. }
  5. var conn sqlx.SqlConn
  6. var u User
  7. err := conn.QueryRowCtx(context.Background(), &u, "select id, name from user where id = ? limit 1", 1)
  8. if err != nil {
  9. fmt.Println(err)
  10. return
  11. }
  12. _ = u

This way we can use data from user tables that you have provided with an account id 1.Common errors can be found below common errors

QueryRowPartialCtx

Both QueryRowPartialCtx and QueryRowCtx provide user queries for data use. But in order to ensure that all fields defined in the User are processed with accuracy, so when QueryRowCtx is designed, the queryVerify QueryRowCtx list needs to match the defined field. For example, the definition and Sql report errors.

  1. type User struct {
  2. Id int64 `db:"id"`
  3. Name string `db:"name"`
  4. Age int `db:"age"`
  5. }
  6. var conn sqlx.SqlConn
  7. var u User
  8. err := conn.QueryRowCtx(context.Background(), &u, "select id, name from user where id = ? limit 1", 1)
  9. if err != nil { // err == ErrNotMatchDestination
  10. fmt.Println(err) // not matching destination to scan
  11. return
  12. }

Because our defined age is not queried in sql, this will cause inconsistency in variables.If the user does have a wide table, only some fields need to be queried. We provided QueryRowPartialCtx this method is not enough for a list of timely queries.

  1. type User struct {
  2. Id int64 `db:"id"`
  3. Name string `db:"name"`
  4. Age int `db:"age"`
  5. }
  6. var conn sqlx.SqlConn
  7. var u User
  8. err := conn.QueryRowPartialCtx(context.Background(), &u, "select id, name from user where id = ? limit 1", 1)
  9. if err != nil { // err == nil
  10. fmt.Println(err)
  11. return
  12. }
  13. _ = u // age is default 0

QueryRowsCtx

We also provided QueryRowsCtx for bulk queryRowsCt, Simple Example:

  1. type User struct {
  2. Id int64 `db:"id"`
  3. Name string `db:"name"`
  4. }
  5. var conn sqlx.SqlConn
  6. var users []*User
  7. err := conn.QueryRowsCtx(context.Background(), &users, "select id, name from user where name = ?", "dylan")
  8. if err != nil {
  9. fmt.Println(err)
  10. return
  11. }
  12. _ = users

This will make it possible to find all users named dylan.Note that we will not return ErrNotFound when there is no user in the database, this block is different from QueryRowCtx.

Common Errors

Some common errors in our sql statements below:

  1. var (
  2. // ErrNotMatchDestination is an error that indicates not matching destination to scan.
  3. ErrNotMatchDestination = errors.New("not matching destination to scan")
  4. // ErrNotReadableValue is an error that indicates value is not addressable or interfaceable.
  5. ErrNotReadableValue = errors.New("value not addressable or interfaceable")
  6. // ErrNotSettable is an error that indicates the passed in variable is not settable.
  7. ErrNotSettable = errors.New("passed in variable is not settable")
  8. // ErrUnsupportedValueType is an error that indicates unsupported unmarshal type.
  9. ErrUnsupportedValueType = errors.New("unsupported unmarshal type")
  10. ErrNotFound = sql.ErrNoRows
  11. )

There is, of course, a network error including sql bottom, not listing.