add sample to show how to build JOIN with Struct

This commit is contained in:
Huan Du
2024-04-24 02:52:38 +08:00
parent 20c2b710b3
commit 76f1e16370
3 changed files with 50 additions and 4 deletions
+7 -3
View File
@@ -52,7 +52,7 @@ fmt.Println(sql)
// SELECT id, name FROM demo.user WHERE status = 1 LIMIT 10
```
In the most cases, we need to escape all input from user. In this case, create a builder before starting.
In the most common cases, we need to escape all input from user. In this case, create a builder before starting.
```go
sb := sqlbuilder.NewSelectBuilder()
@@ -222,7 +222,7 @@ type ATable struct {
Field1 string // If a field doesn't has a tag, use "Field1" as column name in SQL.
Field2 int `db:"field2"` // Use "db" in field tag to set column name used in SQL.
Field3 int64 `db:"field3" fieldtag:"foo,bar"` // Set fieldtag to a field. We can call `WithTag` to include fields with tag or `WithoutTag` to exclude fields with tag.
Field4 int64 `db:"field4" fieldtag:"foo"` // If we use `s.WithTag("foo").Select(table)`, columnes of SELECT are field3 and field4.
Field4 int64 `db:"field4" fieldtag:"foo"` // If we use `s.WithTag("foo").Select("t")`, columnes of SELECT are "t.field3" and "t.field4".
Field5 string `db:"field5" fieldas:"f5_alias"` // Use "fieldas" in field tag to set a column alias (AS) used in SELECT.
Ignored int32 `db:"-"` // If we set field name as "-", Struct will ignore it.
unexported int // Unexported field is not visible to Struct.
@@ -232,6 +232,10 @@ type ATable struct {
// The `omitempty` can be written as a function.
// In this case, omit empty field `Tagged` when UPDATE for tag `tag1` and `tag3` but not `tag2`.
Tagged string `db:"tagged" fieldopt:"omitempty(tag1,tag3)" fieldtag:"tag1,tag2,tag3"`
// By default, the `SelectFrom("t")` will add the "t." to all names of fields matched tag.
// We can add dot to field name to disable this behavior.
FieldWithTableAlias string `db:"m.field"`
}
```
@@ -254,7 +258,7 @@ var userStruct = NewStruct(new(User))
func ExampleStruct() {
// Prepare SELECT query.
// SELECT id, name, status FROM user WHERE id = 1234
// SELECT user.id, user.name, user.status FROM user WHERE id = 1234
sb := userStruct.SelectFrom("user")
sb.Where(sb.Equal("id", 1234))
+12 -1
View File
@@ -307,10 +307,11 @@ func (s *Struct) selectFromWithTags(table string, with, without []string) (sb *S
buf := newStringBuilder()
cols := make([]string, 0, len(tagged.ForRead))
tableAlias := parseTableAlias(table)
for _, sf := range tagged.ForRead {
if s.Flavor != CQL && !strings.ContainsRune(sf.Alias, '.') {
buf.WriteString(table)
buf.WriteString(tableAlias)
buf.WriteRune('.')
}
buf.WriteString(sf.NameForSelect(s.Flavor))
@@ -323,6 +324,16 @@ func (s *Struct) selectFromWithTags(table string, with, without []string) (sb *S
return sb
}
func parseTableAlias(table string) string {
idx := strings.LastIndex(table, " ")
if idx == -1 {
return table
}
return table[idx+1:]
}
// Update creates a new `UpdateBuilder` with table name.
// By default, all exported fields of the s is assigned in UPDATE with the field values from value.
// If value's type is not the same as that of s, Update returns a dummy `UpdateBuilder` with table name.
+31
View File
@@ -386,6 +386,37 @@ func ExampleStruct_useStructAsORM() {
// sqlbuilder.User{ID:1234, Name:"huandu", Status:1}
}
func ExampleStruct_buildJOIN() {
// Suppose we're going to query a "member" table joined with "user" table.
type Member struct {
ID string `db:"id"`
UserID string `db:"user_id"`
MemberName int `db:"name"`
CreatedAt time.Time `db:"created_at"`
// Add "u." prefix to the field name to specify the field in "user" table.
Name string `db:"u.name"`
Email string `db:"u.email"`
}
// Parse member struct. The memberStruct can be a global variable.
// It's guraanteed to be thread-safe.
var memberStruct = NewStruct(new(Member))
// Prepare JOIN query.
sb := memberStruct.SelectFrom("member m").Join("user u", "m.user_id = u.user_id")
sb.Where(sb.Like("m.name", "Huan%"))
sql, args := sb.Build()
fmt.Println(sql)
fmt.Println(args)
// Output:
// SELECT m.id, m.user_id, m.name, m.created_at, u.name, u.email FROM member m JOIN user u ON m.user_id = u.user_id WHERE m.name LIKE ?
// [Huan%]
}
var orderDB testDB = 1
func ExampleStruct_WithTag() {