github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/caches/README.md (about)

     1  # Gorm Caches
     2  
     3  Gorm Caches plugin using database request reductions (easer), and response caching mechanism provide you an easy way to optimize database performance.
     4  
     5  ## Features
     6  
     7  - Database request reduction. If three identical requests are running at the same time, only the first one is going to be executed, and its response will be returned for all.
     8  - Database response caching. By implementing the Cacher interface, you can easily setup a caching mechanism for your database queries.
     9  - Supports all databases that are supported by gorm itself.
    10  
    11  ## Install
    12  
    13  ```bash
    14  go get -u github.com/go-gorm/caches/v2
    15  ```
    16  
    17  ## Usage
    18  
    19  Configure the `easer`, and the `cacher`, and then load the plugin to gorm.
    20  
    21  ```go
    22  package main
    23  
    24  import (
    25  	"fmt"
    26  	"sync"
    27  
    28  	"github.com/go-gorm/caches"
    29  	"gorm.io/driver/mysql"
    30  	"gorm.io/gorm"
    31  )
    32  
    33  func main() {
    34  	db, _ := gorm.Open(
    35  		mysql.Open("DATABASE_DSN"),
    36  		&gorm.Config{},
    37  	)
    38  	cachesPlugin := &caches.Caches{Conf: &caches.Config{
    39  		Easer: true,
    40  		Cacher: &yourCacherImplementation{},
    41  	}}
    42  	_ = db.Use(cachesPlugin)
    43  }
    44  ```
    45  
    46  ## Easer Example
    47  
    48  ```go
    49  package main
    50  
    51  import (
    52  	"fmt"
    53  	"sync"
    54  	"time"
    55  
    56  	"github.com/go-gorm/caches"
    57  	"gorm.io/driver/mysql"
    58  	"gorm.io/gorm"
    59  )
    60  
    61  type UserRoleModel struct {
    62  	gorm.Model
    63  	Name string `gorm:"unique"`
    64  }
    65  
    66  type UserModel struct {
    67  	gorm.Model
    68  	Name   string
    69  	RoleId uint
    70  	Role   *UserRoleModel `gorm:"foreignKey:role_id;references:id"`
    71  }
    72  
    73  func main() {
    74  	db, _ := gorm.Open(
    75  		mysql.Open("DATABASE_DSN"),
    76  		&gorm.Config{},
    77  	)
    78  
    79  	cachesPlugin := &caches.Caches{Conf: &caches.Config{
    80  		Easer: true,
    81  	}}
    82  
    83  	_ = db.Use(cachesPlugin)
    84  
    85  	_ = db.AutoMigrate(&UserRoleModel{})
    86  
    87  	_ = db.AutoMigrate(&UserModel{})
    88  
    89  	adminRole := &UserRoleModel{
    90  		Name: "Admin",
    91  	}
    92  	db.FirstOrCreate(adminRole, "Name = ?", "Admin")
    93  
    94  	guestRole := &UserRoleModel{
    95  		Name: "Guest",
    96  	}
    97  	db.FirstOrCreate(guestRole, "Name = ?", "Guest")
    98  
    99  	db.Save(&UserModel{
   100  		Name: "ktsivkov",
   101  		Role: adminRole,
   102  	})
   103  	db.Save(&UserModel{
   104  		Name: "anonymous",
   105  		Role: guestRole,
   106  	})
   107  
   108  	var (
   109  		q1Users []UserModel
   110  		q2Users []UserModel
   111  	)
   112  	wg := &sync.WaitGroup{}
   113  	wg.Add(2)
   114  	go func() {
   115  		db.Model(&UserModel{}).Joins("Role").Find(&q1Users, "Role.Name = ? AND Sleep(1) = false", "Admin")
   116  		wg.Done()
   117  	}()
   118  	go func() {
   119  		time.Sleep(500 * time.Millisecond)
   120  		db.Model(&UserModel{}).Joins("Role").Find(&q2Users, "Role.Name = ? AND Sleep(1) = false", "Admin")
   121  		wg.Done()
   122  	}()
   123  	wg.Wait()
   124  
   125  	fmt.Println(fmt.Sprintf("%+v", q1Users))
   126  	fmt.Println(fmt.Sprintf("%+v", q2Users))
   127  }
   128  ```
   129  
   130  ## Cacher Example
   131  
   132  ```go
   133  package main
   134  
   135  import (
   136  	"fmt"
   137  	"sync"
   138  
   139  	"github.com/go-gorm/caches"
   140  	"gorm.io/driver/mysql"
   141  	"gorm.io/gorm"
   142  )
   143  
   144  type UserRoleModel struct {
   145  	gorm.Model
   146  	Name string `gorm:"unique"`
   147  }
   148  
   149  type UserModel struct {
   150  	gorm.Model
   151  	Name   string
   152  	RoleId uint
   153  	Role   *UserRoleModel `gorm:"foreignKey:role_id;references:id"`
   154  }
   155  
   156  type dummyCacher struct {
   157  	store *sync.Map
   158  }
   159  
   160  func (c *dummyCacher) init() {
   161  	if c.store == nil {
   162  		c.store = &sync.Map{}
   163  	}
   164  }
   165  
   166  func (c *dummyCacher) Get(key string) *caches.Query {
   167  	c.init()
   168  	val, ok := c.store.Load(key)
   169  	if !ok {
   170  		return nil
   171  	}
   172  
   173  	return val.(*caches.Query)
   174  }
   175  
   176  func (c *dummyCacher) Store(key string, val *caches.Query) error {
   177  	c.init()
   178  	c.store.Store(key, val)
   179  	return nil
   180  }
   181  
   182  func main() {
   183  	db, _ := gorm.Open(
   184  		mysql.Open("DATABASE_DSN"),
   185  		&gorm.Config{},
   186  	)
   187  
   188  	cachesPlugin := &caches.Caches{Conf: &caches.Config{
   189  		Cacher: &dummyCacher{},
   190  	}}
   191  
   192  	_ = db.Use(cachesPlugin)
   193  
   194  	_ = db.AutoMigrate(&UserRoleModel{})
   195  
   196  	_ = db.AutoMigrate(&UserModel{})
   197  
   198  	adminRole := &UserRoleModel{
   199  		Name: "Admin",
   200  	}
   201  	db.FirstOrCreate(adminRole, "Name = ?", "Admin")
   202  
   203  	guestRole := &UserRoleModel{
   204  		Name: "Guest",
   205  	}
   206  	db.FirstOrCreate(guestRole, "Name = ?", "Guest")
   207  
   208  	db.Save(&UserModel{
   209  		Name: "ktsivkov",
   210  		Role: adminRole,
   211  	})
   212  	db.Save(&UserModel{
   213  		Name: "anonymous",
   214  		Role: guestRole,
   215  	})
   216  
   217  	var (
   218  		q1Users []UserModel
   219  		q2Users []UserModel
   220  	)
   221  
   222  	db.Model(&UserModel{}).Joins("Role").Find(&q1Users, "Role.Name = ? AND Sleep(1) = false", "Admin")
   223  	fmt.Println(fmt.Sprintf("%+v", q1Users))
   224  
   225  	db.Model(&UserModel{}).Joins("Role").Find(&q2Users, "Role.Name = ? AND Sleep(1) = false", "Admin")
   226  	fmt.Println(fmt.Sprintf("%+v", q2Users))
   227  }
   228  ```
   229  
   230  ## License
   231  
   232  MIT license.
   233  
   234  ## Easer
   235  The easer is an adjusted version of the [ServantGo](https://github.com/ktsivkov/servantgo) library to fit the needs of this plugin.